Workflows SPI

On this page:

SPI API Reference

If you need more technical information on the latest SPI packages and interfaces, please read the complete API reference.

Get Started

The Jira application development platform allows applications to introduce new conditions, post-functions, and validators via the workflow modules. We refer to these capabilities as "workflow transition participants". Each workflow participant (condition, validator, or post-function) may store an arbitrary configuration in the form of key-value pairs. The Service Provider Interface for workflows provides the facilities for moving such configuration between different Jira instances. Configuration Manager will handle all the heavy load around moving the right configuration elements which are referenced in the properties of the workflow transition participants - for example, custom fields, users and groups, etc.

This integration point is available since SPI version 1.1.0

WorkflowParticipantHandler

The SPI for workflow transition participants consists of only one interface - com.botronsoft.cmj.spi.configuration.workflow.WorkflowParticipantHandler.

/** * Implement this interface to handle export/import for custom configuration data referenced in the arguments of a workflow transition * participant (condition, validator or post-function). */ @PublicSpi public interface WorkflowParticipantHandler { /** * Invoked when a configuration is being exported. This method will be called by Configuration Manager for each workflow transition * participant (condition, validator or post-function) which is handled by this handler. * * Implementers may call {@link com.botronsoft.cmj.spi.configuration.ConfigurationReferenceCollector} methods to handle references to * other configuration objects. * * @param className * the fully qualified class name of the currently exported workflow transition participant. * @param args * a map of arguments that are configured for the currently exported workflow transition participant. * @param exportContext * the context of the export operation. * @return a map of the transformed arguments - these can be the same arguments which were passed to this method or enhanced set of * arguments. This map will be passed to {@link #transformArgumentsForImport(String, Map, ImportContext)} when the configuration * is being deployed. * * @see ExportContext */ Map<String, String> transformArgumentsForExport(String className, Map<String, String> args, ExportContext exportContext); /** * Invoked when a configuration is being imported. This method will be called by Configuration Manager for each workflow transition * participant (condition, validator or post-function) which is handled by this handler. * * Implementers can call {@link com.botronsoft.cmj.spi.configuration.ConfigurationReferenceLookup} methods to retrieve the respective * matching configuration objects referred with {@link com.botronsoft.cmj.spi.configuration.ConfigurationReferenceCollector}. * * @param className * the fully qualified class name of the currently exported workflow transition participant. * @param args * the map which was returned by the invocation of {@link #transformArgumentsForExport(String, Map, ExportContext)}. * @param importContext * the context of the import operation. * @return a map of the transformed arguments - these are the arguments that will be effectively stored for the corresponding transition * participant. * * @see ImportContext */ Map<String, String> transformArgumentsForImport(String className, Map<String, String> args, ImportContext importContext); }

The different methods of this interface will be invoked by Configuration Manager when:

  • The configuration for a transition participant (condition, validator, or a post-function) is exported on the source system - this happens when a snapshot is being created.

  • The configuration for a transition participant (condition, validator, or a post-function) is imported into the target system - this happens when a snapshot is being deployed and a new workflow is created or an existing one is being updated.

Each transition participant is uniquely identified by its class name, which will be provided as a first argument to the methods for export and import.

The configuration for each transition participant is stored in Jira as a key-value property map. This key-value property map can be moved by Configuration Manager as is, or apps may choose to transform these properties and/or store additional data if needed.

Important

Check out SPI Tools for an easy way to implement a WorkflowParticipantHandler using a simple descriptive language.

Configuration Serialization and Versioning

The SPI does not impose any restrictions about how the configuration in each property value is serialized, only that the end result should be a String.

Collecting References

Each property (key-value pair) may contain references to other configuration elements in Jira, such as custom fields, Saved Filters, etc. It is important that during export, Configuration Manager is notified about these references because the IDs of these elements may be different between the source and the target instance, and Configuration Manager will match them and provide the correct IDs during import.

This can be achieved by invoking the methods of the ConfigurationReferenceCollector interface, accessible via the ExportContext interface. The key must be a unique identifier, that will be used when importing the configuration to resolve the reference on the target instance. The keys need to be unique only within the type of the configuration element - i.e. you can use the same key for a resolution or a status. In this sense, the Jira internal identifiers can be used as keys as well.

Resolving References

When a snapshot is being deployed, all collected references to other configuration elements must be resolved, because the identifiers of these elements are most probably different on the target system.

Use the ConfigurationReferenceLookup interface, accessible via the ImportContext interface. It provides convenient methods for resolving references by the same keys which were provided when collecting these references. The methods return java.util.Optional, because, in certain situations, references may be unresolvable. SPI implementations should be implemented to handle this possibility.

Registering the Handler with Configuration Manager

There are two options for registering the handler with Configuration Manager:

Via Java annotations

Annotate the handler class with the ConfigurationManagerSpiHandler annotation and the HandlesWorkflowParticipant annotation for each workflow participant that will be handled by this class:

@ConfigurationManagerSpiHandler @HandlesWorkflowParticipant(className = "com.mycompany.app.workflow.MyWorkflowCondition") @HandlesWorkflowParticipant(className = "com.mycompany.app.workflow.MyWorkflowValidator") @HandlesWorkflowParticipant(className = "com.mycompany.app.workflow.MyWorkflowPostFunction") public class SampleAnnotatedWorkflowParticipantHandler implements WorkflowParticipantHandler { ... }

In addition, the following entry needs to be added to the atlassian-plugin.xml which specifies the Java packages which contain the handlers:

<!-- Configuration Manager SPI Handler Packages --> <configurationManagerSpiHandler key="configuration-manager-spi-handler-packages"> <package>com.mycompany.app.handlers</package> </configurationManagerSpiHandler>

Only one entry is needed per app - multiple packages may be defined if needed. The classes in these packages will be scanned by Configuration Manager for the SPI annotations.

Via atlassian-plugin.xml

Another approach is to declare the handler in atlassian-plugin.xml directly - create a <workflowParticipantHandler> tag and the attributes and elements below.

Here is the list of supported attributes:

Attribute

Purpose

Attribute

Purpose

The unique key of the SPI implementation.

Required: yes

The implementation class - must extend the com.botronsoft.cmj.spi.configuration.workflow.WorkflowParticipantHandler interface.

Required: yes

Here is the list of supported elements:

Element

Purpose

Element

Purpose

The class of the transition participant (condition, validator, post-function) which is managed by this WorkflowParticipantHandler implementation. Multiple "participant" elements may be defined for a single handler.

Required: yes