Custom field shows up EMPTY with a value in it

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

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 vote

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.

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

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
Atlassian Community Anniversary

Happy Anniversary, Atlassian Community!

This community is celebrating its one-year anniversary and Atlassian co-founder Mike Cannon-Brookes has all the feels.

Read more
Community showcase
Julia Dillon
Posted Apr 17, 2018 in Jira

Tell us how your team runs on Jira!

Hey Atlassian Community! Today we are launching a bunch of customer stories about the amazing work teams, like Dropbox and Twilio, are doing with Jira. You can check out the stories here. The thi...

767 views 2 19
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