I have created a public class in Script editor for processing project keys. I have a Service desk form which will supply the project keys from the form to this class thro the post function, which is supposed to be processed later by a different script.
The keys are getting supplied correctly but is not retained in the class for processing by another script. What am i missing for the keys to be retained for processing later ?
public class ProjectUpdater {
private static final Logger log = Logger.getLogger(ProjectUpdater.class)
public static ConcurrentHashMap<String, String> projectDetailsMap = new ConcurrentHashMap<>()
public static void updateProjects(List<String> projectKeys)
Hi @Aisha M
All is good, thanks! I hope you're doing great as well.
This approach might not be the best that I'd suggest. First, in a clustered setup (I assume you have multiple nodes in your Jira DC), each node has its own JVM, and static variables are not shared across nodes. This means that the ConcurrentHashMap
in your class will only be available on the node where it was set, and other nodes won't have access to it. So the access to this class from other requests might be handled by the other instances which means that they will have their own ConcurrentHashMap.
On the other hand, static variables which are accessed in a concurrent environment should be handled correctly. Ensure that the static projectDetailsMap
is being accessed and modified in a thread-safe manner, I mean, while you are adding to this map, another thread might be clearing it.
I don't know your case 100% but have you considered storing these keys in a more permanent storage mechanism, such as a database? In this way, you can share this data across different scripts easier.
I hope I was clear and this helps!
Tuncay
@Tuncay Senturk Thank you so much for your insights !! I actually wanted to directly use the customfield which takes the project keys as input from the form in to the script.
But, our org wants to use the class instead, so that the method can be re-used for multiple scripts.
For now (for testing purpose) have two scripts on the service desk post function ,
1) one to supply the project keys to the class
2) to get the processed project keys from the class and post the keys as comment on the issue (this i randomly added to test if the class is working)
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
From my understanding, these individual scripts could be invoked via post-functions from separate nodes. As I mentioned, each node has its own JVM. This means that a static map in the class will not be helpful because each node will have its own map. If you add a key to the map in node A, it won't be visible in node B. To address this, you can use Atlassian cache to distribute this map to other nodes. Or you can use custom field as you mentioned
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
I took your feedback, and simplified the class script. Now I'm able to get the project keys from the service desk form to the class, and then get the projects list from the class to be added as a comment on the issue when resolved.
But our actual requirement is something LIKE THIS -> .Basically, we want to have users submit a Service desk from with the project keys, This project keys will be processed by the class, and will later be utilized by another script (another developer is working on) which will migrate these projects to a new workflow scheme.
For my testing purpose, I added the comment part to check if the projects keys are getting processed by the class.
Do, you think I'm on the right track with this ? I kinda feel overwhelmed at this point. . Not lol
CLASS SCRIPT:
public class ProjectUpdater {
private static final Logger log = Logger.getLogger(ProjectUpdater.class)
public static void updateProjects(List<String> projectKeys)
{
log.info("Starting updateProjects with keys: ${projectKeys}")
projectKeys.each { projectKey ->
log.info("Processing project key: ${projectKey}")
def project = ComponentAccessor.getProjectManager().getProjectByCurrentKey(projectKey)
if (project) {
log.info("Project found: ${project.name}")
} else {
log.info("Project not found: ${project.Key}")
}
}
log.info("Completed updateProjects.")
}
}
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi @Aisha M
The code seems OK, but there is another problem, let me try to explain it.
The code you've written to update the projectKeys hashmap, which is a static variable, seems fine at first glance. However, I want to highlight a potential issue that may arise in a multi-node Jira environment. ( I assume you have multi-node DC environment)
If you had only one Jira node, this approach would work perfectly because the code that updates projectKeys and the code that reads from it would both be running in the same JVM. However, with multiple nodes, subsequent calls to this code might be handled by different nodes, leading to inconsistencies.
Think about this scenario:
Now we have;
If a request that reads from projectKeys is handled by Node 2, it will only see PR-2 and PR-3. Conversely, if the request is handled by Node 1, it will see only PR-1.
This can lead to issues where the data is not consistent across nodes. That's why I said you may use Atlassian's distributed cache or another mechanism to ensure that projectKeys is synchronized across all nodes to avoid this inconsistency.
I may be missing some points though, please let me know if there is something else that I'm missing or if you need any further clarification or assistance on this.
Best!
Tuncay
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Ohhhhhh understood ! I tried modifying the script to store the keys and then retrieve , but unable to fix the below section ,
public static void storeProjectKeys(Issue issue, List<String> projectKeys) {
log.info("Storing project keys for issue ${issue.key}: ${projectKeys}")
def propertySet = getPropertySet(issue)
String projectKeysString = projectKeys.join(",")
propertySet.setString(PROPERTY_KEY, projectKeysString)
}
public static List<String> retrieveProjectKeys(Issue issue) {
log.info("Retrieving project keys for issue ${issue.key}")
def propertySet = getPropertySet(issue)
String projectKeysString = propertySet.getString(PROPERTY_KEY)
if (projectKeysString) {
return projectKeysString.split(",").collect { it.trim() }
}
return []
}
private static PropertySet getPropertySet(Issue issue) {
return PropertySetManager.getInstance("jira.properties", issue.id.toString())
}
}
Also, will it be okay to have an empty customField to store the keys getting processed instead ?? I remember seeing a class script that does something like this in our instance
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Sorry I could not get it, what's the problem with the code? Are you getting compile errors?
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
@Tuncay Senturk I have a different developer working on the class. So, you can ignore it :)
For now my task is to create the workflow post function to get the projects from the Service desk form to the class and then run another script in the editor to migrate the projects to the new schemes.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Okay, could you provide more details about your Service Desk form and the post function? I apologize if this is a basic question, but I need a better understanding. What does the form look like? What specific fields or properties do you want to extract from the issue? Have you started working on any code for this?
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
@Tuncay Senturk Thank you for checking on it ! Really appreciate your kindness to help :)
So, I created a Service desk form with a drop down field to specify the old project scheme type along with another field for taking the project keys as input. Using a workflow post-function when the ticket is resolved, the projects will be migrated to the new scheme (based on the old type).
In the post function script, have ensured the project keys are supplied to another script in the editor which will thereby move the project to the new scheme. So, we have multiple scripts in the editor for different old schemes. For now , able to achieve this & is working.
And reason for this complicated route is due to the need for migrating 3000+ projects with a huge number of issues.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Online forums and learning are now in one easy-to-use experience.
By continuing, you accept the updated Community Terms of Use and acknowledge the Privacy Policy. Your public name, photo, and achievements may be publicly visible and available in search engines.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.