There are at least three ways to change issue status I know (I am two weeks in Jira API):
1. set status to value and shoot store() on it - Does not appear to do things right as UI still shows transitions per previous state. Can reidex help?
2. do issueManager.updateIssue(...) -have not tried this one yet
3. Do proper workflow transition with WorkflowManager - appears overkill at first glance assuming there are no specific conditions or validations I cannot do in code prior to status change
What is the Kosher way of doing it? Samples?
Community moderators have prevented the ability to post new answers.
1. No.
Those issues are very broken - you need to set them back to the previous status, then run the integrity checker. You might need to reindex as well, but you could trigger that by making any other change to the issue, rather than redoing the whole system.
2. Don't bother - it's much the same as point 1 - you're changing too little of the data you need to hit and you'll simply break the issues
3. This is the right way to do it. Yes, there are conditions/validators/post-functions you can run here, but it will also handle all the other things that just changing the status will break. There's an assumption here - that Status is a field like the other issue attributes, but that's incorrect - status is a consequence of a position in a workflow. Ideally, it should be removed from the issue completely, which would save a lot of confusion...
I have this scribbled down for some stuff I vaguely need to do in the future (although I've not tried it in anger yet):
TransitionValidationResult validationResult = issueService.validateTransition(user, theIssue.id, actionId
as
Integer, issueInputParameters)
issueService.transition(user, validationResult)
You want to change the status of the issue , this means you want to transition the issue from one status to another , Have a look at the below code snippet , you will get an idea how to transition an issue programmatically .
MutableIssue issue1=getIssueObject(); final String remoteuser=ComponentManager.getInstance().getJiraAuthenticationContext().getUser().getName(); WorkflowTransitionUtil workflowTransitionUtil = ( WorkflowTransitionUtil ) JiraUtils.loadComponent( WorkflowTransitionUtilImpl.class ); workflowTransitionUtil.setIssue(issue1); workflowTransitionUtil.setUsername(remoteuser); workflowTransitionUtil.setAction(5);//Id of the status you want to transition to workflowTransitionUtil.progress();
Hope it helps :)
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
This works but using IssueService is preferred going forward. If it's available in your jira version, use it...
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Jamie, got code snippet? It's just so confusing to have so much choice :)
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
IssueService issueService = ComponentManager.getComponentInstanceOfType(IssueService.class) IssueInputParameters issueInputParameters = new IssueInputParametersImpl([:]) issueInputParameters.setComment("Test script transitioned this to resolved...") issueInputParameters.setResolutionId("2") IssueService.TransitionValidationResult validationResult = issueService.validateTransition(adminUser, issue.id, 5 as Integer, issueInputParameters) def errorCollection = validationResult.errorCollection log.debug(errorCollection) if (! errorCollection.hasAnyErrors()) { issueService.transition(adminUser, validationResult) } else { // log errors etc }
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
@Jamie Echlin [Adaptavist] , Thanks for the code.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Mizan; It update only in history but not on view issue page what is a problem?
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
I m facing this problem... but I don t have a transition from 'oldstatus' to 'newstatus'. Can I change the status without using a transition? Can I execute a 'Integrity Checker' in one issue?
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
I call my transitionIssue function from here and then call an update function which does reIndex.
@Override void issueClosed(IssueEvent event) { log.warn("----------------------------") log.warn("Issue Closed Event: " + event.getEventTypeId() + " fired for issue: " + event.getIssue().toString() + " and caught by Incomplete Story Listener") //Transition the issue to reopened so we can edit it. transitionIssue(event.getIssue(), getActionId(event.getIssue(),ISSUE_ACTION_REOPEN),ISSUE_STATUS_REOPENED); // Reload the issue and Re-index it updateIncomplete(event.getIssue()); }
This is the transition function
boolean transitionIssue(Issue issue, int actionID, String targetStatus) { log.warn("Trying to transition issue " + issue.getKey() + " with action ID " + actionID + "\n"); IssueService.TransitionValidationResult validationResult; def res = false; if (actionID) { def issueInputParameters = issueService.newIssueInputParameters(); issueInputParameters.setStatusId(targetStatus); issueInputParameters.setSkipScreenCheck(true); issueInputParameters.setResolutionId(null); validationResult = this.issueService.validateTransition(this.authContext.getUser().getDirectoryUser(), issue.getId(), actionID, issueInputParameters); if (validationResult.isValid()) { log.warn("Transition validated. Let's do it."); def IssueService.IssueResult transitionResult = this.issueService.transition(this.authContext.getUser().getDirectoryUser(), validationResult); if(transitionResult.isValid()){ log.warn("Succesfully transitioned: " + transitionResult.getIssue().toString()); } else { showIssueErrors(transitionResult); } // Here I print out the status of the transition result. It is Reopened!!!! log.warn("Transition result status is: " + transitionResult.getIssue().getStatusObject().getName()); } else { showTransitionErrors(validationResult); } res = validationResult.isValid(); } else { log.warn("NO valid ActionID!!!!") } return res; }
This is the Update Function
Issue updateIncomplete(Issue issue) { log.warn("updating issue: " + issue.toString() + " which is in state: " + issue.getStatusObject().getName()) def issueInputParameters = issueService.newIssueInputParameters(); issueInputParameters.setStatusId(ISSUE_STATUS_REOPENED); issueInputParameters.setResolutionId(null); IssueService.UpdateValidationResult validationRes = issueService.validateUpdate(authContext.getUser().getDirectoryUser(), issue.getId(), issueInputParameters); if(validationRes.isValid()) { IssueService.IssueResult updateResult = issueService.update(authContext.getUser().getDirectoryUser(),validationRes); } else { Collection<String> errors = validationRes.getErrorCollection().getErrorMessages(); for(String errMsg in errors) { log.warn("[ERROR] - Error message:" + errmsg); } } def idxMgr = ComponentAccessor.getIssueIndexManager(); idxMgr.reIndex(issue); log.warn("What is the status of the updated issue?? " + issue.getStatusObject().getName()); }
So the issue is in Closed. I transition it. The transition result says status is Reopened. I then do an update to set status to Reopened followed by a reIndex. Status never moves from closed
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
This is a 4 year old block of code with no Jira version referenced, so there's no way of knowing whether it might have been mildly tweaked to fix it, or completely rewritten.
You will need to check that your code is valid for your version of Jira and then share the detail of what you're doing if you want more help with it.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
That's correct. I have made necessary code changes at my end. After applying the reindex of issue it doesn't change the status in the UI. I don't know what I'm missing here. The problem is same as above.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Then your code has not been changed correctly, as it's not changing the status. I'm afraid we can't tell you what might be wrong without seeing it (and knowing what version of Jira you are aon)
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hello Nic,
thanks for your response.
here is the code snippet.
else if( EventType.ISSUE_GENERICEVENT_ID.equals(eventTypeId) && IssueEventSource.WORKFLOW.equals(eventSource)){
//Custom workflow event.
JiraWorkflow workFlow = ComponentAccessor.getWorkflowManager().getWorkflow(issue);
Status status = issue.getStatus();
if(null!= status && status.getName().equalsIgnoreCase("Done")) {
MutableIssue mutableIssue = ComponentAccessor.getIssueManager().getIssueObject(issue.getId());
int actionId = 0;
ChangeHistoryManager changeHistoryManager = ComponentAccessor.getChangeHistoryManager();
String oldStatusId = changeHistoryManager.getChangeItemsForField(issue, "status").get(changeHistoryManager.getChangeItemsForField(issue, "status").size() - 1).getFrom();
Status oldStatus = ComponentAccessor.getConstantsManager().getStatusObject(oldStatusId);
Collection<ActionDescriptor> actions = workFlow.getAllActions();
if(null != oldStatus) {
for (ActionDescriptor actionDescriptor : actions) {
if (actionDescriptor.getName().equals(oldStatus.getName())) {
actionId = actionDescriptor.getId();
}
}
IssueService issueService = ComponentAccessor.getIssueService();
issueService.newIssueInputParameters().setStatusId(oldStatusId).setResolutionId(null).setSkipScreenCheck(true);
IssueService.TransitionValidationResult transitionValidationResult = issueService
.validateTransition(authContext.getLoggedInUser(),
issue.getId(), actionId, issueService.newIssueInputParameters());
if (transitionValidationResult.isValid()) {
transitionValidationResult.getIssue().setStatus(oldStatus);
IssueService.IssueResult transitionResult = issueService.transition(
authContext.getLoggedInUser(), transitionValidationResult);
if (transitionResult.isValid()) {
// Do something
log.info("Valid transition :::: "+ transitionResult.isValid());
IssueIndexingService issueIndexingService = ComponentAccessor.getComponent(IssueIndexingService.class);
IssueIndexingParams params = IssueIndexingParams.INDEX_ALL;
try {
List<Issue> issues = new ArrayList<>();
issues.add(issue);
long durationMillis = issueIndexingService.reIndexIssueObjects(issues, params);
log.info("Re indexed {} issues in {} milliseconds.", issues.size(), durationMillis);
} catch (IndexException e) {
log.warn("Failed to reindex issues.", e);
}
}
}
}
}
}
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Well, I am using issueService to do the transitions and to me it looks as if it is broken. I have a listener on issue event "Closed". If a condition is met, I am moving the issue back to "Reopened". There is more to the use case but that is not important right now and I don't think it maters what event you are listening to or the status you want to transition the issue to.
Basically the status and resolution are NOT set but the issue HAS BEEN transitioned in the workflow. I think it is because the previous transition and update is somehow NOT complete. Even though the I have recieved the "IssueClosed" event.
From an agile board I drag an issue to "Closed" status.
On the board the issues status and resolution are still "Closed" and "Fixed". If I open the issue, the workflow shows the issue is in the "Reopened" status, i.e, I can transition it to "In Progress". So the issue status and resolutiona are out of sync. I have tried updating Status and resolution on the issue AFTER the transition but have had no luck.
If my assumption that the issue is still being processed by the UI action when I try to transition it to a new state is correct. And this is the cause of the failed updates then I think the API could be called broken. I think it should ensure ordered actions on issues. Either by queueing them or by not sending the event until the issue updates are actually finished.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Those symptoms are yelling "the indexing is not being done". As a general rule, JIRA works off the index, so most searches and displays like the issue navigator and gadgets are showing you index data. Issue updates and, most importantly, issue *view* read the database. So when you change an issue and it looks fine in view but wrong in the navigator/gadget/board, it's the index. Does your code try to index the changed issue at all?
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
This is the function I am calling from the IssueClosed event. boolean transitionIssue(Issue issue, int actionID, String targetStatus) { log.warn("Trying to transition issue " + issue.getKey() + " with action ID " + actionID + "\n"); IssueService.TransitionValidationResult validationResult; def res = false; if (actionID) { def idxMgr = ComponentAccessor.getIssueIndexManager(); def issueInputParameters = issueService.newIssueInputParameters(); issueInputParameters.setStatusId(targetStatus); issueInputParameters.setResolutionId(null); validationResult = this.issueService.validateTransition(this.authContext.getUser().getDirectoryUser(), issue.getId(), actionID, issueInputParameters); if (validationResult.isValid()) { log.warn("Transition validated. Let's do it."); def IssueService.IssueResult transitionResult = this.issueService.transition(this.authContext.getUser().getDirectoryUser(), validationResult); if(transitionResult.isValid()){ log.warn("Succesfully transitioned: " + transitionResult.getIssue().toString()); } else { Collection<String> errors = transitionResult.getErrorCollection().getErrorMessages(); for (errmsg in errors){ log.warn("[ERROR] - Error message:" + errmsg); } } idxMgr.reIndex(validationResult.getIssue()); } else { Collection<String> errors = validationResult.getErrorCollection().getErrorMessages(); for (errmsg in errors) { log.warn("[ERROR] - Error message:" + errmsg); } } res = validationResult.isValid(); } else { log.warn("NO valid ActionID!!!!") } return res; } I have also tired a full reindex but that changes nothing.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Sorry it's a bit messy. But I do call reIndex with the ValidationResult. Quite possible I am doing something wrong. So any help would be appreciated!
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Community moderators have prevented the ability to post new answers.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.