Project Issue Data SPI

This integration point is available since SPI version 1.6.0

 

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

Apps often expand Jira’s functionality by providing different project facets, related to additional features, e.g., test case management, timesheet management, etc. Such apps usually store additional data related to issues in Jira. Such data may be persisted in Active Objects, entity properties, or anywhere else in Jira. When issues are moved from one instance of Jira to another, to keep the integrity of the data, this additional app data must also be migrated. This SPI endpoint helps with this process by allowing apps to migrate their own data without compromising its integrity.

This integration endpoint is designed for apps that store any type of data associated with issues or issue data (comments, attachments, etc.). The interface provides the tools to move this data and, in addition, resolve any references to configuration elements or Jira issue data (issues, comments, attachments, worklogs).

There is a separate endpoint for custom field data, which you can use if your app provides custom field types for fields that store data in a custom field value.

IssueDataHandler

The SPI for issue data consists of only one interface - com.botronsoft.cmj.spi.issue.IssueDataHandler.

/** * Interface for migrating issue data. This interface will be called whenever a project with issues is being exported or imported. */ @PublicSpi public interface IssueDataHandler { /** * Exports issue data for the provided project. Implementors are advised to optimize the performance of this method by first checking if * anything needs to be exported for the project at all. * * @param project * the project for which data is exported. * @param issueIds * a set of all exported issue ids - this could contain all issues in the project or just a subset. * @param context * the export context. * @return an {@link Optional} with the exported issue data or {@link Optional#empty} if the app does not store any issue data for this * project. */ Optional<String> exportIssueData(Project project, Set<Long> issueIds, IssueExportContext context); /** * Imports issue data for the provided project. * * @param data * the data which was exported by the {@link #exportIssueData(Project, Set, IssueExportContext)})}) method. * @param project * the project for which data is imported. * @param context * the import context. */ void importIssueData(String data, Project project, IssueImportContext context); }

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

  • A project with issues is exported on the source system - this happens when a project snapshot with issues is created.

  • A project with issues is imported into the target system - this happens when a project snapshot with issues is deployed.

The second parameter for the exportIssueData method is the set of issues that are currently being exported. Apps should make sure to export only the data that is related to those issues. The exportIssueData method will be invoked only once for a given project. It may be invoked only for a subset of the issues in the project.

Not all projects will contain issue data for a given app, that is why the implementors of this interface must first check if they store any data related to this project and immediately return an empty java.util.Optional if this is not the case.

Configuration Serialization and Versioning

The SPI does not impose any restrictions on how the issue data is serialized, only that the end result should be a String (see the return value of method exportIssueData). 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 importIssueData).

When implementing the SPI, it is crucial to think about configuration versioning in advance. Consider the following situation - source Jira has version 1.2 of your app, while the 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 backward compatible with previous versions.

Collecting References

Your issue data may contain references to configuration elements - either standard Jira configuration such as fields, custom field options, saved filters, etc., or custom configuration provided by the app, and handled by some of the Configuration SPI endpoints.

Collecting references to standard Jira configuration elements

Configuration Manager must be notified about all references to standard Jira configuration elements during export because:

  • Configuration Manager must include these elements in the snapshot.

  • 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.

Collecting the references can be achieved by invoking the methods of the ConfigurationReferenceCollector interface, accessible via the IssueExportContext interface. The key must be a unique identifier that will be used when importing the issue data 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.

Collecting references to app configuration elements

The issue data may also contain references to the configuration, which is specific to the app and is handled by some of the Configuration SPI endpoints. There is no need to collect these references in this case, as the app itself will migrate them, but you must take care to resolve them correctly when the data is being imported. More information on this is available in the next section.

Resolving References

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

Resolving references to standard Jira configuration elements

Use the ConfigurationReferenceLookup interface, accessible via the IssueImportContext 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.

Resolving references to app configuration elements

Use the AppMappingContext to lookup resolve IDs of the app-specific configuration elements that have been created as part of the import by any Configuration SPI endpoints. More information on using the AppMappingContext can be found in Share references between SPI handlers.

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:

@ConfigurationManagerSpiHandler public class SampleAnnotatedIssueDataHandler implements IssueDataHandler { ... }

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 <issueDataHandler> tag and the attributes below. Only one issue data handler per app is allowed.

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 implementation class - must extend the com.botronsoft.cmj.spi.issue.IssueDataHandler interface.

Required: yes