How to transition an issue from a groovy script in JIRA?

Ben Poulson
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.
October 17, 2018

I am trying to timeout issues with a certain route after x minutes of inactivity. The way I have it set up now is as follows:

1 scripted field that is a timestamp of the last comment.

Another scripted field that determines whether the issues has timed out (this works fine), and transitions it if it has (this does not work).

Here is the code for the field. Please forgive the unnecessarily large number of imports as I have hacked this together from various forum answers etc. I will clean them up once I've got it working.

 

import com.atlassian.jira.component.ComponentAccessor;
import com.atlassian.jira.issue.Issue;
import com.atlassian.jira.bc.issue.IssueService;
import com.atlassian.jira.issue.IssueInputParametersImpl;
import java.util.Date.*;
import org.apache.log4j.Logger;
import org.apache.log4j.Level;
import com.atlassian.jira.component.ComponentAccessor;
import com.atlassian.jira.event.issue.IssueEventBundle;
import com.atlassian.jira.event.issue.IssueEventManager;
import com.atlassian.jira.event.issue.IssueEventBundleFactory;
import com.atlassian.jira.event.issue.IssueEvent;

final int MINS=10; //Number of minutes until chat times out

def log = Logger.getLogger("com.acme.workflows")
log.level = Level.INFO;

// Used to get data from tickets
def customFieldManager = ComponentAccessor.getCustomFieldManager();
def route=issue.getCustomFieldValue(customFieldManager.getCustomFieldObjectByName("Route"));
if(route.toString().equals("Chat"))
{
// Defining what field were looking at
def fieldName = "Time Of Last Chat"; //This field is a timestamp of the last comment
def field=issue.getCustomFieldValue(customFieldManager.getCustomFieldObjectByName(fieldName));
Date last=(Date)field;
Date now=new Date();
long elapsed=(now.getTime()-last.getTime()); //Time between now and last comment in milliseconds
long threshhold=MINS*1000*60;
if(elapsed>threshhold)
{
def issueEventManager = ComponentAccessor.getIssueEventManager();
long EVENT_ID = 14110; //This is the ID of the timeout transition in the workflow.
def issueManager = ComponentAccessor.getIssueManager()
def user = ComponentAccessor.getUserManager().getUserByName('user_worker')

//HERE IS THE PROBLEM
IssueEventManager issueEventM = ComponentAccessor.getIssueEventManager()
IssueEventBundleFactory issueEventFactory = (IssueEventBundleFactory) ComponentAccessor.getComponent(IssueEventBundleFactory.class)

IssueEventBundle eventBundle = issueEventFactory.wrapInBundle(new IssueEvent (issue, null, user, EVENT_ID, true))
issueEventM.dispatchEvent(eventBundle)
//TO HERE

return "Timed Out";
}
else
{
return "Active";
}
}
return "N/A";

 There are no errors when this runs, the field populates correctly, it just doesn't transition the issue. I'm fairly new to Jira administration, so I might be fundamentally misunderstanding something here. My understanding is that dispatching the event should transition the issue- is this correct? Is there another way to do this? If this is the best way, does anybody know how to transition the issue from within a script?

 

Thanks in advance!

1 answer

1 accepted

0 votes
Answer accepted
Ben Poulson
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.
October 17, 2018

EDIT: I JUST REALIZED YOU CAN USE A SCRIPTRUNNER ESCALATION SERVICE TO DO THIS. ESCALATION SERVICES ARE SERVER SIDE AND YOU CAN SET THEM UP TO RUN AUTOMATICALLY LIKE A CRON JOB (THE BELOW SOLUTION ONLY RECALCULATES WHEN THE ISSUE IS REFRESHED). DO THAT INSTEAD.

 

 

 

I fixed it. For anyone in the future who might who stumbled onto this post, here's the code.

 

import com.atlassian.jira.component.ComponentAccessor;
import com.atlassian.jira.ComponentManager;
import com.atlassian.jira.issue.Issue;
import com.atlassian.jira.bc.issue.IssueService;
import com.atlassian.jira.issue.IssueInputParametersImpl;
import java.util.Date.*;
import org.apache.log4j.Logger;
import org.apache.log4j.Level;
import com.atlassian.jira.component.ComponentAccessor;
import com.atlassian.jira.event.issue.IssueEventBundle;
import com.atlassian.jira.event.issue.IssueEventManager;
import com.atlassian.jira.event.issue.IssueEventBundleFactory;
import com.atlassian.jira.event.issue.IssueEvent;
import com.opensymphony.workflow.WorkflowContext
import com.atlassian.jira.workflow.WorkflowTransitionUtil;
import com.atlassian.jira.workflow.WorkflowTransitionUtilImpl;
import com.atlassian.jira.util.JiraUtils;
import com.opensymphony.workflow.loader.StepDescriptor;
import com.atlassian.jira.*;
import com.atlassian.jira.workflow.WorkflowManager;
import com.atlassian.jira.workflow.JiraWorkflow;
import com.opensymphony.workflow.loader.ActionDescriptor;
import com.atlassian.jira.issue.MutableIssue
//Massively unnecessary amt of imports. I hacked this
//together from various SO, atlassian, etc. posts. I
//Don't want to delete any of those imports in case I
//break it.

final int MINS=10; //Number of minutes until chat times out

def log = Logger.getLogger("com.acme.workflows")
log.level = Level.INFO;
// Used to get data from tickets
def customFieldManager = ComponentAccessor.getCustomFieldManager();
def route=issue.getCustomFieldValue(customFieldManager.getCustomFieldObjectByName("Route"));
if(route.toString().equals("Chat") && !(issue.getStatusObject().getName().toString().equals("Completed") || issue.getStatusObject().getName().toString().equals("Chat Timed Out")))
{
// Defining what field were looking at
def fieldName = "Time Of Last Chat";
def field=issue.getCustomFieldValue(customFieldManager.getCustomFieldObjectByName(fieldName));
log.error(field)
Date last=(Date)field;
Date now=new Date();
long elapsed=(now.getTime()-last.getTime()); //Time between now and last comment in milliseconds
long threshhold=MINS*1000*60;
if(elapsed>threshhold)
{
def issueEventManager = ComponentAccessor.getIssueEventManager();
int EVENT_ID = 201;
def issueManager = ComponentAccessor.getIssueManager()
def user = ComponentAccessor.getUserManager().getUserByName('user_worker')
ComponentManager componentManager = ComponentManager.getInstance()
WorkflowTransitionUtil workflowTransitionUtil = ( WorkflowTransitionUtil ) JiraUtils.loadComponent( WorkflowTransitionUtilImpl.class );
MutableIssue mi = issueManager.getIssueObject(issue.getKey());
workflowTransitionUtil.setIssue(mi);
workflowTransitionUtil.setUsername("user@email.com");
workflowTransitionUtil.setAction(EVENT_ID);
workflowTransitionUtil.validate();
workflowTransitionUtil.progress();


return "Timed Out";
}
else
{
return "Active";
}
}
return "N/A";

Suggest an answer

Log in or Sign up to answer