How to import groovy classes into Riada Insight groovy scripts?

Tomi Kallio January 19, 2018

I have a simple groovy class that helps me deal with Insight object attributes. There is some amount of boilerplate code that is needed when dealing with objects, e.g. in automation when setting an attribute value based on other attributes.

The problem is the class must be inside the same groovy script in order for it to function. If I put it in an external file, the import will obviously fail since groovy does not know where to find the file.

Is it somehow possible to import classes directly from groovy files and use those classes in Insight automation groovy scripts (without compiling them to .class files)?

It would be best if we could import classes from within Script Runner's scripts directory.

Here's an example of using that class in automation:

import SimpleInsightObject


def obj = new SimpleInsightObject(object)

// Compose a new id based on two object attributes.
def id = obj.get("Attribute A") + " " + obj.get("Attribute B")

// Set the value of the "Id" attribute.
obj.setText("Id", id)

When I have a lot of automation tasks that deal with objects and their attributes, using such a helper class simplifies things greatly.

4 answers

1 accepted

Suggest an answer

Log in or Sign up to answer
2 votes
Answer accepted
Alexander Sundström
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.
January 24, 2018

Hi Tomi,

The way this can be done as of today is documented at https://documentation.riada.se/insight/latest/insight-for-developers/groovy-scripting/import-groovy-script-from-one-to-another

Let us know if you have any feedback about how it could be improved and if some functionality is missing.

Best Regards
Alexander

Tomi Kallio January 24, 2018

There's a little bit of boilerplate code required but it can be seen as just another way to do import and instantiation for the classes.

This solves my problem, thanks a lot!

Alexander Sundström
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.
January 25, 2018

Glad that I could be of help!

Best Regards
Alexander

Tomi Kallio January 25, 2018

@Alexander Sundström, perhaps a small enhancement to your documentation? Or not even an enhancement but an addition that might help users:

Instead of using an absolute path for the scripts, one can use this instead:

def PATH_TO_SCRIPTS = new File(getClass().protectionDomain.codeSource.location.path).parent

This will provide a path to the directory in which the automation scripts is contained. Groovy classes in this directory are now easy to access, and if the directory is somehow relative to where one's Script Runner scripts are located, this could also come handy when accessing those (just build a relative path).

Another benefit is that it works on different Jira instances right out of the box. Say, you have a production and QA/test/dev instances and they have different paths for where the scripts live. Finding the path dynamically means that the code works on all of those instances without any modification.

Tomi Kallio January 25, 2018

And finally, for the sake of closure, here is the original example script with modifications:

def scriptPath = new File(getClass().protectionDomain.codeSource.location.path).parent
File classFile = new File(scriptPath, "SimpleInsightObject.groovy")
Class objectClass = new GroovyClassLoader(getClass().getClassLoader()).parseClass(classFile)


GroovyObject obj = (GroovyObject) objectClass.newInstance(object)

// Compose a new id based on two object attributes.
def id = obj.get("Attribute A") + " " + obj.get("Attribute B")

// Set the value of the "Id" attribute.
obj.setText("Id", id)
Alexander Sundström
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.
January 31, 2018

Hi Tommi,

Thanks for the adding this information. I've updated our documentation to mention this possibility.

Cheers!
Alexander

0 votes
Tomi Kallio January 24, 2018

The short answer at the moment is that it is not possible to import groovy classes into Insight automation groovy scripts for now.

If/when things change, or if somebody has a working solution in mind, please suggest it here.

Tomi Kallio January 24, 2018

Riada has instructions for this available in their documentation (as instructed by Alexander in the comments). It might not be the way I was looking for but it is a way and will certainly get the job done.

0 votes
Rickard Hyllenstam January 22, 2018

Some enhancements have been made to the API to help us with for example updating attributes on objects. Check out the ObjectAttributeBeanFactory, javadoc

with some example's here: documentation

Hope this help's a bit!

Br,

Rickard

Tomi Kallio January 22, 2018

Hi Rickard!

I am already using that API inside my SimpleInsightObject class; there are getters and setters so that the example code above works.  So those .get() and .setText() methods exists and work already so that is not a problem at all.

What is the real problem is that the definition of SimpleInsightObject class must be within the same groovy script in order for it to work. Somehow groovy (as used by Insight automation) will not find the class I'm trying to import (something related to CLASSPATH?).

I'm potentially writing a large number of automation scripts and want to share code between them. I wrote SimpleInsightObject class to keep the automation scripts as simple as possible, without any of the boilerplate code. I'd rather not write (copy-paste, really) all that code in your API example into each and every automation script that sets attributes. I'd much rather use my own class where all the boilerplate is already written inside the class and its methods.

I'm trying to obey Don't Repeat Yourself rule here.

Rickard Hyllenstam January 23, 2018

I fully follow your case and I like it! :)

I suggest you file a ticket with our support to get this sorted, might be a lack of feature that could be implemented. I could really get use of your class some times! 

Tomi Kallio January 24, 2018

Riada could add such a class into the API. Just a class that abstracts away everything that is strictly not necessary to get and set values. The intended purpose for the class would be to easily and conveniently get/set attributes in automation scripts.

Actually, the class or even an instance of the class could be automatically given as "context" for the automation groovy scripts, letting the user to deal with just the business logic (or whatever you'd call it).

That wouldn't take away the need to use external groovy libs, though. In my case, I have a fair amount of groovy created to be used in Script Runner scripts/post-functions/listeners in a given customer's context. Getting access to those will make Insight automation an even more powerful part of the system!

Thanks for the tip - I will file a ticket for you guys!

Tomi Kallio January 24, 2018

@Rickard Hyllenstam RPS-5236 is the ticket.

Rickard Hyllenstam January 24, 2018

I agree with the fact that such class should be present as context and very useful for groovy scripts. 

I will try to push for such feature, feel free to share your class. 

Br,

Rickard

0 votes
Ivan Punko January 22, 2018

Hello @Tomi Kallio, it is a really weird, because I have one self-writed Class and import in multiply scripts w/o any problems.

e.g.

ls ./

Class1.groovy
test.groovy
Class2.groovy

 and then in test.groovy:


import Class1
import Class2

first = new Class1()
second = new Class2()

Works like a magic .

> without compiling them to .class files

You don't have to compile to any class and you even don't need to define Class in your Class1 and Class2 scripts, because groovy compile to ScriptName class on the fly if has no definition.

 

But in your MainScript(test.groovy) in example you must create a new object (like first = new Class1() )

Regards,

Ivan

Tomi Kallio January 22, 2018

Hi Ivan!

So your (external) classes work in Riada Insight automation groovy scripts? Because that's what I'm after.

I too have (external) classes that are stored under Script Runner's scripts directory, and get imported into scripts (e.g. post-functions and listeners). When it comes to Script Runner, things work just fine.

My problem is that I can not use those classes of mine with Insight as import fails (Groovy as used by Insight can not find them), even when the classes are defined in files right beside the scripts, located in the very same directory.

TAGS
AUG Leaders

Atlassian Community Events