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
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:
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
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
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
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)
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.