Come for the products,
stay for the community

The Atlassian Community can help you and your team get more value out of Atlassian products and practices.

Atlassian Community about banner
4,365,484
Community Members
 
Community Events
168
Community Groups

New Adaptivist ScriptRunner searchProvider method for Jira 8?

Edited

I am trying to refactor a Scriptrunner listener to work with the new Jira 8 updates. The listener should copy a custom field value from parent to all children on update. It was previously working w/ Jira 7.

Specifically, having trouble implementing searchProvider.search() method. Code block below...I have loads of new type check errors and don't know where to begin!!

jira8-priorityNumber.PNG

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.Issue
import com.atlassian.jira.issue.MutableIssue
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.issuetype.IssueType
import com.atlassian.jira.issue.util.DefaultIssueChangeHolder
import com.atlassian.jira.issue.IssueInputParameters
import com.atlassian.jira.issue.ModifiedValue
import com.atlassian.jira.bc.issue.*
import static com.atlassian.jira.workflow.TransitionOptions.Builder;
import com.atlassian.jira.issue.IssueManager;
import com.atlassian.jira.issue.link.IssueLinkManager
import com.atlassian.jira.issue.link.IssueLink
import org.apache.log4j.Logger
import org.apache.log4j.Level
import com.atlassian.jira.issue.search.SearchProvider
import com.atlassian.jira.jql.parser.JqlQueryParser
import com.atlassian.jira.web.bean.PagerFilter
import com.atlassian.jira.issue.index.IssueIndexingService;
import com.atlassian.jira.issue.search.IssueSearchResultsFactory;
import com.atlassian.jira.issue.search.DocumentSearchResultsFactory;

def log = Logger.getLogger("com.acme.debug")
log.setLevel(Level.DEBUG)
Issue issue = event.issue

def key = issue.getKey()
def customFieldManager = ComponentAccessor.getCustomFieldManager()
def issueManager = ComponentAccessor.getIssueManager();
def field = customFieldManager.getCustomFieldObjects(event.issue).find { it.name == "Priority Number" }
def issueService = ComponentAccessor.getIssueService()
def user = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()

def jqlQueryParser = ComponentAccessor.getComponent(JqlQueryParser)
def searchProvider = ComponentAccessor.getComponent(SearchProvider)
def parentLink = customFieldManager.getCustomFieldObjectsByName('Parent Link') // getting the Parent Link custom field
def customFieldValue = issue.getCustomFieldValue(parentLink) // Parent Link field value
def parentKey = (String) customFieldValue
def parentIssue = issueManager.getIssueObject(parentKey) // Parent issue object
def parentValue = issue.getCustomFieldValue(field)

def jqlSearch = "issuetype in (Feature,'Forecasting Placeholder',Epic,Story)and status not in (Done,'Feature Post-Implementation','Feature Released') and issuekey in childIssuesOf(" + key + ")";
def query = jqlQueryParser.parseQuery(jqlSearch)

def results = searchProvider.search(query, user, PagerFilter.getUnlimitedFilter())

results.getResults().each {documentIssue ->;

def childIssue = issueManager.getIssueObject(documentIssue.id)
def changeHolder = new DefaultIssueChangeHolder()
def childValue = childIssue.getCustomFieldValue(field)
def issueIndexManager = ComponentAccessor.getComponent(IssueIndexingService)
field.updateValue(null, documentIssue, new ModifiedValue(childValue, parentValue), changeHolder)

issueIndexManager.reIndex(documentIssue)
}

 I have found my way here https://confluence.atlassian.com/jiracore/lucene-upgrade-975041047.html but I am so far, unable to translate these updates...

Any advice is appreciated! 

 

Logs: 

2019-09-24 12:36:25,462 ERROR [runner.AbstractScriptListener]: *************************************************************************************
2019-09-24 12:36:25,462 ERROR [runner.AbstractScriptListener]: Script function failed on event: com.atlassian.jira.event.issue.IssueEvent, file: <inline script>
groovy.lang.MissingMethodException: No signature of method: com.atlassian.jira.issue.search.providers.LuceneSearchProvider.search() is applicable for argument types: (com.atlassian.query.QueryImpl, com.atlassian.jira.user.DelegatingApplicationUser, com.atlassian.jira.web.bean.PagerFilter) values: [{issuetype in ("Feature", "Forecasting Placeholder", "Epic", "Story")} AND {status not in ("Done", "Feature Post-Implementation", "Feature Released")} AND {issuekey in childIssuesOf(ZSMBT-10)}, ...]
Possible solutions: search(com.atlassian.jira.issue.search.SearchQuery, com.atlassian.jira.web.bean.PagerFilter), search(com.atlassian.jira.issue.search.SearchQuery, com.atlassian.jira.web.bean.PagerFilter, java.util.Set), search(com.atlassian.jira.issue.search.SearchQuery, org.apache.lucene.search.Collector), each(groovy.lang.Closure)
	at Script402.run(Script402.groovy:49)

 

1 answer

1 accepted

13 votes
Answer accepted

I've found 2 ways.

1) change to use com.atlassian.jira.bc.issue.search.SearchService instead of SearchProvider

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.bc.issue.search.SearchService
import com.atlassian.jira.jql.parser.JqlQueryParser
import com.atlassian.jira.web.bean.PagerFilter
import com.atlassian.jira.issue.search.SearchQuery
def user = ComponentAccessor.jiraAuthenticationContext.loggedInUser
def jqlQueryParser = ComponentAccessor.getComponent(JqlQueryParser)
def searchService = ComponentAccessor.getComponent(SearchService)
def jqlSearch = "project=JSP and assignee=p6s and resolution is empty"
def query = jqlQueryParser.parseQuery(jqlSearch)
//note different order of parameters compared to searchprovider
def results = searchService .search(user,query, PagerFilter.getUnlimitedFilter())
results.getResults()

2) Continue to use the searchProvider but wrap some parameters in a SearchQuery (and get issue_id from the lucene document)

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.search.SearchProvider
import com.atlassian.jira.jql.parser.JqlQueryParser
import com.atlassian.jira.web.bean.PagerFilter
import com.atlassian.jira.issue.search.SearchQuery
def user = ComponentAccessor.jiraAuthenticationContext.loggedInUser
def jqlQueryParser = ComponentAccessor.getComponent(JqlQueryParser)
def searchProvider = ComponentAccessor.getComponent(SearchProvider)
def jqlSearch = "project=JSP and assignee=p6s and resolution is empty"
def query = jqlQueryParser.parseQuery(jqlSearch)
def searchQuery = SearchQuery.create(query, user)
def results = searchProvider.search(searchQuery, PagerFilter.getUnlimitedFilter())
results.getResults()*.document.collect{ComponentAccessor.issueManager.getIssueObject(it.getField('issue_id').stringValue())}

@Peter-Dave Sheehan The first method you provided worked perfectly thank you! 

Curiosity...Any idea why I'm still getting a static type-check error on line 45? Everything is working but it is showing that error: Cannot find matching method getCustomFieldValue:

def customFieldValue = issue.getCustomFieldValue(parentLink) // Parent Link field value
Like Joe Pursel likes this

I see you've updated from the deprecated getCustomFieldObjectByName (singular) to use the new "getCustomFieldObjectsByName" (plural). This new method returns a list, not a single custom field. So maybe try:

def parentLink = customFieldManager.getCustomFieldObjectsByName('Parent Link')[0]
def customFieldValue = issue.getCustomFieldValue(parentLink)

 To get the first (and presumably only) field in the list.

Or change to getCustomFieldObject(id) using the internal id (long) of the Parent Link field

Like # people like this

I'm not sure if anybody could use the 2) method described here. But I found out that the last row:

def results = searchProvider.search(searchQuery, PagerFilter.getUnlimitedFilter())
results.getResults()*.document.collect{ComponentAccessor.issueManager.getIssueObject(it.getField('issue_id').stringValue())}

does not work for me, and I had to change the id from String to Long to make it run

def results = searchProvider.search(searchQuery, PagerFilter.getUnlimitedFilter())
results.getResults()*.document.collect{ComponentAccessor.issueManager.getIssueObject(it.getField('issue_id').stringValue().toLong())}

 Is that the correct way, or we could have better function to retrieve Issue from these docId results?

Like Joe Pursel likes this

I think I was working on 8.3 at the time of my answer.

I saw that with 8.5.1, you are correct, toLong() is required.

I also found this works:

results.getResults()*.document.collect{
ComponentAccessor.issueManager.getIssueObject(it.getValues('issue_id').first() as Long)
}

I can't think of why one would be better than the other. Either way, we now have to use native Lucene method to extract values from the document.

Like Joe Pursel likes this

:+1: for solution 1) this fixes our issue after migration from Jira 7.13 to Jira 8.5.

Solution 1 Fixed the problem. But the "result" line should be like below

def results = searchService .search(user,query, PagerFilter.getUnlimitedFilter()).getResults()
def results = searchService .search(user,query, PagerFilter.getUnlimitedFilter())
results = results.getResults()

Item #2 above prints the issues with their key.

Thanks to all above!

Thank you soooo much!!! #1 Solved my Issue I was working on for ages!!! :D Super happy :D

Suggest an answer

Log in or Sign up to answer
TAGS

Atlassian Community Events