Custom Fields 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 custom field types via the customfield-type module. Custom fields of such type may have their own specific configuration. The Service Provider Interface for custom fields 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 custom field configuration - for example, other fields, JQLs, users and groups, etc.

This integration point is available since SPI version 1.0.0

CustomFieldConfigurationHandler

The SPI for custom fields consists of only one interface - com.botronsoft.cmj.spi.configuration.field.CustomFieldConfigurationHandler.

/** * Implement this interface to handle export/import for custom configuration data used by a * {@link com.atlassian.jira.issue.fields.CustomField}. * * The implementation of this interface is responsible for serializing/deserializing custom field configuration data and recording * references to Jira configuration elements like workflows, users, groups, other custom fields, etc. * * @see ConfigurationReferenceCollector * @see ConfigurationReferenceLookup */ @PublicSpi public interface CustomFieldConfigurationHandler { /** * Invoked when a configuration is being exported. This method will be called by Configuration Manager for each context of the currently * exported field. * * Implementers may call {@link com.botronsoft.cmj.spi.configuration.ConfigurationReferenceCollector} methods to handle references to * other configuration objects. * * @param customFieldContext * the currently exported {@link FieldConfigScheme}. * @param exportContext * context of the export operation. * * @see ExportContext */ String exportConfiguration(FieldConfigScheme customFieldContext, ExportContext exportContext); /** * Invoked when a configuration is being imported. This method will be called by Configuration Manager for each context of the currently * imported field. * * 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 customFieldContext * the currently imported {@link FieldConfigScheme} instance. * @param importContext * context of the import operation. * * @see ImportContext */ void importConfiguration(String configuration, FieldConfigScheme customFieldContext, ImportContext importContext); /** * Invoked when configuration needs to be deleted. This method will be called by Configuration Manager when a custom field context is * deleted so any configuration stored by the app and associated with this context can also be deleted. * * @param customFieldContext * the deleted {@link FieldConfigScheme} instance. */ void deleteConfiguration(FieldConfigScheme customFieldContext); }

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

  • The configuration for a custom field is exported on the source system - this happens when a snapshot is being created.

  • The configuration for a custom field is imported into the target system - this happens when a snapshot is being deployed and a new custom field context is created or an existing one is being updated.

  • The configuration for a custom field is deleted - this happens when a custom field or a custom field context is being deleted, usually when a snapshot is deployed in Restore mode.

The SPI is designed around custom field contexts (com.atlassian.jira.issue.fields.config.FieldConfigScheme) as a single custom field may have multiple contexts with a different configuration.

Configuration Serialization and Versioning

The SPI does not impose any restrictions about how the configuration of the custom field is serialized, only that the end result should be a String (see the return value of method exportConfiguration). Internally you can use XML, JSON, or whatever format is needed, as long as the app can deserialize it when the configuration is imported (see method importConfiguration).

When implementing the SPI it is very important to think about configuration versioning in advance. Consider the following situation - source Jira has version 1.2 of your app, while target Jira has version 1.3 and there is a change in the way configuration data was serialized in between the versions. To ensure smooth user experience, make sure the SPI implementation in your app is backwards compatible with previous versions.

Collecting References

Your custom field configuration may contain references to other configuration elements in Jira, such as other fields, JQLs, 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 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 HandlesCustomFieldType annotation, providing the type key:

@ConfigurationManagerSpiHandler @HandlesCustomFieldType(typeKey = "com.mycompany.app:samplefield") public class SampleAnnotatedCustomFieldConfigurationHandler implements CustomFieldConfigurationHandler { ... }

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 <customFieldConfigurationHandler> tag and the attributes below.

Here is the list of supported attributes:

Attribute

Purpose

Attribute

Purpose

The name of the SPI implementation.

Required: no

The unique key of the SPI implementation.

Required: yes

The full key of the custom field type for which this SPI implementation applies.

Required: yes

The implementation class - must extend the com.botronsoft.cmj.spi.configuration.field.CustomFieldConfigurationHandler interface.

Required: yes