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

Scriptrunner - Update Insight Object attribute value if it was empty before

Six June 16, 2021

Hi Community!

I want to update Insight object attribute in workflow post function. I have many object type e.g.: Monitor, Laptop, Phone. Every object type has the attribute: Status (The type of the Status attribute is Status). In the ticket there is an asset list, e.g.: monitor1, laptop1, laptop2.

I want update the attribute Status of all objects in the ticket regardless of their type. I have a working solution if the object Status value is not null (earlier somehow was set), but it's not working, if the attribute is empty:

assetList.each{asset ->
def insightObject = iqlFacade.findObjectsByIQLAndSchema(schemaId, "key = " + asset.getObjectKey()).first();
def attributeId = insightObject.objectAttributeBeans.find {
objectTypeAttributeFacade.loadObjectTypeAttributeBean(it.objectTypeAttributeId).name == "Status"
}?.objectTypeAttributeId;

def objectTypeAttributeBean = objectTypeAttributeFacade.loadObjectTypeAttributeBean(attributeId);
def newStatusAttributeBean = asset.createObjectAttributeBean(objectTypeAttributeBean);
def newObjectAttributeBean = objectAttributeBeanFactory.createObjectAttributeBeanForObject(insightObject, objectTypeAttributeBean, "NewStatusName");

def objectAttributeBean = objectFacade.loadObjectAttributeBean(insightObject.getId(), objectTypeAttributeBean.getId());
if (objectAttributeBean != null) {
newObjectAttributeBean.setId(objectAttributeBean.getId());
}
objectAttributeBean = objectFacade.storeObjectAttributeBean(newObjectAttributeBean);
}

I can get the ObjectTypeId from the asset and create a new ObjectTypeBean:

def objectTypeId = asset.getObjectTypeId();
def objectTypeBean = objectTypeFacade.loadObjectTypeBean(objectTypeId);

??????
def attributeId = objectTypeBean.getAttributeId.where(name == "Status"); //here I want to get the the current asset attribute id, where the attribute name is Status
??????

But I don't know, how to get the attributeId of the current object type Status attribute by the name of the attribute!

5 answers

1 accepted

2 votes
Answer accepted
Alex van Vucht (GLiNTECH)
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.
June 20, 2021

Okay, here is my 'lazyUpdate' function. 'simpleAttributes' is a simple "Key: attribute name, value: list of values for that attribute" map. Just call this function with the object and map, and as long as the attribute names match, it should update in most cases. In my case, I didn't have to update object references, so you may need to extend this function a little for that.

You should have instantiated the relevant facades: 

  • attrMgr: ObjectTypeAttributeFacade
  • attrFty: ObjectAttributeBeanFactory
  • objMgr: ObjectFacade

 

Map lazyUpdate(ObjectBean object, Map<String,List> simpleAttributes) {

/* Get metadata on attributes from object metadata (ie. the object type) */
List<ObjectTypeAttributeBean> objectTypeAttributeBeans = attrMgr.findObjectTypeAttributeBeans(object.getObjectTypeId())

List objectTypeAttributeNames = objectTypeAttributeBeans.collect{it.getName().toLowerCase()}

/* Proceed only with attributes that match keys in the map */
simpleAttributes.findAll {
it.key.toLowerCase() in objectTypeAttributeNames

}.collectEntries { attr, values ->

/* This is the object type attribute and the one we want to modify */
ObjectTypeAttributeBean objectTypeAttributeBean = objectTypeAttributeBeans.find {
it.getName().toLowerCase() == attr.toLowerCase()
}

/* Create the new attribute bean based on the value */
def newObjectAttributeBean = attrFty.createObjectAttributeBeanForObject(object, objectTypeAttributeBean, values.getAt(0) as String)

/* Load the attribute bean */
def objectAttributeBean = objMgr.loadObjectAttributeBean(object.getId(), objectTypeAttributeBean.getId());
if (objectAttributeBean != null) {
/* If attribute exist reuse the old id for the new attribute */
newObjectAttributeBean.setId(objectAttributeBean.getId());
}

/* Store the object attribute into Insight. */
try {
objectAttributeBean = objMgr.storeObjectAttributeBean(newObjectAttributeBean);
} catch (Exception vie) {
log.warn("Could not update object attribute due to validation exception:" + vie.getMessage());
}
[objectTypeAttributeBean.getName(),objectAttributeBean.getObjectAttributeValueBeans()*.getValue()]
}
}
Six June 28, 2021

Hi,

Thank you for your help, I didn't used this function, but it helped a lot!

This line was the key, what I needed, after that my code is working fine.

List<ObjectTypeAttributeBean> objectTypeAttributeBeans = attrMgr.findObjectTypeAttributeBeans(object.getObjectTypeId())

 Thanks again! I'm very happy now! :)

Six

1 vote
Alex van Vucht (GLiNTECH)
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.
June 17, 2021

Hey, so the issue is that you can't reliably ask an object for its attribute types because objects only store information on attributes that have values. Objects won't tell you about attributes that don't have a value.

The way to work with Insight attributes is:

  1. Get the object type ID from the object
  2. Get the object type from the object type ID
  3. Get the attributes from the object type

It looks simpler to get the attributes from the object but if you ever want to change objects, that's not going to be enough. You have to get the attributes from the object type.

Hope that helps!

Six June 18, 2021

Hi,

Thank you for your reply!

Yes, that's what I tried to do, just I don't know how to do that by the name of the attribute. Can you help me?

Six

Alex van Vucht (GLiNTECH)
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.
June 20, 2021

<Moved to an answer>

0 votes
Carlos Tichy May 11, 2022

Try always getting first the objectAttributeBean and based on that (to see if it is null) then the attribute.

See the following piece of code:

 



//Gets the Device Type -> DeviceTypeAttribute and related fields
def DeviceTypeAttributeOAB = objectFacade.loadObjectAttributeBean(objectId, objectTypeAttributeName)
def DeviceTypeAttribute = DeviceTypeAttributeOAB ? DeviceTypeAttributeOAB.getObjectAttributeValueBeans()[0] : null; //Loads the ObjectAttributeValueBeans of the DEVICE_TYPE or null

0 votes
Carlos Tichy May 11, 2022

Try always getting first the objectAttributeBean and based on that (to see if it is null) then the attribute.

See the following piece of code:

 



//Gets the Device Type -> DeviceTypeAttribute and related fields
def DeviceTypeAttributeOAB = objectFacade.loadObjectAttributeBean(objectId, objectTypeAttributeName)
def DeviceTypeAttribute = DeviceTypeAttributeOAB ? DeviceTypeAttributeOAB.getObjectAttributeValueBeans()[0] : null; //Loads the ObjectAttributeValueBeans of the DEVICE_TYPE or null

 

0 votes
John Chin
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.
June 16, 2021

Hi @Six 

Does the following code works for you to get the attribute id ?

def attribute = objectFacade.loadObjectAttributeBean(asset.getId(), "Status")

log.warn "attribute id: "+attribute.objectTypeAttributeId

Regards,

John Chin 

Six June 17, 2021

Hi @John Chin

It's not working, I get the following error:
"java.lang.NullPointerException: Cannot get property 'objectTypeAttributeId' on null object".

I think the problem is the same as in my solution: The current asset has no Status attribute (because it's empty yet). :(
(I have tried the solution with an attribute which has value and that case it's working.)

Six

Suggest an answer

Log in or Sign up to answer
DEPLOYMENT TYPE
SERVER
TAGS
AUG Leaders

Atlassian Community Events