Updating assignee field using Groovy script Postfunction is not persisted during state transition

Rajath B K September 10, 2016

Hi, 

   I have a requirement that i need to automatically assign new issues to users from a particular group in Round robin fashion. I have written a script for this. When i run this script using Script runner console, the field gets updated but it is not persisted in the DB despite calling mutableIssue.store. 
And when this script runs as a post function nothing happens though, in logs i see that the script successfully executed.

This is what im doing 
results holds a Jql query results 

MutableIssue mutableIssue = issueManager.getIssueObject(results.issues.get(0).id)
mutableIssue.setAssignee(agentPQ.peek().user)
mutableIssue.store()

 

Screenshot of my post-functions for this transition

Screen Shot 2016-09-11 at 12.32.25 AM.png

Im stuck at this issue since a day and badly need help... 
Kindly help

 

Thanks 



2 answers

0 votes
JamieA
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 12, 2016

Move the post-function up the list, before the system functions to save and reindex the issue

Rajath B K September 12, 2016

I have already experimented by placing my post function at various positions in the list . I had gathered from the api doc that the "issueService.assign" does save and re-index the issue . This was the reason i had placed my post-function at the top of the list, as you can notice that in the attachment.

After using issueService to assign, the changes do persist and user is also assigned if i run the script from the script console. But when it runs as post-function, the history and activity tabs show the assigment but the "assignee" field still shows as unassigned.. My curl call to the rest api for the issue with "expand=changelog" also has the assignment item.

So, now the only problem is that the changes made by the script running as post-function is not reflecting in the assignee field.

 

JamieA
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 12, 2016

In your question you mentioned nothing about issueService... 

So, it turns out you are not updating the current issue, but some other issue right? In which case, yes, your code in your question is not sufficient. Using issueService.assign should be fine.

If you are actually updating the current issue just use the provided issue variable, do not redefine it or get it from the results of a query.

Have you check your atlassian-JIRA log?

Rajath B K September 12, 2016

Yes, sorry , i found out about the issue service after i posted my question.   
BTW , could you please review my script pasted in my comment to Nic Brough earlier
 

JamieA
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 12, 2016

looks ok

0 votes
Nic Brough -Adaptavist-
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 10, 2016

Could you give us the  script?

Rajath B K September 11, 2016

I fetch the latest unassigned issue and fetch an assignee from a specific group in a round-robin like fashion.

I maintain a priority queue , prioritising assignees based on their current load , last assigned time and pick the root of the queue as my new assignee

This is my script

class Agent {
    ApplicationUser user;
    int issueCount;
    long lastAssignedTime;
}

def groups = ComponentAccessor.getGroupManager()  as GroupManager
def agents = groups.getUsersInGroup("Test")



def userManager = ComponentAccessor.getUserManager() as UserManager
def user = ComponentAccessor.jiraAuthenticationContext.loggedInUser
def jqlQueryParser = ComponentAccessor.getComponent(JqlQueryParser.class)
def searchProvider = ComponentAccessor.getComponent(SearchProvider.class)




def PriorityQueue<Agent> agentPQ = new PriorityQueue<>(agents.size(), new Comparator<Agent>() {
    @Override
    int compare(Agent o1, Agent o2) {
        if(o1.issueCount == o2.issueCount){
            if(o2.lastAssignedTime == o1.lastAssignedTime){
                return o1.user.name.compareTo(o2.user.name)
            }else{
                return o1.lastAssignedTime.compareTo(o2.lastAssignedTime)
            }
        }else{
            return  o1.issueCount - o2.issueCount
        }
    }
})




def jqlQuery = "status != Closed and assignee=null ORDER BY created DESC"
def query = jqlQueryParser.parseQuery(jqlQuery)
def results = searchProvider.search(query, user, PagerFilter.getUnlimitedFilter())

assignAgent(user,results, agents, jqlQueryParser, searchProvider,agentPQ)


def assignAgent(ApplicationUser admin,SearchResults results ,Collection<ApplicationUser> agents, JqlQueryParser jqlQueryParser, SearchProvider searchProvider, PriorityQueue<Agent> agentPQ){
    def issueManager = ComponentAccessor.issueManager
    MutableIssue mutableIssue = issueManager.getIssueObject(results.issues.get(0).id)
    agents.forEach{agent ->
        log.debug("agent = " + agent)
        Agent a = new Agent()

        def count = getIssueCountForAgent(agent, jqlQueryParser , searchProvider)
   
        if(count > 0){
            a.lastAssignedTime = getLastAssignedTimeForAgent(agent, jqlQueryParser , searchProvider)
            log.debug("Last assigned time for agent " + agent + "= " + a.lastAssignedTime)
            a.issueCount = count

        }else{
            a.lastAssignedTime = 0
            a.issueCount = 0
        }
        a.user = agent
        agentPQ.add(a)
    }
    log.debug(agentPQ.peek().user.name)

    log.debug("Assigning for issue = " + mutableIssue.key + " Desc = " + mutableIssue.description)
    /*mutableIssue.setAssignee(agentPQ.peek().user)
    mutableIssue.store()

    issueManager.updateIssue(admin, mutableIssue, createIssueUpdateRequest())*/
   /* def issueService = ComponentAccessor.getIssueService()
    IssueInputParameters params = ComponentAccessor.issueService.newIssueInputParameters()
    params.assigneeId = agentPQ.peek().user.id
    def validateUpdateResult = issueService.validateUpdate(admin,mutableIssue.id,params)

    if(!validateUpdateResult.errorCollection.hasAnyErrors()){
        log.debug("Assignee validated = " +  validateUpdateResult.fieldValuesHolder.get("assigneeId"))
        IssueService.IssueResult serviceResult=issueService.update(admin,validateUpdateResult)
        log.debug(serviceResult)
    }else{
        log.debug validateUpdateResult.errorCollection.errorMessages.toString()
    }*/

    def issueService = ComponentAccessor.getIssueService()
    def validateAssignResult = issueService.validateAssign(admin, mutableIssue.id, agentPQ.peek().user.name)
    if(validateAssignResult.errorCollection.hasAnyErrors()){
        log.debug("Validation failed" + validateAssignResult.errorCollection.getErrorMessages())
    }else{
        log.debug("Assignee validated = " +  validateAssignResult.assigneeId)
        IssueService.IssueResult issueResult = issueService.assign(admin, validateAssignResult)
        log.debug(issueResult)
    }

}


//Code to get time when the last issue was assigned to an user
def getLastAssignedTimeForAgent(ApplicationUser agent, JqlQueryParser jqlQueryParser, SearchProvider searchProvider ){
    def jqlQuery = "assignee=\""+ agent.name + "\" and status!=Closed "+  " ORDER BY created DESC"
    def query = jqlQueryParser.parseQuery(jqlQuery)
    log.debug("JQL Query = " + jqlQuery)
    def results = searchProvider.search(query, agent, PagerFilter.getUnlimitedFilter())
    if(results.issues.size() == 0)
        return 0;
    else{
        def changeLogManager = ComponentAccessor.changeHistoryManager
        def assignedAt = changeLogManager.getChangeItemsForField(results.issues.get(0),"assignee").find {
            it.toString == agent.name
        }?.getCreated() as Timestamp
        if(assignedAt){
            Date d = new Date(assignedAt.getTime())
            return  d.getTime()
        }else{
            return  0
        }
    }
}


//Code to get issue count
def getIssueCountForAgent(ApplicationUser agent ,JqlQueryParser jqlQueryParser, SearchProvider searchProvider ){
    def jqlQuery = "assignee=\""+ agent.name + "\" and status!=Closed "+  " ORDER BY created DESC"
    def query = jqlQueryParser.parseQuery(jqlQuery)
    def results = searchProvider.search(query, agent, PagerFilter.getUnlimitedFilter())
    return results.total
}

 

 

Mayur Gaikwad_Tech PMO February 5, 2024

Im getting below error when using this

Screenshot 2024-02-06 132412.png

Suggest an answer

Log in or Sign up to answer
TAGS
AUG Leaders

Atlassian Community Events