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

Set assignee from component lead using script listener

Alvin
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.
September 13, 2018

Hello Community, I need help on scriptrunner, I need to set assignee based on the component's lead. Below is the code that I'm using

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.MutableIssue
import com.atlassian.jira.issue.customfields.option.LazyLoadedOption


// a map with select list option to Component
def componentsMap = [
"BOSS" : "Component1",
"Mashery" : "Component2",
]

def issue = event.issue as MutableIssue

def selectList = ComponentAccessor.customFieldManager.getCustomFieldObjectByName("Affected Service")
def selectListValue = issue.getCustomFieldValue(selectList) as LazyLoadedOption

// there is no value for the select list - therefore do nothing
if (! selectListValue) {
return
}

def componentManager = ComponentAccessor.projectComponentManager
def componentName = componentsMap.get(selectListValue.value)
def component = componentManager.findByComponentName(issue.projectObject.id, componentName)
def userManager = ComponentAccessor.userManager
def components = issue.componentObjects.toList()

if (component) {
componentManager.updateIssueProjectComponents(issue, [component])
}
issue.setAssignee(ComponentAccessor.userManager.getUserByKey(component.lead))

 

In this code, I have Affected Service as a single select list, if BOSS has been selected, the Component Field will update and set to Component1, but the assignee remains unassigned even if I have default assignee on my component. I know that there's something wrong with my code because I'm a beginner. I need to change assignee everytime component field is changed, that's why I used script listener. Thanks

2 answers

1 accepted

Suggest an answer

Log in or Sign up to answer
1 vote
Answer accepted
Charlie Misonne
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
September 13, 2018

Hi Alvin

Assigning an issue with a script is more complex. Jira needs to check whether the assignment is valid. Therefore you have to use th issueService.

Replace your issue.setAssignee line with:

def issueService = ComponentAccessor.getIssueService()
def user = component.componentLead
def currentUser = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()
def assignmentValidation = issueService.validateAssign(currentUser, issue.id, user.key)
if (assignmentValidation.isValid()){
    issueService.assign(user, assignmentValidation)
} else {
    log.debug(assignmentValidation) // you probably have to loop through the ErrorCollection object
}

At the top of the script you can import loggers and set the level. It can be useful to have some logging when troubleshooting:

import org.apache.log4j.Logger
import org.apache.log4j.Level
 
def log = Logger.getLogger("com.yourjira.componentupdate")
log.setLevel(Level.DEBUG)
Alvin
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.
September 13, 2018

Hi @Charlie Misonne, Thank you for the very fast response. will try this now and update you. Thank you!

Alvin
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.
September 13, 2018

Hi @Charlie Misonne , it shows some error. can you help me?

2018-09-13 10:10:19,380 ERROR [runner.AbstractScriptListener]: *************************************************************************************
2018-09-13 10:10:19,409 ERROR [runner.AbstractScriptListener]: Script function failed on event: com.atlassian.jira.event.issue.IssueEvent, file: <inline script>
java.lang.NullPointerException: Cannot get property 'componentLead' on null object
 at Script1208.run(Script1208.groovy:37)

 

import org.apache.log4j.Logger
import org.apache.log4j.Level
def log = Logger.getLogger("com.yourjira.componentupdate")
log.setLevel(Level.DEBUG)
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.MutableIssue
import com.atlassian.jira.issue.customfields.option.LazyLoadedOption


// a map with select list option to Component
def componentsMap = [
"BOSS" : "Component1",
"Mashery" : "Component2",
]

def issue = event.issue as MutableIssue

def selectList = ComponentAccessor.customFieldManager.getCustomFieldObjectByName("Affected Service")
def selectListValue = issue.getCustomFieldValue(selectList) as LazyLoadedOption

// there is no value for the select list - therefore do nothing
if (! selectListValue) {
return
}

def componentManager = ComponentAccessor.projectComponentManager
def componentName = componentsMap.get(selectListValue.value)
def component = componentManager.findByComponentName(issue.projectObject.id, componentName)
def userManager = ComponentAccessor.userManager
def components = issue.componentObjects.toList()

if (component) {
componentManager.updateIssueProjectComponents(issue, [component])
}

def issueService = ComponentAccessor.getIssueService()
def user = component.componentLead
def currentUser = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()
def assignmentValidation = issueService.validateAssign(currentUser, issue.id, user.key)
if (assignmentValidation.isValid()){
issueService.assign(user, assignmentValidation)
} else {
log.debug(assignmentValidation) // you probably have to loop through the ErrorCollection object
}

and this is the whole code , already applied your suggestions 

Charlie Misonne
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
September 13, 2018

That error means the component is null.

On your issue: do you selected a value for Affected Service?

And does Component1 and Component2 exist in your project?

 

It's probably safer if you put the assignment part in your if:

log.debug(component)
if (component) {
    componentManager.updateIssueProjectComponents(issue, [component])
    def issueService = ComponentAccessor.getIssueService()
    def user = component.componentLead
    def currentUser = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()
    def assignmentValidation = issueService.validateAssign(currentUser, issue.id, user.key)
    if (assignmentValidation.isValid()){
        issueService.assign(user, assignmentValidation)
    } else {
        log.debug(assignmentValidation) // you probably have to loop through the ErrorCollection object
    }
}

I also added  log.debug(component)

You can check the execution log after updating your Affected Service field to check whether the component was found.

Alvin
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.
September 13, 2018

@Charlie Misonne That works so perfectly ! Thank you for helping me! I missed the part on editing the component1, you're a life saver. Thank you!!

Charlie Misonne
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
September 13, 2018

You're welcome @Alvin!

Alvin
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.
September 13, 2018

Hi @Charlie Misonne, I add Issued Updated on event to fire on because I think that's the way for the Assignee to change everytime Component/s field change. but I see that it neglects my edit and it goes back to the original issue posted. Any thoughts about this? Thank you.

Charlie Misonne
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
September 13, 2018

So it was working a couple of hours ago but now it doesn't?

Issue Udpated is the correct event to use.

Have you selected your project in the Project Key picker?

Alvin
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.
September 13, 2018

@Charlie Misonne, yep its working perfectly. Before, the event is only Issue Created and it works really well, then now I try to add Issue Updated, so there are two events now, Issue Created and Issue Updated. But whenever I tried to Edit Component/s field, (i.e. I change it to JIRA) , it just neglect my edit and sticks to what I've created. (if I create issue with Affected Services = BOSS , Component/s = Component1 , and assignee will be the component lead , it stays the same even if I edit it.) 

But when I update issue with one event only (which is Issue Created) , it can be edited but thee Component/s Field woudn't change. 

I just want to go deeper escalation with these Component/s , Is it possible ? Thank you!

Alvin
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.
September 13, 2018

@Charlie Misonne , I found out  that the Component/s , and the Assignee relies on the value of the Affected Service. Thank you for helping me ! I really appreciate it. Thanks!

Charlie Misonne
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
September 14, 2018

@Alvinglad it was resolved!

Alvin
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.
September 14, 2018

Hi @Charlie Misonne , I just have a quick question here, how can I map multiple attributes to one value?

 

Script below

def componentsMap = [
"BOSS" : "Component1",
"WORK" : "Component1",
"Class" : "Component1",
"Mashery" : "Component2",
]

 

 

I tried to make it like this, but no luck. Thank you 

def componentsMap = [
["BOSS","WORK,"Class" ] : "Component1",
"Mashery" : "Component2",
]

Charlie Misonne
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
September 14, 2018

Apparenlty there is a MultikeyMap but I have absolutely no experience with it. http://www.tothenew.com/blog/multikeymap-nested-maps-solution/

Alvin
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.
September 16, 2018

Thank you @Charlie Misonne, will check on this

Alvin
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.
September 25, 2018

@Ivan Tovbin I tried to use MultiKeyMap but it keeps on giving me unresolved class even if I import MultiKeyMap. Thank you

Ivan Tovbin
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.
September 25, 2018

@Alvin 

I assume your idea is to be able to pull the required component by using ANY of the attributes, right? Problem with MultiKeyMap is that you have to provide a set of ALL attributes mapped to a value to get that value. Surely, it's possible to write a logic that would first search all attribute sets for the attribute you need and then use that set to pull a value, but that's a bit too complicated imho. 

That said I would suggest using a regular map. That way you'll be able to pull your component by using ANY attribute, mapped to it, not a combination of all attributes:

Map<String, String> map = new HashMap<>()
map.put("attribute1", "component1")
map.put("attribute2", "component1") 
map.put("attribute3", "component1") 
map.put("attribute4", "component2") 
map.put("attribute5", "component2") 
map.put("attribute6", "component2")

and so on.. 

Alvin
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.
September 25, 2018

Hi @Ivan Tovbin , Thank you for your help, just want to clarify, so if I have 150+ attribute, that would be equal to 150+ lines?

Ivan Tovbin
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.
September 25, 2018

In any case, even if you have a problem importing MultiKeyMap class, you can always use a regular Map, and simply use a collection of strings as its key, like so:

Map<List<String>, String> map = new HashMap<>()
map.put(Arrays.asList("attribute1", "attribute2", "attribute3"), "component1")
map.put(Arrays.asList("attribute3", "attribute4", "attribute5"), "component2")

But like I said, to get a value from this map you'll need to either provide the whole collection of attributes or create a logic that would first search for your attribute in all collections and then use the collection that contains it. For that i'd create a function:

Map<List<String>, String> map = new HashMap<>()
map.put(Arrays.asList("attribute1", "attribute2", "attribute3"), "component1")
map.put(Arrays.asList("attribute3", "attribute4", "attribute5"), "component2")

List<String> getAttributeList(String attribute, Map map){
List<String> attributeList = new ArrayList<>()
attributeList = map.keySet().find{it.contains(attribute)}
return attributeList
}

map.get(getAttributeList("attribute4", map))
Alvin
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.
September 25, 2018

 Hi @Ivan Tovbin, I tried to use your code but it returned an error

Screenshot from 2018-09-25 17_06_39.png

Ivan Tovbin
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.
September 25, 2018

@Alvin You can ignore these errors. Scriptrunner's static type checking is not always accurate.

Alvin
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.
September 25, 2018

Hi @Ivan Tovbin, will do what you've suggest. will give feedback later. Thank you so much!

0 votes
Alvin
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.
September 24, 2018

Hi @Charlie Misonne , I just want to ask something. How can I add Group , from Single Group picker field, based on the value of the Affected Service Field. 

Scenario right now  is  whenever requestor selects "BOSS" as value of Affected Service Field, Component Field will be updated and  Assignee will be the Component Lead.

Now I want to add Group too, based on the Value of Affected Service Field inside the condition. Can you help me? Thank you!

TAGS
AUG Leaders

Atlassian Community Events