It's not the same without you

Join the community to find out what other Atlassian users are discussing, debating and creating.

Atlassian Community Hero Image Collage

issue updated event contents

I'm writing a listener that will listen for issue updated events. Is there a way to read what changed that caused the issue updated event. The changlog is printed out to catalina.out when using the com.atlassian.jira.event.listener.DebugListener. I'm looking to get the same information for evaluation in the listener.

3 answers

1 accepted

6 votes
Answer accepted

I was able to figure it out. The code below worked for me.

public void onIssueEvent(IssueEvent issueEvent) {
        Long eventTypeId = issueEvent.getEventTypeId();
        Issue issue = issueEvent.getIssue();
        User user = issueEvent.getUser();
      
        
        // if it's an event we're interested in, log it
        if (eventTypeId.equals(EventType.ISSUE_CREATED_ID)) {
            log.info("Issue {} has been created at {}.", issue.getKey(), issue.getCreated());
        } else if (eventTypeId.equals(EventType.ISSUE_RESOLVED_ID)) {
            log.info("Issue {} has been resolved at {}.", issue.getKey(), issue.getResolutionDate());
        } else if (eventTypeId.equals(EventType.ISSUE_CLOSED_ID)) {
            log.info("Issue {} has been closed at {}.", issue.getKey(), issue.getUpdated());
        } else if (eventTypeId.equals(EventType.ISSUE_UPDATED_ID)) {
        	List<GenericValue> changeItems = null;
        	
        	try {
        		GenericValue changeLog = issueEvent.getChangeLog();
            	changeItems = changeLog.internalDelegator.findByAnd("ChangeItem", EasyMap.build("group",changeLog.get("id")));
        	} catch (GenericEntityException e){
        		System.out.println(e.getMessage());
        	}
        	
        	log.info("number of changes: {}",changeItems.size());
        	for (Iterator<GenericValue> iterator = changeItems.iterator(); iterator.hasNext();){
        		GenericValue changetemp = (GenericValue) iterator.next();
	        		String field = changetemp.getString("field");
	        		String oldstring = changetemp.getString("oldstring");
	        		String newstring = changetemp.getString("newstring");
	        		StringBuilder fullstring = new StringBuilder();
	        		fullstring.append("Issue ");
	        		fullstring.append(issue.getKey());
	        		fullstring.append(" field ");
	        		fullstring.append(field);
	        		fullstring.append(" has been updated from ");
	        		fullstring.append(oldstring);
	        		fullstring.append(" to ");
	        		fullstring.append(newstring);
	        		log.info("changes {}", fullstring.toString());
	        		
	        		if(field == "Component") changeAssignee(changetemp, issue, user);
	        	}
          }
    }

   
    private void changeAssignee(GenericValue changetemp, Issue issue, User user) {
		String currentAssignee = issue.getAssigneeId();
		String componentName = null;
		String componentLead = null;
		Collection<ProjectComponent> components = issue.getComponentObjects();
		//log.info("current assignee: {}", currentAssignee);
		
		for (Iterator<ProjectComponent> iterator = components.iterator(); iterator.hasNext();){
			ProjectComponent component = (ProjectComponent) iterator.next();
			componentName = component.getName();
			componentLead = component.getLead();
			log.info("component name: {}", componentName);
			log.info("component lead: {}", componentLead);

		}
		if (currentAssignee != componentLead && components.size() == 1){
			MutableIssue mIssue = (MutableIssue) issue;
			mIssue.setAssigneeId(componentLead);
			IssueService issueService = ComponentAccessor.getIssueService();

			IssueInputParameters issueInputParameters = issueService.newIssueInputParameters();
			issueInputParameters.setAssigneeId(componentLead);
			 
			UpdateValidationResult updateValidationResult = issueService.validateUpdate(user,mIssue.getId(), issueInputParameters);
			 
			if (updateValidationResult.isValid())
			{
			    IssueResult updateResult = issueService.update(user, updateValidationResult);
			    if (!updateResult.isValid())
			    {
			        log.info("Issue Assignee changed");
			    }
			}
		}
	}

I agree, this API could use some re-design :-) Thanks for sharing the solution with us!

package com.example.tutorial.plugins;
import com.atlassian.event.api.EventListener;
import com.atlassian.event.api.EventPublisher;
import com.atlassian.jira.event.issue.IssueEvent;
import com.atlassian.jira.event.type.EventType;
import com.atlassian.jira.issue.Issue;
import com.atlassian.jira.issue.IssueInputParameters;
import com.atlassian.plugin.spring.scanner.annotation.imports.JiraImport;
import com.atlassian.jira.user.ApplicationUser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.ofbiz.core.entity.GenericValue;
import org.ofbiz.core.entity.GenericEntityException;
import com.atlassian.jira.issue.MutableIssue;
import com.atlassian.jira.component.ComponentAccessor;
import com.atlassian.jira.bc.project.component.ProjectComponent;
import com.atlassian.jira.bc.issue.IssueService;
import com.atlassian.jira.bc.issue.IssueService.IssueResult;
import com.atlassian.jira.bc.issue.IssueService.UpdateValidationResult;
import com.atlassian.jira.util.collect.MapBuilder;
import java.util.List;
import java.util.*;



@Component
public class IssueUpdateListener {
private static final Logger log = LoggerFactory.getLogger(IssueUpdateListener.class);


@Autowired
public IssueUpdateListener(@JiraImport EventPublisher eventPublisher) {
eventPublisher.register(this); // Demonstration only -- don't do this in real code!
}

@EventListener
public void onIssueEvent(IssueEvent issueEvent) {
Long eventTypeId = issueEvent.getEventTypeId();
Issue issue = issueEvent.getIssue();
ApplicationUser user = issueEvent.getUser();


// if it's an event we're interested in, log it
if (eventTypeId.equals(EventType.ISSUE_CREATED_ID)) {
log.info("Issue {} has been created at {}.", issue.getKey(), issue.getCreated());
} else if (eventTypeId.equals(EventType.ISSUE_RESOLVED_ID)) {
log.info("Issue {} has been resolved at {}.", issue.getKey(), issue.getResolutionDate());
} else if (eventTypeId.equals(EventType.ISSUE_CLOSED_ID)) {
log.info("Issue {} has been closed at {}.", issue.getKey(), issue.getUpdated());
} else if (eventTypeId.equals(EventType.ISSUE_UPDATED_ID)) {
List<GenericValue> changeItems = null;

try {
GenericValue changeLog = issueEvent.getChangeLog();
changeItems = changeLog.internalDelegator.findByAnd("ChangeItem", MapBuilder.build("group",changeLog.get("id")));
} catch (GenericEntityException e){
System.out.println(e.getMessage());
}

log.info("number of changes: {}",changeItems.size());
for (Iterator<GenericValue> iterator = changeItems.iterator(); iterator.hasNext();){
GenericValue changetemp = (GenericValue) iterator.next();
String field = changetemp.getString("field");
String oldstring = changetemp.getString("oldstring");
String newstring = changetemp.getString("newstring");
StringBuilder fullstring = new StringBuilder();
fullstring.append("Issue ");
fullstring.append(issue.getKey());
fullstring.append(" field ");
fullstring.append(field);
fullstring.append(" has been updated from ");
fullstring.append(oldstring);
fullstring.append(" to ");
fullstring.append(newstring);
log.info("changes {}", fullstring.toString());

if(field == "Component") changeAssignee(changetemp, issue, user);
}
}
}


private void changeAssignee(GenericValue changetemp, Issue issue, ApplicationUser user) {
String currentAssignee = issue.getAssigneeId();
String componentName = null;
String componentLead = null;
Collection<ProjectComponent> components = issue.getComponentObjects();
//log.info("current assignee: {}", currentAssignee);

for (Iterator<ProjectComponent> iterator = components.iterator(); iterator.hasNext();){
ProjectComponent component = (ProjectComponent) iterator.next();
componentName = component.getName();
componentLead = component.getLead();
log.info("component name: {}", componentName);
log.info("component lead: {}", componentLead);

}
if (currentAssignee != componentLead && components.size() == 1){
MutableIssue mIssue = (MutableIssue) issue;
mIssue.setAssigneeId(componentLead);
IssueService issueService = ComponentAccessor.getIssueService();

IssueInputParameters issueInputParameters = issueService.newIssueInputParameters();
issueInputParameters.setAssigneeId(componentLead);

UpdateValidationResult updateValidationResult = issueService.validateUpdate(user,mIssue.getId(), issueInputParameters);

if (updateValidationResult.isValid())
{
IssueResult updateResult = issueService.update(user, updateValidationResult);
if (!updateResult.isValid())
{
log.info("Issue Assignee changed");
}
}
}
}}

You can get the changelog from IssueEvent object. Use getChangeLog() method. You can get change items from the changelog using OfBizDelegator.

Long id = changeLog.getLong("id");
List&lt;GenericValue&gt; changes = this.delegator.findByAnd("ChangeItem", MapBuilder.build("group", id));

I'm thinking I made a wrong move somewhere. Can you help me with this. I'm using the tutorial code as a base for learning purposes.

Some imports removed for length.

package com.example.tutorial.plugins;

import java.util.List;

import com.atlassian.jira.util.collect.MapBuilder;
import com.atlassian.jira.ofbiz.OfBizDelegator;

import org.ofbiz.core.entity.GenericValue;

public class IssueCreatedResolvedListener implements InitializingBean, DisposableBean {

    private static final Logger log = LoggerFactory.getLogger(IssueCreatedResolvedListener.class);

    private final EventPublisher eventPublisher;

    private OfBizDelegator delegator;

    public IssueCreatedResolvedListener(EventPublisher eventPublisher) {
        this.eventPublisher = eventPublisher;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        // register ourselves with the EventPublisher
        eventPublisher.register(this);
    }

    @Override
    public void destroy() throws Exception {
        // unregister ourselves with the EventPublisher
        eventPublisher.unregister(this);
    }

    @EventListener
    public void onIssueEvent(IssueEvent issueEvent) {
        Long eventTypeId = issueEvent.getEventTypeId();
        Issue issue = issueEvent.getIssue();
        
        // if it's an event we're interested in, log it
if (eventTypeId.equals(EventType.ISSUE_UPDATED_ID)) {
        	GenericValue changeLog = issueEvent.getChangeLog();
        	Long id = changeLog.getLong("id");
        	List&lt;GenericValue&gt; changes = delegator.findByAnd("ChangeItem", MapBuilder.build("group", id));
        	String updated = changes.toString();
        	log.info("Issue {} has been updated with {}", issue.getKey(),updated);
        }
    }
}

What exactly are you trying to get? You can iterate on the changeItems and get the changes.

String field = change.getString("field");
String oldValue = change.getString("oldstring");
String newValue = change.getString("newstring");

Hi Jobin, below code snippet is not working. I am using JIRA 6.1.6. What is wrong here? Could you please help? {code} try{ GenericValue changeLog = issueEvent.getChangeLog(); Long id = changeLog.getLong("id"); List<GenericValue> changes = this.delegator.findByAnd("ChangeItem", MapBuilder.build("group", id)); for(GenericValue change: changes){ String field = change.getString("field"); String oldValue = change.getString("oldstring"); String newValue = change.getString("newstring"); log.info(field + " - "+oldValue+" - "+newValue+" - "+change.getEntityName()); } }catch(Exception e){ log.error(e.getMessage()); } {code}

It is working with the below code change List<GenericValue> changes = changeLog.internalDelegator.findByAnd("ChangeItem", MapBuilder.build("group",changeLog.get("id"))); thanks, Srinivas

Suggest an answer

Log in or Sign up to answer
This widget could not be displayed.
This widget could not be displayed.
Community showcase
Posted 5 hours ago in Off-topic

Miscellaneous Monday - Where it all started.

Happy Monday everyone! If you're anything like me, you tend to think a lot about what the future looks like. What are my kids up to in 15 years? Have we solved for climate change? How could TVs poss...

18 views 1 1
Join discussion

Atlassian User Groups

Connect with like-minded Atlassian users at free events near you!

Find a group

Connect with like-minded Atlassian users at free events near you!

Find my local user group

Unfortunately there are no AUG chapters near you at the moment.

Start an AUG

You're one step closer to meeting fellow Atlassian users at your local meet up. Learn more about AUGs

Groups near you