Capturing the custom field value of an issue

custom-field
eventlisteners
jira-server

#1

Hello Community,

I am stuck on this problem since last one week. I am actually creating one addon using Java and Maven which will help me in integrating jira with some other third party tool.

What I want to do is to capture the current values of the fields on the particular issue and pass them to the other tool using webservices. Capturing the same works well for jira default fields but for custom fields nothing seems to be happening. The value always comes out to be null. Following is the snapshot of the code that I have written,

import com.atlassian.event.api.EventListener;
import com.atlassian.event.api.EventPublisher;
import com.atlassian.jira.component.ComponentAccessor;
import com.atlassian.jira.event.issue.IssueEvent;
import com.atlassian.jira.issue.Issue;
import com.atlassian.jira.issue.fields.CustomField;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Iterator;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;

 

public class IssueCreatedResolvedListener implements InitializingBean, DisposableBean {

private final EventPublisher eventPublisher;
public String field = null;
public String fromValue = null;
public String toValue = null;
public String user = null;
public String issueType = null;
public String jiraId = null;
public String silo=null;

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) throws IOException {
Issue issue = issueEvent.getIssue();

CustomField cf=ComponentAccessor.getCustomFieldManager().getCustomFieldObject((long) 14440);
silo=cf.getValueFromIssue(issue);

}

In the above code the field silo is a custom field in our instance and 14440 is the ID of the same. But this value always comes null.

Can you please suggest where I am making any mistakes? Your help would be highly appreciated. Thanks in advance :slight_smile: :slight_smile:


#2

Hi @Bhushan.Patil,

Can you verify and try to GET localhost:8080/rest/api/<issue_id> for desired issue_id and go to the customefield’s id?

If you inspect the value of issue from issueEvent.getIssue() and try: issue.getCustomFieldValue(CustomField), what do you get?

It would be worthy to take a look into this answered community post as well.

Cheers,
Anne Calantog


#3

Hi Anne,

I have tried to access <my_server_ip>:port/rest/api/<issue_id> but it gave me a dead link error.
I have checked the value of issue from issueEvent.getIssue(); and it gave me the issue name to which I have made changes. So that is ok.
Then I tried issue.getCustomfieldvalue(CustomField) but my code didn’t work.
If needed I can share you the whole code with you. Please help as I have critical delivery :frowning:


#4
import com.atlassian.event.api.EventListener;
import com.atlassian.event.api.EventPublisher;
import com.atlassian.jira.component.ComponentAccessor;
import com.atlassian.jira.event.issue.IssueEvent;
import com.atlassian.jira.issue.Issue;
import com.atlassian.jira.issue.changehistory.ChangeHistory;
import com.atlassian.jira.issue.changehistory.ChangeHistoryManager;
import com.atlassian.jira.issue.fields.CustomField;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Iterator;
import org.ofbiz.core.entity.GenericValue;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;

public class IssueCreatedResolvedListener implements InitializingBean, DisposableBean {

	private final EventPublisher eventPublisher;
	public String field = null;
	public String fromValue = null;
	public String toValue = null;
	public String user = null;
	public String issueType = null;
	public String jiraId = null;
	public String silo=null;
	public long silo_id=14440;
	public String summary=null;

	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) throws IOException {
		Issue issue = issueEvent.getIssue();
		ChangeHistoryManager chm = ComponentAccessor.getChangeHistoryManager();
		ChangeHistory changeHistory = chm.getChangeHistoryById(issueEvent.getChangeLog().getLong("id"));
		Writer writer = null;
		CustomField cf=ComponentAccessor.getCustomFieldManager().getCustomFieldObject(silo_id);
		silo=(String) issue.getCustomFieldValue(cf);
		try {
			try {
				File file = new File("/data2/jboss/CA_JIRA/IssueUpdates/" + issue.getKey() + "-Field.txt");
				writer = new BufferedWriter(new FileWriter(file));
				Iterator<GenericValue> itr = changeHistory.getChangeItems().listIterator();
				user = changeHistory.getAuthorKey();
				jiraId = issue.getKey();
				issueType = issue.getIssueTypeObject().getName();
				summary=issue.getSummary();
				writer.write("  " + "\r\n"
						+ "****************************************************************************************************************"
						+ "\r\n" + "Issue Update Details" + "  " + issue.getUpdated()+"\r\n"
						+ "****************************************************************************************************************"
						+ "\r\n\r\n");

				while (itr.hasNext()) {
					GenericValue genvalue = itr.next();
					field = (String) genvalue.getAllFields().get("field");
					fromValue = (String) genvalue.getAllFields().get("oldstring");
					toValue = (String) genvalue.getAllFields().get("newstring");

					if (!"admin".equals(user)) {
						if(issueType.equalsIgnoreCase("Request")){
							if(field.equalsIgnoreCase("Description")){
								String url1 = //Desired URL
								String encurl = url1.replace(" ", "%20");
								URL url = new URL(encurl);
								try {
									HttpURLConnection conn = (HttpURLConnection) url.openConnection();
									writer.write(String.format("%10s %10s \r\n", "Silo =", silo));
									writer.write(String.format("%10s %10s \r\n", "Summary =", summary));
									writer.write(String.format("%10s %10s \r\n", "User =", user));
									writer.write(String.format("%10s %10s \r\n", "Field =", field));
									writer.write(String.format("%10s %10s \r\n", "From =", fromValue));
									writer.write(String.format("%10s %10s \r\n", "To =", toValue));
									writer.write(String.format("%10s %10s \r\n", "URL =", url));
									writer.write(String.format("%10s %10s \r\n", "Message =",
											conn.getResponseCode() + ":" + conn.getResponseMessage()));
								} catch (MalformedURLException e) {
									e.printStackTrace();
								}
							}
						}//end of Request if
					}//end of user if
				}//end of while

			}catch(

	FileNotFoundException e)
	{
		e.printStackTrace();
	}catch(
	IOException e)
	{
		e.printStackTrace();
	}finally
	{
		if (writer != null) {
			writer.close();
		}
	}}catch(
	Exception e)
	{
			e.printStackTrace();
		} // end of finally
}// end of method
}// end of class

#5

Do the custom fields you are trying to get the values from return dates or numbers?

Have you tried calling getValue instead of getValueFromIssue ?

So change silo=cf.getValueFromIssue(issue); to silo=cf.getValue(issue); and change silo from String to Object

If you look at getValueFromIssue on the Jira ImmutableCustomField it expects the values to be a string

This is the jira source on ImmutableCustomField…

public String getValueFromIssue(Issue issue) {
    Object value = getValue(issue);

    if (!(value instanceof String)) {
        return null;
    } else {
        return (String) value;
    }
}

This has caused an issue for me before


#6

Hi David,

It your suggestion did work for some of the custom fields. But some fields the value came null. Just for curiosity I checked our jira database and found that there is no value stored for the desired customfield under Customfieldvalue table even if the on front end I can see the values on issue page.
Is database value the culprit?


#7

Hi are these other fields from another plugin that might not store the values in the database? Check the custom field type of the field where you can see them on screen but not in the database. They might be calculated fields? However they should be returning a value from getValueFromIssue in the custom field type of the custom field. Below is the jira source for getValue on ImmutableCustomField

@Override
public Object getValue(Issue issue) {
    return getCustomFieldType().getValueFromIssue(this, issue);
}

If its a calculated field that doesn’t store a database value then its my understanding it should still be returning some from this method.


#8

Hi David,

This field is of type com.atlassian.jira.plugin.system.customfieldtypes:textfield

Please suggest.


#9

That is one of the standard Jira text custom fields and uses the customFieldValuePersister in the AbstractSingleFieldType that is used by many custom fields. It makes sense if there is no database value then the API calls are consistent with that. Not sure why values are still visible in the view screen. Have you restarted and reindexed the jira you are testing against? If not get a test copy of it and test against that. Its the only other thing I can think of at the moment. Anyone have any other suggestions?


#10

Hi David,

I am facing an issue in calling the methods in my listener class.

I am not sure how can I share the whole code with you so that you could understand my conern.


#11

Hello,

Did you find the solution?

Regards