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

Earn badges and make progress

You're on your way to the next level! Join the Kudos program to earn points and save your progress.

Deleted user Avatar
Deleted user

Level 1: Seed

25 / 150 points

Next: Root

Avatar

1 badge earned

Collect

Participate in fun challenges

Challenges come and go, but your rewards stay with you. Do more to earn more!

Challenges
Coins

Gift kudos to your peers

What goes around comes around! Share the love by gifting kudos to your peers.

Recognition
Ribbon

Rise up in the ranks

Keep earning points to reach the top of the leaderboard. It resets every quarter so you always have a chance!

Leaderboard

Come for the products,
stay for the community

The Atlassian Community can help you and your team get more value out of Atlassian products and practices.

Atlassian Community about banner
4,410,252
Community Members
 
Community Events
169
Community Groups

Check for duplicates link in Groovy transition validation script

I have a transition called "Close as Duplicate" that allows the user to link an issue, and the post function automatically sets the status to closed and resolution to duplicate. I would like to enforce that a link either already exists or is being added in the current transition with the link_type = "duplicates".

I tried this before and found that I can examine already existing links, but the code looking at the existing links didn't find a link that was being added in the current transtion.

Can this be done in a Groovy transition validation script?

Thanks,
Robert

9 answers

1 accepted

Comments for this post are closed

Community moderators have prevented the ability to post new answers.

Post a new question

0 votes
Answer accepted

Thank you Henning and Jamie!

Below is the implementation as a simple script validator,.

linkCnt = 0

request = webwork.action.ActionContext.getRequest()
if (request) {
    // check for new duplicates link 
    linktype = request.getParameter('issuelinks-linktype')
    linkedIssue = request.getParameter('issuelinks-issues')
    if (linktype == 'duplicates' && linkedIssue) linkCnt = 1
}

// check for existing duplicates link
if ( issueLinkManager.getOutwardLinks(issue.getId())*.issueLinkType.name.contains('Duplicate') ) linkCnt += 1

// Transition requires one, and only one, duplicates link
(linkCnt==1)

1 vote

You could use the request to get the information with this Simple scripted validator condition:

request = webwork.action.ActionContext.getRequest()
linktype = request.getParameter('issuelinks-linktype')
linkedIssue = request.getParameter('issuelinks-issues')
(linktype == 'duplicates' && linkedIssue)

Henning

JamieA Rising Star Feb 20, 2013

Good call but check for nulls! There won't be a request when transition is executed through a service for instance, and possibly not when through the REST API.

JamieA Rising Star Feb 20, 2013

I have blown myself up before assuming there will always be a request... so the above is from bitter experience.

Ok, good note. Robert should combine this (incl. null checks) with looking for already existing links and if none of both ways results in an existing link the validator should return false.

Hi Henning,

Question -- I am using this validator to verify that there is a link of key "RFC" associated with an issue.

How would I modify your webwork action validator example to include a check for links added during a workflow transition screen?

import com.atlassian.jira.component.ComponentAccessor;
import com.atlassian.jira.issue.Issue;
import com.atlassian.jira.issue.link.IssueLink;
 
Issue issue = issue;

String result = '';
Collection<IssueLink> olinks = ComponentAccessor.getIssueLinkManager().getOutwardLinks(issue.getId());
Collection<IssueLink> ilinks = ComponentAccessor.getIssueLinkManager().getInwardLinks(issue.getId());
Collection<IssueLink> links = olinks + ilinks;

for(IssueLink il : links){
  result += il.getSourceObject().getProjectObject().getKey()
  result += il.getDestinationObject().getProjectObject().getKey()
  
  if(result.contains("RFC")){
     return true;

//return result
    }
}

Actually, I figured it out -- this works (though suggestions on improving code always welcome!):

import com.atlassian.jira.component.ComponentAccessor
import webwork.action.ActionContext
import com.atlassian.jira.issue.link.IssueLink;


// check for existing RFC links

String result = '';
Collection<IssueLink> olinks = ComponentAccessor.getIssueLinkManager().getOutwardLinks(issue.getId());
Collection<IssueLink> ilinks = ComponentAccessor.getIssueLinkManager().getInwardLinks(issue.getId());
Collection<IssueLink> links = olinks + ilinks;

for (IssueLink il : links) {
result += il.getSourceObject().getProjectObject().getKey()
result += il.getDestinationObject().getProjectObject().getKey()

if (result.contains("RFC")) {
return true;
}
}


// check for new RFC link
def request = ActionContext.getRequest()
if (request) {

linkedIssue = request.getParameter('issuelinks-issues')

if (linkedIssue.contains("RFC")) {
return true;
}
}


0 votes
HarryH Rising Star Feb 29, 2016

The validator script doesn't work at create transition because it reads out the null  issueLinkTypes object.

We can use "Boolean validator with math, date-time or text-string terms' Validator for this transitior" validator instead.

For example:

 

count(linkedIssues("Duplicate"))>0

I added some imports and calls not to rely on names, but only on IDs:

import com.atlassian.jira.ComponentManager
import com.atlassian.jira.issue.link.IssueLinkTypeManager

def typeManager = (IssueLinkTypeManager)ComponentManager.getComponentInstanceOfType(IssueLinkTypeManager.class);
def linkCnt = 0
def duplicateLinkId = '10002'
 
request = webwork.action.ActionContext.getRequest()
if (request) {
    // check for new duplicates link 
    linktype = request.getParameter('issuelinks-linktype')
    linkedIssue = request.getParameter('issuelinks-issues')
    if (typeManager.getIssueLinkTypesByOutwardDescription(linktype).id.toString().contains(duplicateLinkId)  &amp;&amp; linkedIssue) linkCnt = 1
}
 
// check for existing duplicates link
if ( issueLinkManager.getOutwardLinks(issue.getId())*.issueLinkType.id.toString().contains(duplicateLinkId) ) linkCnt += 1
 
// Transition requires one, and only one, duplicates link
(linkCnt&gt;0)

Thanks for the tweaks. I'm using 4.4.4 and it looks like getIssueLinkManager is not available from ComponentAccessor in 4.4. But I'll keep it in a comment for when we upgrade.

0 votes
JamieA Rising Star Feb 20, 2013

There's no down sides to putting it in a file. You can add it pretty much as you have it already, except add:

def issueLinkManager = ComponentAccessor.getIssueLinkManager()

> what import do I need for webwork getRequest()?

Henning did the fully-qualified class... you could do:
import webwork.action.ActionContext
def request = ActionContext.getRequest()

And now that I've got the simple scripted validator working, since I have this "close as duplicate" transition in three places in the workflow, I think I'd like to put the script in a file, and put the path in the validator, instead of duplicating the simple script.

What imports do I need to accomplish this? I know I need:

import com.opensymphony.workflow.InvalidInputException

import com.atlassian.jira.issue.link.IssueLinkManager

import com.atlassian.jira.ComponentManager

what import do I need for webwork getRequest()?

Are there any downsides such as performance to putting the script in a file versus using a simple scripted validator?
Thanks,
Robert
As a script in a file::
import org.apache.log4j.Category
import com.opensymphony.workflow.InvalidInputException
import com.atlassian.jira.issue.link.IssueLinkManager
import com.atlassian.jira.ComponentManager
log = Category.getInstance("com.onresolve.jira.groovy.example.testValidator")
log.setLevel(org.apache.log4j.Level.DEBUG)
log.debug("Condition testValidator script running")
ComponentManager componentManager = ComponentManager.getInstance()
IssueLinkManager issueLinkManager = componentManager.getIssueLinkManager()
linkCnt = 0
request = webwork.action.ActionContext.getRequest()
if (request) {
// check for new duplicates link
linktype = request.getParameter('issuelinks-linktype')
linkedIssue = request.getParameter('issuelinks-issues')
if (linktype == 'duplicates' && linkedIssue) linkCnt = 1
}
// check for existing duplicates link
if ( issueLinkManager.getOutwardLinks(issue.getId())*.issueLinkType.name.contains('Duplicate')) linkCnt += 1
// Transition requires one, and only one, duplicates link
if (linkCnt!=1) invalidInputException = new InvalidInputException("Close as Duplicate requires One, and only One, 'duplicates' link type. Do not use 'is duplicated by'.")

Thank you Henning and Jamie!

I implemented the following as a simple scripted validator in a test transition and it seems to work. I want to require one, and only one, duplicates link during this transition. Please let me know if you see any other null or error checking that I should to do to this. Thanks again!!

linkCnt = 0

request = webwork.action.ActionContext.getRequest()
if (request) {
    // check for new duplicates link 
    linktype = request.getParameter('issuelinks-linktype')
    linkedIssue = request.getParameter('issuelinks-issues')
    if (linktype == 'duplicates' && linkedIssue) linkCnt = 1
}

// check for existing duplicates link
if ( issueLinkManager.getOutwardLinks(issue.getId())*.issueLinkType.name.contains('Duplicate') ) linkCnt += 1

// Transition requires one, and only one, duplicates link
(linkCnt==1)

I guess Jamies script runner could accomplish this. It ships with a built-in scripted validator called:

Has at least one outward duplicate link

You should give it a try...Hope that helps

Cheers Christian

I can't find my code right now, but I did try this before. I need to try it again to be sure. But I think it worked if the link already existed. But if the link was being added during the transition, then it didn't find the link.

Thanks for the input.

Robert

Good link. Basically the same problem I am having. Thier conversation ended about the same point; trying to check for a link that was created created, but not yet committed to the database yet. They were trying to check for a link on the create issue step, so no existing link, but checking for a new link.

I'm wondering if I need to do something with transientVars and changeitems to see values before they are committed.

JamieA Rising Star Feb 20, 2013

I'm not sure this is possible... looking at the source of IssueLinkManager, all the methods to get the links involve looking up records in the database. In a validator they're not written yet.

If it's not in the transientVars, then it may not be possible. This would be true of a plugin written in java as well as script runner.

JamieA Rising Star Feb 20, 2013

Yeah... I had a look at this. You need access to the fieldValuesHolder and I'm not sure how you get at this from a validator. I think in the past I may have recommended that you fail validation with a message to the user to add the link before doing the transition. Historically this was never a problem because you couldn't put issue links on the screen, therefore this couldn't happen.

Bummer. Thanks Jamie and Christian for the help. Do you think this is possible with the Behaviours plug-in?

Hey All, what if i want to create link between two issues, After doing research i came to conclusion that, i can use


linkManager.createIssueLink(issue.getId(),opt.getId(),issueLinkTypes.getAt(1),1,currentUser)

but its showing incomptability issues.

So any help or suggestions?

Comments for this post are closed

Community moderators have prevented the ability to post new answers.

Post a new question

TAGS

Atlassian Community Events