Set asset custom field value with searching assets

This page is about Assets & Inventory Plugin for Jira DC. Using Cloud? Click here.

In this example, we will define a post function to set the asset custom field's value. The function searches for assets based on type and a user attribute, then assigns the first matching asset to the custom field if it's initially empty.

Example

In this example, we have Computer asset type and a Jira User attribute that has unique values. When we create a Jira Service Management issue and leave the asset custom field value empty, we'll find Computer 01 and set it to the custom field.

Configuration

  1. Add the post function to the Create Issue Transition.

  2. Select [AIP] - Asset generic Groovy script.

Parameters of post function

  • Asset custom fields (with values) to inject as script parameter – Select the custom field to set. In this example, Assets - 10227 is picked.

  • Groovy script – Add the Groovy script and modify the parameters.

    • assetTypeName: Asset type name to search.

    • def fieldName: Attribute name to search.

    • fieldValue: Attribute value to search.

    • AUTH_HASH: Auth hash for authorization. The sample is for user=admin, and password=admin.

    • assetCustomFieldId: ID of the asset custom field. To find it quickly, right click on the Issue Edit screen where the asset custom field appears, and find its ID. For example, = customfield_10227.

Post function Groovy script

import com.atlassian.jira.component.ComponentAccessor import com.atlassian.jira.issue.CustomFieldManager import com.atlassian.jira.issue.ModifiedValue import com.atlassian.jira.issue.util.DefaultIssueChangeHolder import Groovy.json.JsonSlurper import inventoryplugin.workflow.function.genericscript.dto.AssetCustomField import inventoryplugin.workflow.function.genericscript.dto.AssetCustomFieldAndValue import org.apache.http.client.methods.CloseableHttpResponse import org.apache.http.client.methods.HttpPost import org.apache.http.entity.StringEntity import org.apache.http.impl.client.CloseableHttpClient import org.apache.http.impl.client.HttpClients import org.apache.http.util.EntityUtils import org.apache.log4j.Logger import org.apache.log4j.Level /*********************************************************************************************************/ /* IMPORTANT: /* Configure these settings according to your environment /* AUTH_HASH value must be changed according to the user who has Browse Assets for all types */ /*********************************************************************************************************/ def assetTypeName = 'Computer'; // asset type name to search def fieldName = 'JIRA User'; // attribute name to search def fieldValue = issue.reporter.username; // attribute value to search def AUTH_HASH = 'Basic YWRtaW46YWRtaW4='; // auth hash for authorization. this sample is for user=admin, and password=admin def assetCustomFieldId = "customfield_10227"; // id of the asset custom field. To find it quickly, right click on issue edit screen where asset custom field appears and find the id of it. /*********************************************************************************************************/ Logger logger = Logger.getLogger("inventoryplugin.Groovy.script") /** * searches for assets that matches fieldName=fieldValues for the given assetTypeName and returns matching asset ids as formatted for asset custom field (i.e: ,12,343,545,) */ def getAssetFieldValue(authHash, assetTypeName, fieldName, fieldValue) { Logger logger = Logger.getLogger("inventoryplugin.Groovy.script") try { if (fieldValue) { // get asset ID(s) def baseurl = ComponentAccessor.getApplicationProperties().getString("jira.baseurl") // this is the search query parameters. When you search assets on Asset Navigator, // same parameters appear on Developer tools-> Network Tab. You can make different searches and get the parameters from there when you need. def queryToPostJson = " {\"searchType\" : \"basic\" ,\n" + " \"listType\" : \"detail\" ,\n" + " \"queryIndexSearchParams\" : [\n" + " {\n" + " \"field\" : \"" + fieldName + "\" ,\n" + " \"keyword\" : \"" + fieldValue + "\" ,\n" + " \"keywords\" : [] ,\n" + " \"fieldType\" : \"STRING\" ,\n" + " \"range\" : false\n" + " },\n" + " {\n" + " \"field\" : \"form.name\" ,\n" + " \"keyword\" : null ,\n" + " \"keywords\" : [\"" + assetTypeName + "\"] ,\n" + " \"fieldType\" : \"LIST\" ,\n" + " \"range\" : false\n" + " }\n" + " ] ,\n" + " \"pageNumber\" : 1 ,\n" + " \"pageSize\" : 10000 ,\n" + " \"sortDirection\" : \"asc\" ,\n" + " \"sortField\" : \"asset.id\"\n" + "} " CloseableHttpClient httpclient = HttpClients.createDefault(); def httpPost = new HttpPost(baseurl + "/rest/jip-api/1.0/index/query"); httpPost.setHeader("Accept", "application/json"); httpPost.setHeader("Content-type", "application/json"); httpPost.setHeader("Authorization", authHash); def entity = new StringEntity(queryToPostJson); httpPost.setEntity(entity); CloseableHttpResponse response = httpclient.execute(httpPost); try { if (response.getStatusLine().getStatusCode() == 200) { BufferedReader br = new BufferedReader(new InputStreamReader(response.getEntity().getContent())); StringBuilder sb = new StringBuilder(); String line; while ((line = br.readLine()) != null) { sb.append(line + "\n"); } br.close(); EntityUtils.consume(response.getEntity()) def jsonSlurper = new JsonSlurper() def json = jsonSlurper.parseText(sb.toString()) def assetIdsArry = json.recordIds; def assetIdsSb = new StringBuffer() if (assetIdsArry != null && assetIdsArry.size() > 0) { assetIdsArry.each { assetIdsSb.append(',').append(it) } assetIdsSb.append(',') } return assetIdsSb.toString() } else { return null; } } finally { httpclient.close(); } } } catch (Exception e) { logger.error("Error while searching assets.", e); return null; } } /** * updates asset custom field of the given issue */ def updateAssetCustomFieldOfTheIssue(customfieldId, issueKey, assetCustomFieldValue) { // get issue def issueToUpdate = ComponentAccessor.getIssueManager().getIssueObject(issueKey); // get asset custom field CustomFieldManager customFieldManager = ComponentAccessor.getCustomFieldManager() def assetCf = customFieldManager.getCustomFieldObject(customfieldId) // asset cf id // execute update assetCf.updateValue(null, issueToUpdate, new ModifiedValue(issueToUpdate.getCustomFieldValue(assetCf), assetCustomFieldValue), new DefaultIssueChangeHolder()) } /** * Checks if Asset custom field value is empty */ boolean isCustomFieldEmpty(assetCustomFieldId) { for (AssetCustomFieldAndValue assetCustomFieldAndValue : assetCustomFieldAndValueList) { AssetCustomField assetCustomField = assetCustomFieldAndValue.getAssetCustomField(); if (assetCustomField.customFieldId == assetCustomFieldId) { if (assetCustomFieldAndValue.getAssetList() != null && assetCustomFieldAndValue.getAssetList().size() > 0) { return false; } } } return true; } try { if (isCustomFieldEmpty(assetCustomFieldId)) { def assetCfValue = getAssetFieldValue(AUTH_HASH, assetTypeName, fieldName, fieldValue) if (assetCfValue != null) { updateAssetCustomFieldOfTheIssue(assetCustomFieldId, issue.getKey(), assetCfValue) } return assetCfValue } } catch (Exception e) { logger.error("Error while setting asset custom field value.", e); } return null;
  1. Save the post function and move it after Creates the issue originally.

  2. Publish the post function and perform these tests:

Test 1: Asset field is empty

Create issue

View issue

Create issue

View issue

User is tyler and Computer field is blank.

Computer value is automatically set to Computer 01 . Its Jira User attribute value is tyler.

Test 2: Asset field is NOT empty

Create issue

View issue

Create issue

View issue

User is tyler and Computer field is not blank.

Computer value won't change.

If the tests pass successfully, it is ready for production.

Search modification

The following part of the script is search parameters. In this example, it filters assets by asset type and one attribute value. You can modify it according to your needs.

def queryToPostJson = " {\"searchType\" : \"basic\" ,\n" + " \"listType\" : \"detail\" ,\n" + " \"queryIndexSearchParams\" : [\n" + " {\n" + " \"field\" : \"" + fieldName + "\" ,\n" + " \"keyword\" : \"" + fieldValue + "\" ,\n" + " \"keywords\" : [] ,\n" + " \"fieldType\" : \"STRING\" ,\n" + " \"range\" : false\n" + " },\n" + " {\n" + " \"field\" : \"form.name\" ,\n" + " \"keyword\" : null ,\n" + " \"keywords\" : [\"" + assetTypeName + "\"] ,\n" + " \"fieldType\" : \"LIST\" ,\n" + " \"range\" : false\n" + " }\n" + " ] ,\n" + " \"pageNumber\" : 1 ,\n" + " \"pageSize\" : 10000 ,\n" + " \"sortDirection\" : \"asc\" ,\n" + " \"sortField\" : \"asset.id\"\n" + "} "

To find more alternatives, navigate to Asset Navigator and click Inspect. In the Network tab, query.json is the service, and locate Request Payload which is the search parameters. 

Â