Transformation Spec

In the Universal Adapter, the transformation spec performs a vital role in syncing data between two applications. It acts as a dedicated channel between an external application and ConnectALL. Further, it converts the message to a readable format in the respective destination applications – whether it's a request from ConnectALL or a response. Jolt and Groovy are the two languages that are supported in ConnectALL for the implementation of a transformation spec.  

A transformation spec is mandatory in a Universal Adapter. In its absence, you cannot enable an app-link (that has a universal adapter).

Given below are examples that illustrate how to implement the transformation spec using Jolt and Groovy in ConnectALL.

Example 1 – Creating a record in Jira with the help of transformation spec to build a suitable format from an unreadable format for Jira.

Type : Jolt

Template : CREATE RECORD

Input

Transformation Spec

Output

{
"fields": {
"summary": "Test for API creation",
"description": "Test for API creation",
"priority": "1",
"modifiedTime": "01-04-2019 11:46:30.124",
"severity": "2",
"status": "Open"
}
}
[
{
"operation": "shift",
"spec": {
"fields": {
"summary": "fields.summary",
"description": "fields.description",

 "priority":"fields.priority.id"

}
}
},
{
"operation": "default",
"spec": {
"fields|value": {
"project": { "key": "TP" },
"issuetype": { "id": "10102" }
}
}
}
]
{
"fields": {
"summary": "Test for API creation",
"description": "Test for API creation",
"priority": {
"id": "1"
},
"issuetype": {
"id": "10102"
},
"project": {
"key": "TP"
}
}
}

In the above example, the output of the spec is the input of the destination. 

Implementing a Spec

It is important to understand a spec completely. Note that a spec is implemented solely based on the expected input or output between ConnectALL and the destination application.
In the above example, under the fields summary, description, and priority, the spec format of each field depends on the expected input and output. Let us discuss in detail what this means.

The "key: value" pairs in the spec denote the format of the field's expected input (i.e. key) and output (i.e. value).


"fields": {
"summary": "fields.summary",
"description": "fields.description",
 "priority":"fields.priority.id"
}

In the above code snippet, lines 2 through 4, the "key" on the left side before the colon ( ':' ) denotes the expected input format. This tells ConnectALL to look for "summary", "description", and "priority" fields in the input.

On the right side (after the colon) is the desired output format. This example tells ConnectALL to output "fields.summary", "fields.description", and "fields.priority.id".

JOLT Operations:

Operation shift: Copies data from input to the output tree.

Operation default: Applies default values to the tree. Thus, in our example, it is appended at the end of the fields in the output.

Operation Modify-overwrite-beta: Writes calculated values to the output. Example operations: toLower, toUpper, concat, min/max/abs, toInteger, toDouble, toLong.

Testing the Spec: The spec script can be tested and debugged using ConnectALL transformation spec test script page or https://jolt-demo.appspot.com/#inception by providing an appropriate input.


Example 2

Type : Groovy

Template : CREATE RECORD

Input

Transformation Spec

Output

{
"fields": {
"summary": "Test for API creation",
"description": "Test for API creation",
"priority": "1",
"modifiedTime": "01-04-2019 11:46:30.124",
"severity": "2",
"status": "Open"
}
}



import groovy.json.JsonSlurper
String getpayload = payload;
JsonSlurper slurper = new JsonSlurper();
Map parsedJson = slurper.parseText(getpayload);
String summaryValue = parsedJson.fields.summary;
String descriptionValue = parsedJson.fields.description;
String priorityValue = parsedJson.fields.priority;
String modifiedTimeValue = parsedJson.fields.modifiedTime;
String severityValue = parsedJson.fields.severity;
String statusValue = parsedJson.fields.status;
String parsedvalue = '''{ "fields": { ''' +
''' "summary": ''' + ''' " ''' + summaryValue + ''' " ''' + ''' , ''' +
''' "description": ''' + ''' " ''' + descriptionValue + ''' " ''' + ''' , ''' +
''' "priority": ''' + '''{"id": "''' + priorityValue + '''"''' + ''' }, ''' +
''' "issuetype": {
"id": "10102" } ''' + ''' , ''' +
''' "project": {
"key": "TP"
} ''' +
''' } ''' +
''' }''';
return parsedvalue;
{
"fields": {
"summary": "Test for API creation",
"description": "Test for API creation",
"priority": {
"id": "1"
},
"issuetype": {
"id": "10102"
},
"project": {
"key": "TP"
}
}
}

In the above example, the output of the spec is the input of the destination. Similar to Jolt, in Groovy also, you have to implement a script based on its expected input and output. So, the format of the fields has to match the destination.

Here, the payload is equal to the input of the Spec, and using JsonSlurper class, parse the payload based on the hierarchy of a particular field.

Testing the spec: Using the Groovy console, the spec can be tested and debugged as well.


Example 3 - Modify the query

Type : Jolt

Template : QUERY MODIFIED RECORDS

Input

Transformation Spec

Output

{
  "metadata": [
    {
      "project": {
        "id": "SP",
        "name": "Sample"
      }
    },
    {
      "issuetype": {
        "id": "10001",
        "name": "Bug"
      }
    }
  ],
  "queryFilter": "",
  "queryFields": [
    "summary",
    "description",
    "assignee",
    "priority",
    "reporter"
  ],
  "fromDate": "01-04-2019 11:46:00.000",
  "toDate": "01-04-2019 11:48:00.000"
}
[
  {
    "operation": "modify-overwrite-beta",
    "spec": {
      "updated": "=concat('\"',@(1,fromDate),'\"')"
    }
  }, {
    "operation": "modify-overwrite-beta",
    "spec": {
      "metadata": {
        "*": {
          "project?": {
            "jql-project": "=concat('project=',@(1,id))"
          },
          "issuetype?": {
            "jql-issuetype": "=concat('issuetype=',@(1,id))"
          }
        }
      },
      "jql-updated": "=concat('updated>=',@(1,updated))"
    }
  },
  {
    "operation": "shift",
    "spec": {
      "metadata": {
        "*": {
          "@project.id": "project",
          "@issuetype.id": "issuetype",
          "@project.jql-project": "jql-project",
          "@issuetype.jql-issuetype": "jql-issuetype"
        }
      },
      "queryFields": "queryFields",
      "jql-updated": "jql-updated"
    }
  }, {
    "operation": "shift",
    "spec": {
      // match the rest using the * wildcard.
      "jql-*": "jql.&(0,1)",
      "queryFields": "queryFields"
    }
  }, {
    "operation": "shift",
    "spec": {
      // match the rest using the * wildcard.
      "jql": {
        "*": "jql"
      }
    }
  }, {
    "operation": "modify-overwrite-beta",
    "spec": {
      "jql": "=join(' and ',@(1,jql))"
    }
  },
  {
    "operation": "default",
    "spec": {
      "maxResults": 100
    }
  }
]
{
  "jql": "project\u003dSP and issuetype\u003d10001 and updated\u003e\u003d\"01-04-2019 11:46:00.000\"",
  "maxResults": 100
}


Note: For further information on Jolt, click here.