This guide will help you extend the JIRA Import plugin using the Project Importer SPI. Currently, you can extend the JIRA importer plugin to include data from your plugins during project imports.
The JIRA Import plugin is used to import a JIRA project from a backup file into a JIRA instance (see documentation). One of the limitations of the JIRA Import plugin is that it cannot handle plugin data, which means that you cannot move plugin data between JIRA instances. An exception to this is custom fields, but even custom fields have limited support, e.g. the JIRA Agile sprint field might bring data across pointing to a sprint, but that sprint will not exist in the new JIRA instance.
The reason behind this limitation is that the JIRA import plugin does not have any idea of what data is stored by plugins or what the meaning and relationships with in that data are. It cannot tell what data refers to what projects or issues or even if the data is related to a project. For example, JIRA Agile is not organised around projects, but rather uses JQL to define rapid boards, etc.
The solution to this limitation is to let plugins actively participate in the import process. Read the following sections for an overview of the project import process and how your plugins can interact with the Project Importer SPI at each part of the process.
The project import process consists of a number of steps. The Project Importer SPI allows a plugin to participate in any of these steps. The basic flow is:
<jiraissue>
, <customfieldvalue>,
<jiraaction>
, etc.There are a number of basic mechanisms that your plugin needs to interact with:
In this document, we refer to the "JIRA Project Importer SPI" or just the "SPI" as we are mostly describing a set of interfaces that plugins will need to implement to fully participate in a project import. However, both SPI and API points will be provided and described.
Plugins can add to the validation that is performed before the import is done.
The process is quite complex, but in essence JIRA does a pass over the JIRA backup and gathers essential information for each project, such as the issue types and custom fields used. This information is held in the session. Once the user selects a project to import, JIRA validates the data from the backup for that project against the current system state.
The SPI described here allows plugins to join in that process.
Defines a handler class that will be able to gather data from the backup, that can then be used for validation or other purposes. This handler will be called in the initial stages of the import before the user is presented with a list of projects, from which they select the project to import.
The plugin point for this handler is: <project-import-ao-overview-handler>.
Method Summary
BackupOverviewBuilder.addAdditionalData(String key, String projectId, Object data)
to store critical backup data for each project in the backup. Multiple entries may be added under the same project and key.As this is a session object, this should only contain the minimum data required to ensure that the import can proceed for a project.
Defines a class that will be called to validate that the selected project can be imported.
Plugin developers need to understand the user flow here:
The plugin point for this handler is: <project-import-validator>
.
Method Summary
PluggableOverviewAoEntityHandler
. See Collection<Object> BackupProject.getAdditionalData(String key)
.Defines a handler class that will be able to perform some operation, given an AO entity name and the entities attributes.
There are two plugin points that both use this handler, <ao-preimport-handler>
and <ao-import-handler>
:
<ao-preimport-handler>
, will be called during the first import stage when the activeobjects.xml is split into files for each entity type. Plugins can gather data at this stage and store that, using instances of AbstractMapper
, for use in the actual import stage.<ao-import-handler>
, will be called after the OfBiz data has been installed. This is the time when plugins would normally import the required data into the database.Method Summary
ImportMapper
. This will be injected when the instance is created.ProjectImportResults
. This will be injected when the instance is created.BackupSystemInformation
. This will be injected when the instance is created.BackupProject
. This will be injected when the instance is created.Defines a handler class that will be able to perform some operation, given an OfBiz entity name and the entities attributes.
There are two plugin points that both use this handler, <ofbiz-preimport-handler>
and <ofbiz-import-handler>:
<ofbiz-preimport-handler>
will be called during the first import stage when the entities.xml is split into files for each entity type. Plugins can gather data at this stage and store that, using instances of AbstractMapper,
for use in the actual import stage.<ofbiz-import-handler>
will be called as JIRA imports the OfBiz Data. Plugins may need to import some data during this stage, e.g. entity properties.Method Summary
ImportMapper
. This will be injected when the instance is created.ProjectImportResults
. This will be injected when the instance is created.BackupSystemInformation
. This will be injected when the instance is created.BackupProject
. This will be injected when the instance is created.Plugins should provide a concrete implementation of this class when they need to map old values from the source system to new values in the destination and/or to flag values as required. They can, of course, extend it to provide any additional data they required to help in completing the import process. A general purpose mapper, SimpleProjectImportIdMapperImpl
, is provided for use in trivial cases.
Instances of the mapper are available by calling the getPluggableMapper(String mapperKey)
on the ImportMapper
.
Method Summary
AbstractMapper
and should not be called from other classes.null
if none is registered.There are two plugin points that both use this handler, <preimport-handler>
and <postimport-handler>:
<preimport-handler>
defines a handler class that will be called after the project object is created, but before any configuration or issue data is imported. Plugins can use this handler to examine the state of the target system before the import begins.<postimport-handler>
defines a handler class that will be called after the all data is imported into the destination system.Method Summary
ImportMapper
. This will be injected when the instance is created.ProjectImportResults
. This will be injected when the instance is created.BackupSystemInformation
. This will be injected when the instance is created.BackupProject
. This will be injected when the instance is created.Any plugins that provide custom field types that need to be migrated need to implement the ProjectImportableCustomField
interface. This interface requires the class to provide a ProjectCustomFieldImporter
that will look after any data translation required during the archiving process.
Method Summary
Interface com.atlassian.jira.imports.project.customfield.ProjectCustomFieldImporter
Plugins also need to supply or use a current JIRA implementation of this interface to actually map the imported data as required.
Method Summary
Each import handler is injected with the ProjectImportResults object. Plugins can add results to this using the following:
void addResult(long count, String msgKey)
A setter for the BackupProject
. This will be injected when the instance is created.
This section describes the key elements for your plugin descriptor, if you are using the Project Importer SPI. An example of the plugin XML is shown below:
1 2<?xml version="1.0" encoding="UTF-8"?> <atlassian-plugin > <project-import-ao-overview-handler key="myplugin-ao-overview-handler" class="com.atlassian.jira.dev.myplugin.imports.project.MyReferenceAoOverview" /> <project-import-validator key="myplugin-import-validator" class="com.atlassian.jira.dev.myplugin.imports.project.MyProjectImportValidator" /> <project-preimport-handler key="myplugin-preimport-handler" class="com.atlassian.jira.dev.myplugin.imports.project.MyPreImportPluginModule" /> <project-postimport-handler key="myplugin-postimport-handler" class="com.atlassian.jira.dev.myplugin.imports.project.MyPostImportPluginModule" /> <project-ao-preimport-handler key="myplugin-ao-preimport-handler" class="com.atlassian.jira.dev.myplugin.imports.project.MyAoPreImport" /> <project-ao-import-handler key="myplugin-ao-import-handler" class="com.atlassian.jira.dev.myplugin.imports.project.MyAoImport" /> <project-ofbiz-preimport-handler key="myplugin-ofbiz-preimport-handler" class="com.atlassian.jira.dev.myplugin.imports.project.MyOfBizPreImport" /> <project-ofbiz-import-handler key="myplugin-ofbiz-import-handler" class="com.atlassian.jira.dev.myplugin.imports.project.MyOfBizImport" /> </atlassian-plugin>
For the definition of the contents of these elements, see below:
Element | Description |
---|---|
| This block defines a handler that will be called while JIRA gathers data for al projects in the backup before the import starts. |
| The key of this handler definition. Must be unique within the plugin. Attribute: key. |
| An implementation of Attribute: class. |
Element | Description |
---|---|
| This block defines a module that can validate that a selected project is OK to import. |
| The key of this handler definition. Must be unique within the plugin. Attribute: key. |
| An implementation of Attribute: class. |
Element | Description |
---|---|
| This block defines a handler that will be called before the import of data commences. |
| The key of this handler definition. Must be unique within the plugin. Attribute: key. |
| An implementation of Attribute: class. |
Element | Description |
---|---|
| This block defines a handler that will be called after the import of data is complete. |
| The key of this handler definition. Must be unique within the plugin. Attribute: class. |
| An implementation of Attribute: class. |
Element | Description |
---|---|
| This block defines a handler that will be called for each data row for OfBiz tables that are handled. It is called during the preprocessing of the data, when all "entities.xml" entry from the backup zip file is processed in one pass and the entity types (tables) are split into separate files. Entities are processed in the order they are contained in the backup, which is alphabetical order. |
| The key of this handler definition. Must be unique within the plugin. Attribute: key. |
| An implementation of Attribute: class. |
Element | Description |
---|---|
| This block defines a handler that will be called for each data row for Active Objects tables that are handled. It is called during the preprocessing of the data, when all "activeobjects.xml" entry from the backup zip file is processed in one pass and the entity types (tables) are split into separate files. Entities are processed in the order they are contained in the backup, which is alphabetical order. |
| The key of this handler definition. Must be unique within the plugin. Attribute: key. |
| An implementation of Attribute: class. |
Element | Description |
---|---|
| This block defines a handler that will be called for each data row for OfBiz tables that are handled. It is called during the import of the data. The import of the data is actually performed by JIRA and generally plugins would not need to do anything at this time, but they can observe the data if they wish. The ordering of the data is controlled by JIRA and is undefined and may change from one JIRA to another. |
| The key of this handler definition. Must be unique within the plugin. Attribute: key. |
| An implementation of Attribute: class. |
Element | Description |
---|---|
| This block defines a handler that will be called for each data row for Active Objects tables that are handled. It is called during the import of the data. Plugins should import their data at this time. The ordering of the data is determined by the results of the calls to getEntityWeight(String entityName) with lowest values processed first. Plugin developers may cooperate to weight entities appropriately so plugin A's data is imported before plugin-B's data. Entities with lower weights are imported before entities with higher weights. |
| The key of this handler definition. Must be unique within the plugin. Attribute: key. |
| An implementation of Attribute: class. |
<property-entry>
and <property-????>
data, i.e. an <OSPropertyString>
entry will also have the entityName
and propertyKey
attributes.Rate this page: