External Callout
Dynamic logic configured for integration steps can perform callouts. From a configuration perspective this leverages the information that is contained in a Destination record. Effectively the attributes addressKey and credentialKey are used. Then from a piece of Groovy dynamic logic, one can initialize a callout by invoking the webTarget predefined method. This method takes the identifying code of a configured destination as input, returning a JAX-RS WebTarget instance. This WebTarget instance can then be used to further construct the actual callout.
webTarget and configuration elements
As mentioned in the introduction there are two specific elements of a Destination configuration that are of importance for callouts.
-
addressKey
This holds a value for which an OHI System Property needs to be defined, that specifies the base segment of the URI from which a complete address is to be formulated. As an example, say the value is configured to be "address.key.policies.application", there needs to be a OHI System Property defined at runtime that maps this key (e.g. a property value of: http://machine:8090/policies/<context-root>"). Please note, for OHI applications, the URL value should be at least till the context root of the application. * credentialKey
This holds a value that is used to obtain a cached JAX-RS client for which an applicable authentication mechanism is activated. In case the configured destination does not specify a value for this credentialKey, this means that no authentication mechanism is used for the callout. On the other hand when a value __is__ specified, an authentication mechanism is set up that matches the OHI System Property value that is defined for: "ohi.service.<credentialKey>.client.authentication".
Traversing Location header through webTarget
Typically when you use a <tt>webTarget</tt> in a POST action to create a resource, a system responds with a HTTP Response code of 201 (Created) and sends back a Location header of that new resource. Now if you want to traverse that Location header link whilst leveraging destination (and credential information), you can use the overloaded webTarget function of <tt>webTarget(<destination code>, <location header>)</tt>. When invoking this function the system will check whether the presented <tt>location header</tt> matches the base URL that is referenced by the <tt>destination code</tt>. When these match a new WebTarget is returned that you can use, if not null is returned.
Examples
This section provides some examples about the external call-out mechanism.
These examples highlight the mechanism and protocol that is currently provided for by default by this module; JAX-RS Client API.
1) Issuing a GET request to a configured destination having the code "destination_remote". The URL has an additional path parameters abc. Response is a xml. The example uses XMLSlurper to parse the response and sets the result on 'a' field of a policy object. Response is:
<root someField='someValue'/>
String response = webTarget("destination_remote")
.path("abc")
.request()
.buildGet()
.invoke()
.readEntity(String.class)
def result = new XmlSlurper().parseText(response)
policy.someField = result.@someField
2) Issuing a GET request to a configured destination having the code "destination_remote". The URL specifies a query parameter "code" as an input. Response is the same query parameter value.
result = webTarget("destination_remote")
.path("abc")
.queryParam("code","ABC")
.request()
.buildGet()
.invoke()
.readEntity(String.class)
3) Issuing a GET request to a configured destination having the code "destination_remote". The URL specifies a header parameter.
result = webTarget("destination_remote")
.path("abc")
.request()
.header("accept","application/xml;test=HeaderProperty")
.buildGet()
.invoke()
.readEntity(String.class)
4) Issuing a PUT/POST request to a configured destination having the code "destination_remote". It takes in XML as an input. This example sets the response as is on 'a' field of a policy object.
def writer = new StringWriter()
def xml = new groovy.xml.MarkupBuilder(writer)
xml.ServiceCategoryRequest(version:4) {
policyCode( policy.code )
someField ( policy.someField )
}
String response = webTarget("destination_remote")
.request()
.header("Accept","application/xml")
.buildPut(Entity.xml(writer.toString()))
.invoke()
.readEntity(String.class)
policy.calloutField = response.toString()
5) Using a returned Location header from a WebTarget POST operation.
newResourceLocation = webTarget("destination_remote")
.request()
.buildPost(Entity.text("Hello World!"))
.invoke()
.getLocation()
newResourceLocationData = webTarget("destination_remote", newResourceLocation)
.request()
.buildGet()
.invoke()
.readEntity(String.class)
6) Issuing a PATCH request to a configured destination having the code "destination_remote". It takes in XML as an input. This example sets the response as is on 'a' field of a policy object.
def writer = new StringWriter()
def xml = new groovy.xml.MarkupBuilder(writer)
xml.ServiceCategoryRequest(version:4) {
policyCode( policy.code )
someField ( policy.someField )
}
String response = webTarget("destination_remote")
.request()
.header("Accept", "application/xml")
.build("PATCH", Entity.xml(writer.toString()))
.invoke()
.readEntity(String.class);
policy.calloutField = response.toString()