Common Script Examples

The following chapter shows examples that can be used in any XDM script, that supports JavaScript or Groovy.

Executing a SQL Query

To access a database a JDBC connection is required. XDM offers parameters of type Connection for example a task stage hook parameter or a custom parameter which wrap a JDBC connection. Using the property jdbcConnection on the XDM connection object accesses the required JDBC connection.

A parameter of type connection is required. In this example the variable name of this parameter is connection.

  • Groovy

  • JavaScript

import groovy.sql.Sql;
def query = 'SELECT "Description" FROM "SCHEMA"."TABLE_1"'
Sql sql = new Sql(taskStageHook.connection.jdbcConnection)
sql.eachRow(query, {
    println("Output option 1: ${it.getString(1)}")
    println("Output option 2: ${it[0]}")
    println("Output option 3: ${it.Description}")
})

Find more information in the documentation on the Groovy SQL API

There are three different ways to access the column values:

  1. The first way is via the method getString(<columnIndex>) . This column index starts with 1.

  2. The second way is via the column index directly. Then the index starts with 0 because it is an array.

  3. The third way is via the column name.

    The it within the code is an implicit-created loop variable for the method eachRow().
importPackage(java.sql);
var query = 'SELECT "Description" FROM "SCHEMA"."TABLE_1"';
var prepareStatement = taskStageHook.myConnection.jdbcConnection.prepareStatement(query);
var resultSet = prepareStatement.executeQuery();
while(resultSet.next()) {
    print("Output option 1: " + resultSet.getString(1));
    print("Output option 2: " + resultSet.getString("Description"));
}

resultSet.close();
prepareStatement.close();

This example is built upon the Java JDBC API.

There are two different ways to access the column values:

  1. The first way is via the method getString(<columnIndex>) . This column index starts with 1.

  2. The second way is via the column name.

Calling a REST API

It is possible to call an external service from XDM scripts via a REST API.

As the Spring RestTemplate API is part of the XDM runtime environment, calling a REST API using the Spring library is a convenient way. Also, for many special requirements in authentication, certificates, using HTTP proxies etc. a solution can be implemented.

There is also a ModificationContext API method callRestEndpoint, which also relies on RestTemplate. This can be used for basic requirements. But typically, the approach to use RestTemplate directly allows to meet advanced requirements in a more convenient way.

This example calls a public REST API genderize.io, which gives an evaluation on the gender of a given name.

  • Groovy

  • JavaScript

import groovy.json.JsonSlurper
import org.springframework.http.HttpHeaders
import org.springframework.http.HttpEntity
import org.springframework.http.HttpMethod
import org.springframework.web.client.RestTemplate

def body = restCall("https://api.genderize.io/?name=john", "GET", null,
       [
           "Content-Type": "application/json",
           "Accept": "application/json",
       ]
    )
 print(body)
 var result = new JsonSlurper().parseText(body)
 print("The name  ${result.name} is with a probability of ${result.probability} of gender ${result.gender}")


def restCall(url, method, payload, headersMap) {

    def headers = new HttpHeaders()
    headersMap.each { entry ->
        headers.set(entry.key, entry.value)
    }

    def entity = new HttpEntity(payload, headers)
    println("Call REST Endpoint $url method: $method")

    def restTemplate = buildRestTemplate()
    def response = restTemplate.exchange(url, HttpMethod.valueOf(method), entity, String.class)

    return response.getBody()
}

def buildRestTemplate() {
    return new RestTemplate()
}
importClass(org.springframework.http.HttpHeaders)
importClass(org.springframework.http.HttpEntity)
importClass(org.springframework.http.HttpMethod)
importClass(org.springframework.web.client.RestTemplate)

var body = restCall("https://api.genderize.io/?name=john", "GET", null,
            {
                "Content-Type": "application/json",
                "Accept": "application/json",
            }
        );
print("Raw REST result:" + body);
var result = JSON.parse(body);
print("The name " + result.name + " is with a probability of " + result.probability + " of gender " + result.gender);

function restCall(url, method, payload, headersMap) {
    var headers = new HttpHeaders()

    for(var key in headersMap) {
        headers.set(key, headersMap[key]);
    }
    var entity = new HttpEntity(payload, headers)
    print("Call REST Endpoint " + url + " with method: " + method)

    var restTemplate = buildRestTemplate();
    var response = restTemplate.exchange(url, HttpMethod.valueOf(method), entity, Packages.java.lang.String.class)

    return response.getBody()
}

function buildRestTemplate() {
    return new RestTemplate();
}

Using an HTTP Proxy

If there are additional requirements on the HTTP connection to be established, this can be achieved by configuring the setup of the RestTemplate. For example, to use an HTTP Proxy use the following buildRestTemplate Method:

  • Groovy

  • JavaScript

//[...]
// add the following imports
import org.springframework.http.client.SimpleClientHttpRequestFactory
import java.net.Proxy.Type

//[...]

def buildRestTemplate() {
    def requestFactory = new SimpleClientHttpRequestFactory()

    def proxy = new Proxy(Type.HTTP, new InetSocketAddress("my.proxy.com", 8080))
    requestFactory.setProxy(proxy)

    return new RestTemplate(requestFactory)
}
//[...]
// add the following imports:
importClass(org.springframework.http.client.SimpleClientHttpRequestFactory)
importClass(java.net.Proxy.Type)

function buildRestTemplate() {
    var requestFactory = new SimpleClientHttpRequestFactory();

    var proxy = new Proxy(Type.HTTP, new InetSocketAddress("my.proxy.com", 8080));
    requestFactory.setProxy(proxy);

    return new RestTemplate(requestFactory);
}

Authentication with an XDM credential

It is also possible to use an XDM credential as a parameter and set up HTTP Basic authentication for the REST call:

  • Groovy

  • JavaScript

//[...]

def auth = new String(credential.user + ':' + credential.password).bytes.encodeBase64().toString()
var body = restCall("https://api.genderize.io/?name=" + firstname, "GET", null,
     {
         "Content-Type": "application/json",
         "Accept": "application/json",
         "Authentication": "Basic " + auth,
     }
)
print("Raw REST result:" + body)
var result = JSON.parse(body)
print("The name " + result.name + " is with a probability of " + result.probability + " of gender " + result.gender)
//[...]
var auth = new String(credential.user + ':' + credential.password).bytes.encodeBase64().toString()
var body = restCall("https://api.genderize.io/?name=" + firstname, "GET", null,
    {
        "Content-Type": "application/json",
        "Accept": "application/json",
        "Authentication": "Basic " + auth,
    }
);
print("Raw REST result:" + body);
var result = JSON.parse(body);
print("The name " + result.name + " is with a probability of " + result.probability + " of gender " + result.gender);

Doing a REST POST request

The restCall method described above can also be used to perform a POST request on a REST API:

  • Groovy

  • JavaScript

//[...]
def payload = [
"myKey": "myValue",
"myOtherKey": 12,
]
def body = restCall("https://echo.zuplo.io/", "POST", JsonOutput.toJson(payload),
[
"Content-Type": "application/json",
"Accept": "application/json",
]
)
//[...]
//[...]
var payload = {
    "myKey": "myValue",
    "myOtherKey": 12,
}
var body = restCall("https://echo.zuplo.io/", "POST", JSON.stringify(payload),
    {
        "Content-Type": "application/json",
        "Accept": "application/json",
    }
);
//[...]