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

Avoid doubles from Jira automations when using ScriptRunner Clone Issue

Isidre Costa April 27, 2021

Hi all,

we have created an ScriptRunner Clone Issue Listener that is executed when the issue is updated. This script checks that a custom field has a specific value and if there isn't already any linked issue as "duplicated" it creates a "duplicated" issue in other Jira project.

This is the Condition:

if ((! issueLinkManager.getInwardLinks(issue.getId())*.issueLinkType.name.contains('Duplicate') ) && 
(! issueLinkManager.getOutwardLinks(issue.getId())*.issueLinkType.name.contains('Duplicate') ) &&
(cfValues['Sub-system responsible']?.value == 'PS')){
return true
} else {
return false
}

The script works properly, but in the project there are other automation scripts triggered on the Issue Creation that changes fields such as the Component, the Organization or the Issue Type.

We have realized that sometimes the script creates the "duplicated" issue twice. And we think that could be that the ScriptRunner listener and the other automation are colliding. We think that the 3 automation executed when the issue is created, are triggering an Issue Update event in parallel, end everyone calls the ScriptRunner listener and creates the "duplicated issue" twice.

Does anybody know how to avoid this problem? May be we need to detect if the script is triggered by an automation or from a user action. But we do not know how to do it?

Any idea?

 

Thanks in advance!

Isidre

 

2 answers

1 accepted

Suggest an answer

Log in or Sign up to answer
1 vote
Answer accepted
Peter-Dave Sheehan
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
April 27, 2021

Is your automation running as a specific user? If so, then you could use the event.getUser() to check to see if the event was executed by the Automation user or not.

If your automation is always running as "current user" and that can't be changed, you need to somehow cause the 2 events to be separated in time from each other.

The only way I can think that would ensure this would be a little hacky ... but it would look something like this:

  • Put the condition code in the action script
  • Wrap it around a Thread.start{} block to run asynchronously
  • Add a sleep statement with a randomly generated number of seconds before checking if the linked tickets exist or not.

The end result is if 2 update events are fired at the same time, one of them should create the link before the second one looks for matching links.

Another hacky thought I have (sorry I get lots of those) is to set some issue property on the source issue (even in the condition code) that should be more immediate than waiting for the clone issue to be created and linked ... so that even if the 2 events fire just milliseconds apart, the second one can detect that the source issue has already processed.

Something like this:

import com.atlassian.jira.entity.property.EntityPropertyService
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.bc.issue.properties.IssuePropertyService

def issueLinkManager = ComponentAccessor.issueLinkManager
def issuePropertyService = ComponentAccessor.getComponent(IssuePropertyService)
def currentUser = ComponentAccessor.jiraAuthenticationContext.loggedInUser


if((cfValues['Sub-system responsible']?.value != 'PS')){
//exit quickly if the cf value doesn't match
return false
}
def prop = issuePropertyService.getProperty(currentUser, event.issue.id, 'psDuplicateExists')
if(prop && prop.isValid() && prop.entityProperty.isDefined() ){
//exit quickly if psDuplciateExist has been set
return false
}

//we'll either be finding an existing duplicate or creating... so let set the psDuplciecateExists property
def validate = issuePropertyService.validateSetProperty(currentUser, event.issue.id, new EntityPropertyService.PropertyInput('{"value":"true"}','psDuplicateExists'))
if(validate.isValid()){
issuePropertyService.setProperty(currentUser, validate)
} else {
//this should not happen, but useful in debug
log.error validate.errorCollection
}

//now, check the old way
def linkCollection = issueLinkManager.getLinkCollection(event.issue, currentUser)
//adjust with the correct link name... this is the name, not the inward/outward descriptions
def linkedDuplicates = ( linkCollection.getInwardIssues('Duplicate')?:[] ) + (linkCollection.getInwardIssues('Duplicate')?:[] )
if(linkedDuplicates){
//don't create duplicate link again,
return false
}

//all prior checks have passed, let's create the duplicate
return true
Isidre Costa May 13, 2021

Hi Peter-Dave,

We have modified the condition with some similar code of your first option with a sleep of a random amount of seconds.

 

if (cfValues['Sub-system responsible']?.value == 'PS'){ 
def mSecs = Math.abs(new Random().nextInt() % 5000) +1000
sleep(mSecs)
if ((! issueLinkManager.getInwardLinks(issue.getId())*.issueLinkType.name.contains('Duplicate') ) &&
(! issueLinkManager.getOutwardLinks(issue.getId())*.issueLinkType.name.contains('Duplicate') ) ){

return true
} else {
return false
}
} else {
return false
}

 

After some days observing its behavior, it seems that it works.

 

Thanks a lot!!!

Isidre

0 votes
Leonard Chew
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
April 27, 2021

Too many triggered scripts can get tricky.

To find out the problem, I suggest to use logging in your scripts to see what happens.

Use the debug log level to activate your debug logs:

import org.apache.log4j.Level
log.setLevel(Level.DEBUG)

log.debug("Doing this or that on: " + issue.key)

 

If you dont need your logs anymore, keep your logs and just set the Info Log-Level

log.setLevel(Level.INFO)
TAGS
AUG Leaders

Atlassian Community Events