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"

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


(lightbulb) 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 w

             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")
GROOVY

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.


(lightbulb) 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 

    • Export your Jira tickets using the CSV exporter - the CSV file generated will be used to import your data in the next step.

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

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.

FeaturesImplementation statusComment
SQL Databases

(tick) Available

Databases supported (tick)

  • Microsoft Azure SQL Database
  • Microsoft SQL Server
  • MySQL
  • Oracle Database (Service identification)
  • PostgreSQL
Jira JQL(warning) Partly available

No out-of-the-box datasource yet.

You can connect to the Jira REST API JQL endpoint by following this tutorial

Jira REST(warning) Partly available

No out-of-the-box datasource yet.

You can connect to the Jira REST API by following this tutorial

LDAP(error) Unavailable
REST APIs (URL)(tick) Available


Microsoft Azure AD

(warning) Partly available

No out-of-the-box datasource yet.

You can connect to the Azure AD REST API by following this tutorial

Salesforce

(error) Unavailable


Zendesk(error) Unavailable
Files(error) Unavailable
Jira SQL(minus) Not possible

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 typeImplementation status
Live text(error) Unavailable
Live user(error) Unavailable
Snapshot text(tick) Available
Snapshot date(error) Unavailable
Snapshot date time(error) Unavailable

Field editors

EditorStatus
Autocomplete

(tick) Available

Read only(tick) Available
Select list(tick) Available
Multi Select list(tick) Available
Cascading select list(tick) Available
Table(error) Unavailable
Checklist(error) Unavailable
Radio button(error) Unavailable

Dependencies

Jira integration

IntegrationStatusComment
Set value from Jira Service Management portal(tick) Available
Set value from Jira create issue screens(minus) Not possibleJira does not allow apps to extend the Create issue screens. We are looking into ways to work around that limitation.
Edit from issue view

(tick) Available

Edition is done in the issue view

JQL search

(warning) Partly available

Search is done on the mirror field
Use Connected items in Jira Dashboards(warning) Partly available
The mirror field can be displayed in some dashboard charts
Post function: Set value(error) Unavailable


Post function: Copy value(error) Unavailable

Advanced field options

FeatureStatusComment
Dynamic query(warning) Partly availableDynamic queries can be configured
Edit queries & template(error) Unavailable
Search query & template(error) Unavailable
Cache(tick) Available5-minute non configurable cache for the datasource
Sort results(error) Unavailable
Filter results(error) Unavailable

Developers

FeatureStatusComment
REST API(warning) Partly available
Java API(minus) Not possibleElements 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.