Work with Issue and Entity Properties
Entity properties allow you to add key/value stores to issues, projects, users, and comments. Your scripts can use these properties for automations, for example, to store a user's department name on the user object.
There are two different mechanisms you can use to create these data stores. Check out the table below to compare the two mechanisms:
Entity properties (more modern) | Property sets (can be applied to any Jira entity) |
---|---|
Permissions are respected, for example, you can only write properties on an issue if you can edit that issue (HAPI provides you with a way to override security). | Have no permissions model. |
Are accessible through a REST API—if the user can view the issue, they can access all the properties through this REST API. | Are not accessible through the out-of-the-box REST API. |
Are limited to 32k. | Effectively unlimited size for strings. |
As well as simple data types, you can serialize your own classes and store them on entities. | - |
Issue properties can be indexed and searched with JQL. | - |
- | HAPI only enables property sets for |
Entity properties
Setting and getting issue properties
The following is a simple example of setting and getting an issue property:
def issue = Issues.getByKey('ABC-1') // setting the property issue.entityProperties.setString('my first property', 'Hello World!') // retrieving the property value issue.entityProperties.getString('my first property') // returns 'Hello World!'
Permissions
Setting a property requires that you have permission to edit the entity in question (issue, user, comment, etc.). Retrieving a property requires you have view permissions, for example, you can view the issue on which the property is stored. You can overwrite security restrictions as described below.
You can also set and get several other property types:
Use the corresponding getter to retrieve the property value.
import groovy.json.JsonOutput import java.time.LocalDate def entityProperties = Issues.getByKey('ABC-1').entityProperties entityProperties.setString('foo', 'bar') entityProperties.setBoolean('onboarded', true) entityProperties.setInteger('meaning of life', 42) entityProperties.setLong('birth year', 1972L) entityProperties.setLocalDate('my date', LocalDate.now())
In addition to the property types listed above, you can store maps, lists, or your own classes. For example, to store a map you could use the following:
entityProperties.setAsActualType('tasks', [ content: 'complete design work', estimateInDays: 2, ]) // retrieve the properties as a Map entityProperties.getAsActualType('tasks', Map)
You can store instances of your own classes. Check out the Searchable entity properties section to find out how.
Overwriting security restrictions
To read and write properties overriding the security restrictions, use getEntityPropertiesOverrideSecurity()
:
def entityProperties = Projects.getByKey('ABC').entityPropertiesOverrideSecurity entityProperties.setString('foo', 'bar')
Searchable entity properties
You can store your own instances of your own class and have it as a searchable entity property.
The property is serialized and deserialized with Jackson 2.x. If you want to handle the serialisation and deserialisation of the property yourself, use setJson
and getJson:
entityProperties.setJson('my json', JsonOutput.toJson([foo: 'bar', qux: 3]))
Creating a searchable entity property
It is possible to have Jira index the property data of your own class, and then you can query on it with JQL. To do this, you can register a new plugin module, specifying which properties to extract.
Register a plugin module using code similar to the following:
Plugin modules registered as follows will be removed when Jira restarts. Use the code in a script inside the
startup
directory, to ensure it executes on every restart.import com.onresolve.licensing.DynamicModulesComponent import com.onresolve.scriptrunner.runner.ScriptRunnerImpl def dynamicModulesComponent = ScriptRunnerImpl.getPluginComponent(DynamicModulesComponent) def pluginXml = """ <index-document-configuration entity-key="IssueProperty" key="jira-issue-tasklist-indexing"> <key property-key="task"> <extract path="content" type="text"/> <extract path="estimateInDays" type="number"/> </key> </index-document-configuration> """ def writer = new StringWriter() writer.write(pluginXml) dynamicModulesComponent.register(writer)
- Add the issue property as follows:
class IssueTask { String content Integer estimateInDays } entityProperties.setAsActualType('task', new IssueTask(content: 'complete design', estimateInDays: 3)) // if you need to retrieve the property programmatically: entityProperties.getAsActualType('task', IssueTask)
- Execute the JQL as follows:
'issue.property[task].content ~ "design" AND issue.property[task].estimateInDays = 3'
Consult Atlassian documentation on making entity properties searchable for more information.
Property sets
Reading and writing user properties
As discussed in the table above, property sets are an older form of storing key/value pairs. Use the following to read and write user properties:
def user = Users.loggedInUser def propertySet = user.propertySet propertySet.setString('foo', 'bar') propertySet.getString('foo')
Consult the javadoc for PropertySet to see the different types of properties you can set and get.