Custom field shows up EMPTY with a value in it

Scott Evans October 3, 2012

I am working on a Groovy script that will update a custom field in numerous tickets based on the fixVersion. I have a "release" type issue that has subtasks. Each subtask represents a product fixVersion that should be released at the same time. Each issue has a custom field called releaseTrain.

When the release issue is updated, the code will clear out the old releaseTrain field on any issue with a matching fixVersion listed in the subtasks and replace it with the releaseTrain value from the release issue.

The following code works and I see the releaseTrain field correctly set. If I filter on fixVersions that should be changed, the releaseTrain field holds the correct value. However, if I filter on releaseTrain, those issues don't show up in the results. I can filter on releaseTrain is EMPTY and I can see issues where the releaseTrain field has a value in it.

How do I set the value and be able to filter on releaseTrain? Please let me know what I'm missing (or doing wrong).

George

package com.custom
 
import com.atlassian.jira.event.issue.IssueEvent
import org.apache.log4j.Category

import com.atlassian.jira.issue.CustomFieldManager
import com.atlassian.jira.issue.ModifiedValue
import com.atlassian.jira.issue.util.DefaultIssueChangeHolder
import com.atlassian.jira.issue.util.IssueChangeHolder
//import com.atlassian.jira.issue.history
import com.atlassian.jira.issue.changehistory.ChangeHistoryManager
import com.atlassian.jira.util.ImportUtils
import com.atlassian.jira.user.util.UserUtil
import com.atlassian.jira.ComponentManager
import com.atlassian.jira.bc.JiraServiceContext
import com.atlassian.jira.bc.JiraServiceContextImpl
import com.atlassian.jira.bc.filter.SearchRequestService
import com.atlassian.jira.event.issue.AbstractIssueEventListener
import com.atlassian.jira.event.issue.IssueEvent
import com.atlassian.jira.issue.IssueManager
import com.atlassian.jira.issue.MutableIssue
import com.atlassian.jira.issue.Issue;
import com.atlassian.jira.issue.fields.CustomField
import com.atlassian.jira.issue.search.SearchRequest
import com.atlassian.jira.issue.search.SearchResults
import com.atlassian.jira.issue.search.SearchException;
import com.atlassian.jira.issue.search.SearchProvider;
import com.atlassian.jira.bc.issue.search.SearchService
import com.atlassian.jira.web.bean.PagerFilter
import com.atlassian.jira.issue.util.DefaultIssueChangeHolder
import com.atlassian.jira.issue.fields.layout.field.FieldLayoutManager;
import com.atlassian.jira.issue.fields.layout.field.FieldLayoutItem;
import com.atlassian.jira.issue.fields.layout.field.EditableFieldLayout;
import com.atlassian.jira.jql.builder.JqlQueryBuilder
import com.atlassian.jira.jql.parser.JqlQueryParser
import com.atlassian.query.Query

//----------------------------------------------------------------------
// UpdateRelease Listener
// 
//    When a Release issue is updated, this Listener will fill in the ReleaseTrain field for appropriate tickets
//    

class ReleaseListener extends AbstractIssueEventListener {
   Category log = Category.getInstance(ReleaseListener.class)

    ComponentManager  cm           = ComponentManager.getInstance()
    def               cfm          = cm.getCustomFieldManager()
    def               lm           = cm.getFieldLayoutManager()
    def               fm           = cm.getFieldManager()
    def               chm          = cm.getChangeHistoryManager()
   
    @Override
    void workflowEvent(IssueEvent event) {
        MutableIssue issue = event.issue as MutableIssue    
        log.setLevel(org.apache.log4j.Level.DEBUG)
        
        //Get current state of the indexer (usually false/disabled)
        def wasIndexing = ImportUtils.indexIssues;
        ImportUtils.indexIssues = true;
 
        // if issue type is a release type, process it
        if (issue.issueTypeObject.name == "Release") {
            
               // Get some values before proceeding
               def               vFixVersion   = issue.getFixVersions()
               CustomField       FixVersion    = cfm.getCustomFieldObjectByName("IP Version") 
               //def               vFixVersion   = issue.getCustomFieldValue(FixVersion)
               CustomField       ReleaseTrain  = cfm.getCustomFieldObjectByName("ReleaseTrain")
               def               vReleaseTrain = ReleaseTrain.getValue(issue)
               //def               vReleaseTrain = issue.getCustomFieldValue(ReleaseTrain)
               def jqlQueryParser = cm.getComponentInstanceOfType(JqlQueryParser.class) as JqlQueryParser
               def fieldLayoutItem = lm.getFieldLayout(issue).getFieldLayoutItem(ReleaseTrain);
               
               // Search for tickets that have the ReleaseTrain matching
               JqlQueryBuilder builder = JqlQueryBuilder.newBuilder()
               builder.where().customField(ReleaseTrain.getIdAsLong()).like(vReleaseTrain.toString())
               Query query = builder.buildQuery()
               SearchService searchService = cm.getInstance().getSearchService();
               def results = searchService.search(cm.getJiraAuthenticationContext()?.getUser(), query, PagerFilter.getUnlimitedFilter())
                  
               // loop through the tickets and clear the ReleaseTrain fields
               def issueCount = 0;
               for (Issue an_issue in results.getIssues()) {
                   //def  SearchReleaseTrain = an_issue.getCustomFieldValue(ReleaseTrain)
                   def  SearchReleaseTrain = ReleaseTrain.getValue(an_issue)
                   
                   log.debug "clearing ReleaseTrain on "+an_issue.getKey()
                   ModifiedValue nwValue = new ModifiedValue(SearchReleaseTrain, null)
                   def nwFieldLayoutItem = lm.getFieldLayout(an_issue).getFieldLayoutItem(ReleaseTrain);
                   ReleaseTrain.updateValue(nwFieldLayoutItem, an_issue, nwValue, new DefaultIssueChangeHolder())
                   ReleaseTrain.store()

                   issueCount++
               }
               log.debug("Searched through $issueCount tickets")

               // Now that the old values are gone, re-set the ReleaseTrain fields
               // Get all the children of the Release issue and loop through them
               for (Issue sub_issue in issue.getSubTaskObjects()) {
                   
                   // get some info
                   //def  SubReleaseTrain = sub_issue.getCustomFieldValue(ReleaseTrain)
                   //def  SubIPVersion    = sub_issue.getCustomFieldValue(FixVersion)
                   def  SubReleaseTrain = ReleaseTrain.getValue(sub_issue)
                   def  SubIPVersion    = FixVersion.getValue(sub_issue)
                
                   // Set the Release Train on the subtask item
                   log.debug "setting ReleaseTrain on subtasks "+sub_issue.getKey()+" IP Version is "+SubIPVersion.toString()
                   ModifiedValue subValue = new ModifiedValue(SubReleaseTrain, vReleaseTrain)
                   def nwFieldLayoutItem = lm.getFieldLayout(sub_issue).getFieldLayoutItem(ReleaseTrain);
                   ReleaseTrain.updateValue(nwFieldLayoutItem, sub_issue, subValue, new DefaultIssueChangeHolder())
                   ReleaseTrain.store()
                   
                   // Find all the tickets with the same IP version field as the sub_issue and set their ReleaseTrain
                   JqlQueryBuilder sub_builder = JqlQueryBuilder.newBuilder()
                   //sub_builder.where().issueType().notEq("Release").and().issueType().notEq("Release IP").and().customField(FixVersion.getIdAsLong()).like(SubIPVersion.toString())
                   sub_builder.where().fixVersion(SubIPVersion)
                   Query sub_query = sub_builder.buildQuery()
                   SearchService ipsearchService = cm.getInstance().getSearchService();
                   def ticket_results = ipsearchService.search(cm.getJiraAuthenticationContext()?.getUser(), sub_query, PagerFilter.getUnlimitedFilter())
                   
                   // For each ticket found, update the ReleaseTrain value
                   for (Issue ip_issue in ticket_results.getIssues()) {
                       def  IPReleaseTrain = ip_issue.getCustomFieldValue(ReleaseTrain)
                       //def  IPReleaseTrain = ReleaseTrain.getValue(sub_issue)
                       log.debug "setting ReleaseTrain on tickets with matching IP version "+ip_issue.getKey()
                       
                       //Set your custom field and store it
                       ip_issue.setCustomFieldValue(ReleaseTrain, "Larry");
                       ip_issue.store();
                       // OR use modifiedValue to set customfield
                       //ModifiedValue ipsubValue = new ModifiedValue(IPReleaseTrain, vReleaseTrain)
                       //def ipFieldLayoutItem = lm.getFieldLayout(ip_issue).getFieldLayoutItem(ReleaseTrain);
                       //ReleaseTrain.updateValue(ipFieldLayoutItem, ip_issue, ipsubValue, new DefaultIssueChangeHolder())
                       //ReleaseTrain.store()
                   }
               }
               
                  
        } else {
            log.debug "[UpdateReleaseListener]: Only Release tickets get to update ReleaseTrains."
        }
        //Reset the indexer to what it was before.
        ImportUtils.indexIssues = wasIndexing;
    }
}

2 answers

1 accepted

1 vote
Answer accepted
Scott Evans October 4, 2012

I figured it out. Jamies hint got me going down the re-index path. I added the following:

def               im           = cm.getIndexManager()

...

                   for (Issue ip_issue in ticket_results.getIssues()) {
                       def  IPReleaseTrain = ip_issue.getCustomFieldValue(ReleaseTrain)
                       //def  IPReleaseTrain = ReleaseTrain.getValue(sub_issue)
                       log.debug "setting ReleaseTrain on tickets with matching IP version "+ip_issue.getKey()
                       
                       //Set your custom field and store it
                       ModifiedValue ipsubValue = new ModifiedValue(IPReleaseTrain, vReleaseTrain)
                       def ipFieldLayoutItem = lm.getFieldLayout(ip_issue).getFieldLayoutItem(ReleaseTrain);
                       ReleaseTrain.updateValue(ipFieldLayoutItem, ip_issue, ipsubValue, new DefaultIssueChangeHolder())
                       ReleaseTrain.store()
                       im.reIndex(ip_issue) //<<<-----NEW line added
                   }

Adding the .reIndex(issue) fixed my problem

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.
October 3, 2012

Could you simplify your question a bit? It's too hard to take on board the text of it alongside the code.

Is the issue:

> However, if I filter on releaseTrain, those issues don't show up in the results

ie you're searching programatically, and don't find issues that you should do for that custom field? If so, is this the same in the UI?

Does the problem go away after you reindex? Which would suggest that your issues are not getting reindex.

Scott Evans October 3, 2012

Sorry if this was confusing - I noticed I even loaded the wrong code. Let me try to clarify and limit your attention.

There is a final for loop that sets the releaseTrain field to a value from another issue.

// For each ticket found, update the ReleaseTrain value
                   for (Issue ip_issue in ticket_results.getIssues()) {
                       def  IPReleaseTrain = ip_issue.getCustomFieldValue(ReleaseTrain)
                       //def  IPReleaseTrain = ReleaseTrain.getValue(sub_issue)
                       log.debug "setting ReleaseTrain on tickets with matching IP version "+ip_issue.getKey()
                       
                       //Set your custom field and store it
                       //ip_issue.setCustomFieldValue(ReleaseTrain, vReleaseTrain);
                       //ip_issue.store();
                       // OR use modifiedValue to set customfield
                       ModifiedValue ipsubValue = new ModifiedValue(IPReleaseTrain, vReleaseTrain)
                       def ipFieldLayoutItem = lm.getFieldLayout(ip_issue).getFieldLayoutItem(ReleaseTrain);
                       ReleaseTrain.updateValue(ipFieldLayoutItem, ip_issue, ipsubValue, new DefaultIssueChangeHolder())
                       ReleaseTrain.store()
                   }

There are 2 ways that I was trying to code, both set the value in the issue. Through the GUI, I can see that the value is set correctly.

In the GUI, I search for issues where "releaseTrain is not EMPTY" and those issues I just looked at don't show up in the results. Why?

I do not do a re-index, since I'm not adding any new fields, just setting the existing fields.

George

Scott Evans October 3, 2012

Jamie,

I did a re-index and the GUI filter worked as expected. I must have missed it when I added the field. Or do I have to re-index after setting the values?

Thanks for the suggestion.

George

Suggest an answer

Log in or Sign up to answer