Create
cancel
Showing results for 
Search instead for 
Did you mean: 
Sign up Log in

Built in scripts from 'Generate Events' wont trigger Insight Read Only field to update

Steve Letch August 14, 2020

Hi all

 

I'm implementing an Insight Read only field into my screens. Insight read only fields are triggered to fill on Issue Created and Issue Updated. the field fills fine when you use native Jira functions such as create an issue, inline edit a field or bulk change something else about issues.

 

I wanted to get the field populated for our old issues, however the built in script to 'Generate Events', Issue Updated and Issue Created don't trigger the field to fill. I've even tried a script in the script console to bulk update a dummy field attached to issues to see if that would trigger it but sadly not.

 

The only thing this Insight field seems to respond to is native Jira functionality, at least with the methods I've tried.

 

Does an additional class need to be added to a custom event or something

 

Thanks

1 answer

1 accepted

Suggest an answer

Log in or Sign up to answer
0 votes
Answer accepted
Peter-Dave Sheehan
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
August 14, 2020

I haven't tried that... but I think you could run a script that runs a JQL to return an issue where the RO Insight field is missing, then just use issue.setCustomFieldValue(objectKey)

I suspect that's what insight does when it detects the issue updated, issue created, and possibly also the issue assigned events.

If you've never done groovy scripting for jira (like with scriptrunner) it would look something like this:

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.jql.parser.JqlQueryParser
import com.atlassian.jira.issue.search.SearchProvider
import com.atlassian.jira.web.bean.PagerFilter
import com.atlassian.jira.issue.search.SearchQuery
import com.atlassian.jira.util.ImportUtils
import com.atlassian.jira.event.type.EventDispatchOption
import com.atlassian.jira.issue.index.IssueIndexingService

def issueManager = ComponentAccessor.issueManager
def jqlQueryParser = ComponentAccessor.getComponent(JqlQueryParser)
def searchProvider = ComponentAccessor.getComponent(SearchProvider)
def currentUser = ComponentAccessor.jiraAuthenticationContext.loggedInUser

def someObjectkeyToSet = 'ABC-123'
def jql =""" Project = PJCT and "Insight ReaOnly Field" is empty """

def query = jqlQueryParser.parseQuery(jql.toString())
def searchQuery = SearchQuery.create(query,currentUser)
def results = searchProvider.search(searchQuery, PagerFilter.newPageAlignedFilter(0,1))

results.results.document.each{
    def issue = issueManager.getIssueObject(it.getValues('issue_id').first() as Long)
    def customField = ComponentAccessor.customFieldManager.getCustomFieldObjectsByName("nsight ReaOnly Field")[0]
    //apply the value
    issue.setCustomFieldValue(customField, someObjectkeyToSet)

    //Store the issue
    issueManager.updateIssue(currentUser, issue, EventDispatchOption.DO_NOT_DISPATCH, false)

    //update the JIRA index
    boolean wasIndexing = ImportUtils.isIndexIssues()
    ImportUtils.setIndexIssues(true)
    ComponentAccessor.getComponent(IssueIndexingService.class).reIndex(issue)
    ImportUtils.setIndexIssues(wasIndexing)
}
Steve Letch August 16, 2020

Will give it a go tomorrow and let you know, thanks

Steve Letch August 18, 2020

Hi @Peter-Dave Sheehan 

 

The part of the script where it tries to select a specific key, I need it to just do it's normal job whereby the content of the field is filled depending on the reporter.

 

My insight field is configured as follows: 

Filter Scope (IQL)

objectType = Users

Filter Assign Scope (IQL)

User = currentReporter()

Peter-Dave Sheehan
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
August 18, 2020

You can use the IQLFacade to find the object

def iqlFacade = ComponentAccessor.getOSGiComponentInstanceOfType(IQLFacade)
def iqlResults = iqlFacade.findObject("objectType = Users and User = $issue.reporter.name"
def objectKeyToSet
if(iqlResults){
objectKeyToSet = iqlResults.first().objectKey
}
Steve Letch August 19, 2020

Wherever I paste that in I just get unexpected token on

def objectKeyToSet
Steve Letch August 21, 2020

@Peter-Dave Sheehan 

Any chance you could repaste the full script with the addition from above in the right place?

Also I notice that script looks like it's trying to set some field content, tbh given it's a read only field allll I need something to do is en mass trigger the riada event listeners to see an issue updated event in the issue, then the field will do the rest.

 

Thanks

Peter-Dave Sheehan
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
August 21, 2020

Haven't actually tested, but this should do the trick

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.jql.parser.JqlQueryParser
import com.atlassian.jira.issue.search.SearchProvider
import com.atlassian.jira.web.bean.PagerFilter
import com.atlassian.jira.issue.search.SearchQuery
import com.atlassian.jira.util.ImportUtils
import com.atlassian.jira.event.type.EventDispatchOption
import com.atlassian.jira.issue.index.IssueIndexingService
import com.riadalabs.jira.plugins.insight.channel.external.api.facade.IQLFacade
import com.onresolve.scriptrunner.runner.customisers.WithPlugin
@WithPlugin('com.riadalabs.jira.plugins.insight')

def iqlFacade = ComponentAccessor.getOSGiComponentInstanceOfType(IQLFacade)
def issueManager = ComponentAccessor.issueManager
def jqlQueryParser = ComponentAccessor.getComponent(JqlQueryParser)
def searchProvider = ComponentAccessor.getComponent(SearchProvider)
def currentUser = ComponentAccessor.jiraAuthenticationContext.loggedInUser

/* update this section */
def insightRoField = 'name of your insight read only custom field'
def jql =""" Project = PJCT and "$insightRoField" is empty """
def insightRoFieldBasedOn = 'reporter' //you can also use assignee
def objectTypeForRoField = 'Users'
def attributeForJiraUser = 'User'
/* end section to update*/

def query = jqlQueryParser.parseQuery(jql.toString())
def searchQuery = SearchQuery.create(query,currentUser)
def results = searchProvider.search(searchQuery, PagerFilter.newPageAlignedFilter(0,1))

results.results.document.each{
def issue = issueManager.getIssueObject(it.getValues('issue_id').first() as Long)
def iqlResults = iqlFacade.findObjects("""objectType = "$objectTypeForRoField" and "$attributeForJiraUser" = "${issue[insightRoFieldBasedOn].name}" """)
def objectKeyToSet
if(iqlResults){
objectKeyToSet = iqlResults.first().objectKey
def customField = ComponentAccessor.customFieldManager.getCustomFieldObjectsByName(insightRoField)[0]
//apply the value
issue.setCustomFieldValue(customField, objectKeyToSet)

//Store the issue
issueManager.updateIssue(currentUser, issue, EventDispatchOption.DO_NOT_DISPATCH, false)

//update the JIRA index
boolean wasIndexing = ImportUtils.isIndexIssues()
ImportUtils.setIndexIssues(true)
ComponentAccessor.getComponent(IssueIndexingService.class).reIndex(issue)
ImportUtils.setIndexIssues(wasIndexing)
log.info "$insightRoField' updated for $issue.key"
} else {
log.warn "Can't set '$insightRoField' field for ${issue.key}. Could not find a valid $objectTypeForRoField object with $attributeForJiraUser = ${issue[insightRoFieldBasedOn].name}"
}
}
Steve Letch August 24, 2020

@Peter-Dave Sheehan 

 

Sad noises:

 

2020-08-24 09:45:17,783 ERROR [common.UserScriptEndpoint]: Script console script failed: java.lang.ClassCastException: java.lang.String cannot be cast to java.util.Collection at com.riadalabs.jira.plugins.insight.services.jira.customfield.deprecated.AbstractCustomField.createValue(AbstractCustomField.java:62) at com.atlassian.jira.issue.fields.ImmutableCustomField.createValue(ImmutableCustomField.java:693) at com.atlassian.jira.issue.fields.ImmutableCustomField.updateValue(ImmutableCustomField.java:410) at com.atlassian.jira.issue.fields.ImmutableCustomField.updateValue(ImmutableCustomField.java:396) at com.atlassian.jira.issue.managers.DefaultIssueManager.updateFieldValues(DefaultIssueManager.java:728) at com.atlassian.jira.issue.managers.DefaultIssueManager.updateIssue(DefaultIssueManager.java:681) at com.atlassian.jira.issue.managers.DefaultIssueManager.updateIssue(DefaultIssueManager.java:667) at com.atlassian.jira.issue.managers.RequestCachingIssueManager.updateIssue(RequestCachingIssueManager.java:217) at com.atlassian.jira.issue.IssueManager$updateIssue$0.call(Unknown Source) at Script1747$_run_closure1.doCall(Script1747.groovy:42) at Script1747.run(Script1747.groovy:31)

 

Peter-Dave Sheehan
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
August 24, 2020

My mistake, I always forget that insight custom field expect an array.

Change 

issue.setCustomFieldValue(customField, objectKeyToSet)

to

issue.setCustomFieldValue(customField, [objectKeyToSet])
Steve Letch August 25, 2020

whirred away for a while then

 

'Failed to post update'

doesn't seem to have made a change to the issues either

tried it on a smaller set of issues and same thing

Steve Letch August 25, 2020

Yikes, seems to be making my Insight go brrrrr. Schema was unresponsive and got this in the manage apps section :|

 

Insight batch process(es) are running. Be aware that upgradingdisabling or uninstalling Insight may cause data inconsistency please wait until the process(es) are completed before performing any of these changes to Insight.Resource: freetext-reindex (freetext), Description: Re-index, Percent: 0%Resource: imports (10), Description: Placeholder, Percent: 0%Resource: imports (2), Description: Reading external data for object type(s), Percent: 0%Resource: imports (1), Description: Reading external data for object type(s), Percent: 0%Resource: generate-data (widget-2), Description: Distribution of Users by Office, Percent: 0%Resource: generate-data (widget-3), Description: Percentage of distribution groups owned by a user, Percent: 0%Resource: generate-data (widget-4), Description: Object count over time for Users and D Lists, Percent: 0%

 

EDIT: nvm seems to have calmed down now :)

Peter-Dave Sheehan
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
August 27, 2020

I'll go back to my very first words during this interaction "I haven't tried that but...".

This was all based on some educated guesses and assumptions.

I use Adaptavist Scriptrunner on my Jira instance every day. My experience with Insight is much more recent, and most scripting I do (even for insight) is executed from Scriptrunner console rather than insight console. The scriptrunner script editor and general groovy implementation are much richer. That's its bread n butter.

But the "failed to post" probably just means that the browser didn't get a response in an acceptable time. The script was likely still running in the background.
Then if you started it a second time on a smaller set ... that might have caused some clashes.

One way to avoid this is to experiment/develop on a single issue in the console ... then, when happy, save the full script to your file system and add an automation configuration to one of your schemas. Doesn't matter which you pick. You will just tell it to execute on a single object (scheduled event) by specifying IQL condition: Key={arbirary valid object key}.
It doesn't matter what key you use since you won't be calling the "object" variable in your script. You can use 0 0 1 * * ? 2099 as a cron expression so it never runs... except when you manually select the run now option. This way, the execution trigger is on the server rather than from your browser and won't be subject to timeout. Further, you can view the progress by outputting some log statements in the script then tailing the insight_automation.log file.

When it's all said and done, a full re-index of insight might not be a bad idea

Steve Letch August 28, 2020

coolsies, well, thanks for your help

Steve Letch August 28, 2020

tried it on a single key:

 

java.lang.ClassCastException: java.lang.String cannot be cast to com.riadalabs.jira.plugins.insight.services.model.ObjectBean at com.riadalabs.jira.plugins.insight.services.core.dal.impl.DeprecatedCustomFieldDalImpl.getObjectBeansToStore(DeprecatedCustomFieldDalImpl.java:595) at com.riadalabs.jira.plugins.insight.services.core.dal.impl.DeprecatedCustomFieldDalImpl.getObjectBeansToStore(DeprecatedCustomFieldDalImpl.java:85) at com.riadalabs.jira.plugins.insight.services.core.impl.DeprecatedCustomFieldServiceImpl.getObjectBeansToStore(DeprecatedCustomFieldServiceImpl.java:427) at com.riadalabs.jira.plugins.insight.services.jira.customfield.deprecated.AbstractCustomField.createValue(AbstractCustomField.java:292) at com.riadalabs.jira.plugins.insight.services.jira.customfield.deprecated.AbstractCustomField.createValue(AbstractCustomField.java:62) at com.atlassian.jira.issue.fields.ImmutableCustomField.createValue(ImmutableCustomField.java:693) at com.atlassian.jira.issue.fields.ImmutableCustomField.updateValue(ImmutableCustomField.java:410) at com.atlassian.jira.issue.fields.ImmutableCustomField.updateValue(ImmutableCustomField.java:396) at com.atlassian.jira.issue.managers.DefaultIssueManager.updateFieldValues(DefaultIssueManager.java:728) at com.atlassian.jira.issue.managers.DefaultIssueManager.updateIssue(DefaultIssueManager.java:681) at com.atlassian.jira.issue.managers.DefaultIssueManager.updateIssue(DefaultIssueManager.java:667) at com.atlassian.jira.issue.managers.RequestCachingIssueManager.updateIssue(RequestCachingIssueManager.java:217) at com.atlassian.jira.issue.IssueManager$updateIssue$1.call(Unknown Source) at Script1855$_run_closure1.doCall(Script1855.groovy:42) at Script1855.run(Script1855.groovy:31)

 

Seeing this in a couple places

Screenshot (56).png

Peter-Dave Sheehan
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
August 28, 2020

The static type checking is normal.

It's telling us that it cant' determined what will be returned from issue[insightRoFieldBasedOn] ... so it doesn't know where .name is valid for that returned value. If you don't want this error, you can explicitly put issue.reporter.name or issue.assignee.name

 

As for the actual error, I went aheat and actually tried that. Assigned an issue to a user without an insight object, created the matching insight object, then tried to run the script to get the Assignee Information Insight read-only field to display the details.

I got the same error as you did.

The first line is what clued me in as to what was wrong: "cannot cast string to ObjectBean".

This means that this custom field is expecting an actual insight object and not the string object key (like non read-only fields actually do).

So I changed this section:

def objectToSet =iqlResults.first()
def customField = ComponentAccessor.customFieldManager.getCustomFieldObjectsByName(insightRoField)[0]
//apply the value
issue.setCustomFieldValue(customField, [objectToSet])
TAGS
AUG Leaders

Atlassian Community Events