Migrating from Jira Server / Data Center
At Elements, we're fully committed to making your path from Server / Data Center to Cloud as seamless as possible.
We're working hard to ensure that in the coming months the value you can get from the Cloud version of Elements Connect matches and even exceeds the one you currently get with our Server / Data Center app.
While this is our long term goal, we know that today there's a gap in functionality between our Server / Data Center product and our Cloud app.
Most of the key functionalities of the Server / Data Center app will be implemented, however, due to functional differences between the Cloud and Server/Data Center platforms (listed as "not possible" on the tables below), we are not able to deliver 1:1 feature parity between the environments.
Rest assured, the Elements team is working hard to ensure our Elements Connect Server/Data Center users find similar functionality in Cloud and enjoy an excellent experience with our Cloud app.
Tell us more about your needs
We know you have your hands full if you are migrating to cloud (or maybe just thinking about it), and we want to do as much as we can to help you achieve on Cloud what you’ve spent time crafting with your Jira on premise.
In order to prioritize which features to bring first to Elements Connect for Cloud so you can offer the same experience and value to your teams, we want to know more about your configuration. By answering these questions, we’ll be able to focus our efforts on what you need most. It will only take 5 minutes of your time!
In order to get a migration assessment of your Connect configuration, feel free to leave your email at the end of the questionnaire or book a 30-min call with the Product Manager here.
Migration path
Here are the key steps to follow to successfully migrate your Elements Connect configuration from Jira Server/Data Center to Jira Cloud:
1. First, verify that all the features you need exist on Jira Cloud (see the table below)
It is important for to be aware of the feature parity between the hosting environments. Some of your configuration may not yet be available, or you need to implement another solution to achieve the same that you have done in your Jira Server / Data Center environment.
2. Install Elements Connect on your Jira Cloud instance.
We recommend you take some time to evaluate the Cloud app to get a better understanding of how it works.
3. Manually create your configuration (datasources and connected items) in Elements Connect for Jira Cloud
- Uncheck the option "Create associated mirror field"
- Uncheck the option "Create associated mirror field"
4. Prepare connected fields values for migration
On your Server / Data Center instance, create as many Jira Text Custom fields as you have Elements Connect fields
For multiple value fields, create Jira Text Area Custom fields.
Now that your target custom fields are created, you can now copy your Connect fields display to these. You can do so in two different ways:
4.1 By using the "Copy field display to another field" post-function
- For each workflow linked to an issue associated with an Elements Connect Custom Field, add a global transition with our post-function "Copy field display to another field"
- Configure as many post-functions as needed in order to have a 1-to-1 mapping between Elements Connect Custom Fields and Jira Text Custom fields
- Use a Bulk operation to execute the previous transition on all the relevant issues
4.2 By running a ScriptRunner script to copy field display to another field
You can also decide to use a groovy script to copy Elements Connect field display to other custom fields. For this to work, you'll need to have Script Runner installed.
The following script will copy the field display of Elements Connect fields that are not empty which match the JQL query specified at line 21.
import org.apache.log4j.Logger
import org.apache.log4j.Level
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.link.IssueLinkTypeManager
import com.atlassian.jira.bc.issue.search.SearchService
import com.atlassian.jira.jql.parser.JqlQueryParser
import com.atlassian.jira.web.bean.PagerFilter
import com.atlassian.jira.issue.ModifiedValue
import com.atlassian.jira.issue.util.DefaultIssueChangeHolder
import com.atlassian.jira.security.groups.GroupManager
log.setLevel(Level.INFO)
log.info("SCRIPT - START")
log.info("-----------------------------------------")
def pluginAccessor = ComponentAccessor.getPluginAccessor();
def customFieldManager = ComponentAccessor.getCustomFieldManager()
def jqlQueryParser = ComponentAccessor.getComponent(JqlQueryParser)
def searchService = ComponentAccessor.getComponent(SearchService)
def user = ComponentAccessor.getJiraAuthenticationContext().getUser()
// -----------------------------------------------------
// TO EDIT: please write a valid JQL query returning the issues to be updated
def jqlQuery = "project = PM"
// TO EDIT: Please populate the table with the following information:
// - In the 1st column, the Connect field ID to be copied (source)
// - In the 2nd column, the Text Area field ID to be populated (target)
// This must be a 1 to 1 relationship, and one Connect field must correspond to one Text Area field.
def fieldsMapping =
[
['customfield_10200','customfield_10305'],
['customfield_10302','customfield_10306'],
['customfield_10203','customfield_10307'],
['customfield_10303','customfield_10308'],
['customfield_10304','customfield_10309'],
]
// Loop to browse all Connect fields to be copied.
for(fields in fieldsMapping){
def connectFieldId = fields[0]
log.info("SCRIPT - Connect field ID => "+connectFieldId)
def textFieldId = fields[1]
def textField = customFieldManager.getCustomFieldObject(textFieldId);
// We get the Connect field type (Live Text, Live User, Snapshot Text, Snapshot Date or Snapshot Datetime)
def connectFieldType = customFieldManager.getCustomFieldObject(connectFieldId).getCustomFieldType().getName();
log.info("SCRIPT - Connect field type => "+customFieldManager.getCustomFieldObject(connectFieldId).getCustomFieldType().getName())
// Improvement of the JQL query with a check of the Connect field in each ticket
def jqlQueryOptimized;
if(jqlQuery){
jqlQueryOptimized = jqlQuery+" AND cf["+connectFieldId.replace('customfield_','')+"] IS NOT EMPTY"
}
else{
jqlQueryOptimized = "cf["+connectFieldId.replace('customfield_','')+"] IS NOT EMPTY"
}
log.info("SCRIPT - JQL Query => "+jqlQueryOptimized)
// Processing of the JQL query
def results = searchService.search(user, jqlQueryParser.parseQuery(jqlQueryOptimized), PagerFilter.getUnlimitedFilter())
def issueManager = ComponentAccessor.issueManager
def issueLinkTypeManager = ComponentAccessor.getComponent(IssueLinkTypeManager)
final Long sequence = 1L
def loggedInUser = ComponentAccessor.jiraAuthenticationContext.loggedInUser
log.info("SCRIPT - Total issues to be updated => ${results.total}")
// Different value copy actions are performed depending on the Connect field type
if(connectFieldType == "Elements Connect - Live - Text"){
// We get the classes related to the Elements Connect API
def plugin = pluginAccessor.getPlugin("com.valiantys.jira.plugins.SQLFeed");
def serviceClass = plugin.getClassLoader().loadClass("com.valiantys.nfeed.api.IFieldDisplayService");
def fieldDisplayService = ComponentAccessor.getOSGiComponentInstanceOfType(serviceClass);
// Loop to browse all the issues returned by the JQL Query
results.getResults().eachWithIndex { issue , it ->
String displayValue = "";
Object displayResult = fieldDisplayService.getDisplayResult(issue.key, connectFieldId);
if (displayResult && displayResult.getDisplay()) {
def textValues = displayResult.getDisplay().replace('<BR/>','\n');
// We copy the Connect field value to the Text Area field
textField.updateValue(null, issue, new ModifiedValue(issue.getCustomFieldValue(textField), textValues), new DefaultIssueChangeHolder())
log.info("SCRIPT - issue ${issue.key} has been updated ("+(it+1)+" out of ${results.total})");
}
}
}
else if(connectFieldType == "Elements Connect - Live - User") {
// We get the classes related to the Elements Connect API
def plugin = pluginAccessor.getPlugin("com.valiantys.jira.plugins.SQLFeed");
def serviceClass = plugin.getClassLoader().loadClass("com.valiantys.nfeed.api.IFieldValueService");
def fieldValueService = ComponentAccessor.getOSGiComponentInstanceOfType(serviceClass);
// Loop to browse all the issues returned by the JQL Query
results.getResults().eachWithIndex { issue , it ->
def userValues = fieldValueService.getFieldValues(issue.key, connectFieldId);
if(userValues){
// We copy the Connect field value to the Text Area field
textField.updateValue(null, issue, new ModifiedValue(issue.getCustomFieldValue(textField), userValues.join('\n')), new DefaultIssueChangeHolder())
log.info("SCRIPT - issue "+issue.key+" has been updated ("+(it+1)+" out of ${results.total})");
}
}
}
else if(connectFieldType == "Elements Connect - Snapshot - Text" || connectFieldType == "Elements Connect - Snapshot - Datetime") {
// Loop to browse all the issues returned by the JQL Query
results.getResults().eachWithIndex { issue , it ->
def snapshotField = customFieldManager.getCustomFieldObject(connectFieldId)
def snapshotValues = issue.getCustomFieldValue(snapshotField)
if(snapshotValues){
// We copy the Connect field value to the Text Area field
textField.updateValue(null, issue, new ModifiedValue(issue.getCustomFieldValue(textField), snapshotValues.toString()), new DefaultIssueChangeHolder())
log.info("SCRIPT - issue "+issue.key+" has been updated ("+(it+1)+" out of ${results.total})");
}
}
}
else if(connectFieldType == "Elements Connect - Snapshot - Date") {
// Loop to browse all the issues returned by the JQL Query
results.getResults().eachWithIndex { issue , it ->
def snapshotField = customFieldManager.getCustomFieldObject(connectFieldId)
def snapshotValues = issue.getCustomFieldValue(snapshotField)
if(snapshotValues){
// We copy the Connect field value to the Text Area field
textField.updateValue(null, issue, new ModifiedValue(issue.getCustomFieldValue(textField), snapshotValues.toString().split(" ")[0]), new DefaultIssueChangeHolder())
log.info("SCRIPT - issue "+issue.key+" has been updated ("+(it+1)+" out of ${results.total})");
}
}
}
else {
log.info("SCRIPT - Connect Field Type => Unknown")
}
log.info("-----------------------------------------")
}
log.info("SCRIPT - END")
Or download it here:
In order for this script to run, you will need to:
Specify a JQL query to narrow down the scope of this field display copy job. (line 21)
We recommend you to start with a restrictive JQL query for testing purposes. If tests are successful, then you can extend the scope of your JQL query.
Specify the Elements Connect field IDs you want to copy (source) and the field IDs of the Text Area custom fields where you want the data to be copied to (target) (start line 28). There should be as many field mappings as there are Elements Connect fields to copy.
If your JQL query returns over 1000 results, make sure to increase the default maximum limit of 1000 in Jira. Alternatively, you can run the script over as many batches as required.
If you wish to run this script over a large number of issues, we recommend you to do that during non-business hours for performance reasons.
We recommend that you verify that all Elements Connect Custom Fields have their display value copied in their dedicated Jira Text Custom Field.
5. Export connected fields values from Jira Server/Data Center
You have two ways of exporting your Jira issues with their values:
Export your Jira tickets using the CSV exporter - the CSV file generated will be used to import your data in the next step.
Or
Export your Jira tickets using the Jira Cloud Migration Assistant
Some specificities to take into account
HTML in display template
For every Elements Connect custom fields using HTML/CSS in the display template, make sure there are no reference to HTML/CSS in the CSV document:
- Edit the display template for each Elements Connect custom fields and remove HTML/CSS references
OR - Make sure there are no HTML/CSS references directly in the CSV file
User type fields
For Elements Connect User type custom fields, use the "Copy field key to another field" post-function. You will copy the user's username in the text field.
- Edit the display template for each Elements Connect custom fields and remove HTML/CSS references
6. Import the previously generated CSV file in Jira Cloud
- On your Jira Cloud instance, create as many Jira Text Custom fields as previously created on Server/Data Center
- Import the CSV file
7. For each Connected item, set the mirror field accordingly
- Map the custom fields created in step 4 to the right Connected item using the mirror fields.
This migration path allows you to migrate data to Jira Cloud only. Configurations need to be performed manually again and Connected items need to be manually added to projects as well.
We're here to help
We’re committed to making your migration to Elements Connect for Jira Cloud as smooth as possible, don’t hesitate to contact our support team should you have any question or concern. We recommend that you attach your support dump file to your support request, it'll help our team provide more accurate answers about your specific case.
Implementation status
This section lists the implementation status in Jira Cloud of Elements Connect main features.
Datasources
Need a datasource not listed below? Tell us more about it.
Features | Implementation status | Comment |
---|---|---|
SQL Databases |
| Databases supported
|
Jira JQL | No out-of-the-box datasource yet. You can connect to the Jira REST API JQL endpoint by following this tutorial | |
Jira REST | No out-of-the-box datasource yet. You can connect to the Jira REST API by following this tutorial | |
LDAP | ||
REST APIs (URL) | ||
Microsoft Azure AD |
| No out-of-the-box datasource yet. You can connect to the Azure AD REST API by following this tutorial. |
Salesforce |
| |
Zendesk | ||
Files | ||
Jira SQL | Atlassian does not give access to Jira database on Cloud. However, the Jira REST API may fit your needs. You can connect to the Jira REST API by following this tutorial. |
Field types
Field type | Implementation status |
---|---|
Live text | |
Live user | |
Snapshot text | |
Snapshot date | |
Snapshot date time |
Field editors
Editor | Status |
---|---|
Autocomplete |
|
Read only | |
Select list | |
Multi Select list | |
Cascading select list | |
Table | |
Checklist | |
Radio button |
Dependencies
Dependency | Integration Status | Comment |
---|---|---|
Project | ||
User field | ||
Reporter | ||
Issue type | ||
Request type | ||
Text custom field | ||
Current User object | ||
Current issue key | ||
Reporter's organization |
Jira integration
Integration | Status | Comment |
---|---|---|
Set value from Jira Service Management portal | ||
Set value from Jira create issue screens | Jira does not allow apps to extend the Create issue screens. We are looking into ways to work around that limitation. | |
Edit from issue view |
| Edition is done in the issue view |
JQL search |
| Search is done on the mirror field |
Use Connected items in Jira Dashboards | The mirror field can be displayed in some dashboard charts | |
Post function: Set value | ||
Post function: Copy value |
Advanced field options
Feature | Status | Comment |
---|---|---|
Dynamic query | Dynamic queries can be configured | |
Edit queries & template | ||
Search query & template | ||
Cache | 5-minute non configurable cache for the datasource | |
Sort results | ||
Filter results |
Developers
Feature | Status | Comment |
---|---|---|
REST API | ||
Java API | Elements Connect code is running outside of your Jira instance, in our own servers. Therefore, you can't access Elements Connect Java API from your own scripts. The recommended way will be to use Elements Connect REST API when it will be available. |
More resources to help you plan your migration
Atlassian has published a dedicated Migration Resource Center with step-by-step guides, free tools, and dedicated support to assist you on your journey to Cloud.
Have specific questions about our app? Please reach out to our support team - they're here to help and advise.