Create
cancel
Showing results for 
Search instead for 
Did you mean: 
Sign up Log in

It's not the same without you

Join the community to find out what other Atlassian users are discussing, debating and creating.

Atlassian Community Hero Image Collage

Scriptrunner - listeners on Issue Updates slow down JIRA Edited

Hi,

I have a custom field in my JIRA environment named "Technical Thrust" and it is in all epic, task, and story issues. I've written two custom listeners with the goal of ensuring the Technical Thrust field matches between an epic and the stories/tasks linked to that epic.

The goal of the first listener is to copy the Technical Thrust labels (1 or more) from an epic to any task or story that is linked to the epic. This listener executes on an Issue Update event and has a check to see if the issue is an Epic before copying anything.

The goal of the second is to copy labels from an Epic Link in the event that a user updates a child task or story. The idea here is that someone might link an already created story to an epic, and the Technical Thrust would need to be copied from the new Epic Link. Or a user might accidentally delete a Technical Thrust label and the code would automatically replace it.

The problem arises when I make the second listener execute on event: Issue Updated. Currently the code works just fine if the second listener only executes on event: Issue Created. When I add the second event, then go to a task that has an epic link, the JIRA environment locks up and the script remains hanging. Furthermore, when I check the Script Listener log, I see that the script has been called multiple times (with multiple failures). This leads me to believe that I am creating a loop when the second listener executes on an issue update it causes an update that triggers the script to run multiple times.

Any help would be much appreciated.

Thanks.

The first listener executes on event: Issue Updated

import com.atlassian.jira.issue.Issue
import com.atlassian.jira.ComponentManager;
import com.atlassian.jira.issue.link.IssueLink;
import com.atlassian.jira.component.ComponentAccessor;
import com.atlassian.jira.issue.label.LabelManager;
import com.atlassian.jira.issue.IssueManager;
import com.atlassian.jira.issue.util.DefaultIssueChangeHolder
import com.atlassian.jira.issue.ModifiedValue

def issueManager = ComponentAccessor.getIssueManager()
def issue = event.issue

// execute following code if in an EPIC
if (issue.issueType.name == "Epic"){

    def customFieldManager = ComponentAccessor.getCustomFieldManager()
    def currentUser = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()
    def labelMgr = ComponentAccessor.getComponent(LabelManager)

    // custom field name is Technical Thrust and its ID is 10300
    def cfname = "Technical Thrust"
    def cf = customFieldManager.getCustomFieldObjects(issue).find {it.name == cfname}
    def cfValue = cf.getValue(issue) // return a collection from the epic custom field for technical thrust
    
    if (!cf) {return} // escape if cf does not exist

    List<IssueLink> allOutIssueLink = ComponentAccessor.getIssueLinkManager().getOutwardLinks(issue.getId());
    for (Iterator<IssueLink> outIterator = allOutIssueLink.iterator(); outIterator.hasNext();) {
        IssueLink issueLink = (IssueLink) outIterator.next();
        def linkedIssue = issueLink.getDestinationId()
        
        def child = issueManager.getIssueObject(linkedIssue) //as Issue
        
        if (!child) {return} // if null, escape
        
        // clear any labels from the child before updating the labels
        def dummy = "" as Set
        def childCF = customFieldManager.getCustomFieldObjects(child).find {it.name == cfname}
        def changeHolder = new DefaultIssueChangeHolder()
        childCF.updateValue(null,child, new ModifiedValue(child.getCustomFieldValue(childCF),dummy),changeHolder)
        
        // loop through each string in cfValue (in the event of multiple labels)
        for (String s : cfValue) {
            labelMgr.addLabel(currentUser, child.getId(), 10300L, s, false);
        }        
    }
}

The second listener executes on event: Issue Created

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.Issue
import com.atlassian.jira.issue.MutableIssue
import com.atlassian.jira.issue.label.LabelManager
import com.atlassian.jira.issue.util.DefaultIssueChangeHolder
import com.atlassian.jira.issue.ModifiedValue

def customFieldManager = ComponentAccessor.getCustomFieldManager()
def issue = event.issue as MutableIssue

// execute following code if issue type is task or story
if (issue.issueType.name == "Task" || issue.issueType.name == "Story"){
    
    def currentUser = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()
def labelMgr = ComponentAccessor.getComponent(LabelManager)

    // custom field name is Technical Thrust and its ID is 10300
    def cfname = "Technical Thrust"
    def cf = customFieldManager.getCustomFieldObjects(issue).find {it.name == cfname}
def epicCf = customFieldManager.getCustomFieldObjects(issue).find {it.name == 'Epic Link'}
    if (!cf || !epicCf) {return} // escape if cf or epicCf do not exist

    def epic = issue.getCustomFieldValue(epicCf) as Issue

    if (!epic) {return} // escape if epic does not exist

    def cfValue = cf.getValue(epic) // return a collection from the epic custom field

    // clear any existing labels before updating
    def dummy = "" as Set
    def changeHolder = new DefaultIssueChangeHolder()
    cf.updateValue(null,issue, new ModifiedValue(issue.getCustomFieldValue(cf),dummy),changeHolder)

    // loop through each string in cfValue (in the event of multiple labels)
    for (String s : cfValue) {
        labelMgr.addLabel(currentUser, event.issue.getId(), 10300L, s, false);
    }
}

 

 

 

1 answer

Hi, 

Since the only loop that is available here is the for loop, can you try something like this,

for(int i=0; i<cfValue.size(); i++){
labelMgr.addLabel(currentUser, event.issue.getId(), 10300L, cfValue[i].toString(), false);
}

 -Praveen

Hi Praveen,

Thanks for the suggestion, but it did not solve my problem.

When I create a task and assign an Epic Link, JIRA indicates in my activity feed that I've done 3 things: 1) created a task, 2) updated task's epic link, and 3) updated the epic's children. When I said loop, my thought was that the the updated epic children causes my listener to execute, which updates the tasks under an epic and causes the update listener to execute again, creating a loop.

Hi Matthew,

Ok, now I got the issue. This is kind of tricky to solve. One solution from my side would be you can use the issueLinkManager to get the links associated to an issue and get the different links (parent/child/etc..) and use it for executing your script (like only for the child links etc..).

Again, this is juat a suggestion as I'm not aware of how the links are established in your environment. Check the below link for more about issueLinkManager

https://docs.atlassian.com/software/jira/docs/api/7.0.4/com/atlassian/jira/issue/link/IssueLinkManager.html

-Praveen

Suggest an answer

Log in or Sign up to answer
TAGS
Community showcase
Published in Statuspage

New feature: Slack notifications for Statuspage

We're excited to announce the release of a long-requested feature on Statuspage. Now visitors to your status page can subscribe to get notified in Slack when you report an incident or maintenance. Th...

51 views 0 8
Read article

Community Events

Connect with like-minded Atlassian users at free events near you!

Find an event

Connect with like-minded Atlassian users at free events near you!

Unfortunately there are no Community Events near you at the moment.

Host an event

You're one step closer to meeting fellow Atlassian users at your local event. Learn more about Community Events

Events near you