Service invocation
The asset-integration-starter
project contains a
com.example.service.client.ExampleServiceClient
class to illustrate the
service invocation.
ExampleServiceClient
class obtains reference to the
SystemGateway
object for the system represented by an identifier
Foo by calling
SystemGatewayFactory.getSystemGateway
method with
Foo
as an argument.
SystemGatewayFactory.getSystemGateway
method thus gives a handle to
any target system by specifying its systemId. Once the handle is
obtained in terms of SystemGateway
object, it can be used to invoke any
service on the respective target system. The following is the corresponding code snippet
from ExampleServiceClient
class:private SystemGateway systemGateway = SystemGatewayFactory.getSystemGateway("Foo");
String systemId = executionContext.getSystemConfig().getIdentifier();
SystemGateway
The com.hcl.unica.system.integration.service.gateway.SystemGateway
provides an overloaded method executeService
, for executing any service
on the target system. One version of this method offers a way to execute any service
declared in service declaration files
(<ASSET_PICKER_HOME>/conf/custom-plugin-services.yml and
<ASSET_PICKER_HOME>/conf/plugin-services.yml) for the
respective system. And the other version offers a way to execute an ad hoc HTTP call on
the target system without declaring any explicit service for it in the service
declaration file. The following are the two versions of the
executeService
method with their signatures:
- <RQ, RS> RS executeService(String serviceName, RQ serviceInput, Class<?
extends ServiceGateway<RQ, RS>> gatewayClass) throws
ServiceExecutionExceptionThis is a generic method and works with the type parameters RQ & RS. The significance of RQ & RS is same as mentioned earlier. This method helps to execute an already declared service. The
invocationDemo
method inExampleServiceClient
class demonstrates the use of this method. It accepts the following arguments:- String serviceName
This must be the name of service to be executed. Name of the service must exactly match with its corresponding declaration in service declaration file.
- RQ serviceInput
This is an input to the service to be executed. The type parameter RQ represents the type of input required for the service being invoked.
- Class<? extends ServiceGateway<RQ, RS>>
gatewayClass
It must be same as the return value of
getServiceInterface
method in corresponding service implementation. It helps the Content Integration Framework to identify the right input for the service being executed and returns the output of desired type. The RQ and RS type parameters used forgatewayClass
argument represents the type of input supplied on service invocation and the type of response returned by the service on completion, respectively.
On successful completion, this method returns the object of type represented by the type parameter RS. Thus, the third argument to the
executeService
method,gatewayClass
, governs the type of input that goes into the service and the type of value that service returns. - String serviceName
- <T> HttpResponse<T> executeService(HttpRequest request, Class<T>
expectedResponse) throws ServiceExecutionExceptionThis is also a generic method, where the type parameter T represents the type of response expected out of the remote HTTP call. It helps to make an ad-hoc HTTP call to the target system without declaring an explicit service for it in service declaration file. The
adHocInvocationDemo
method in theExampleServiceClient
class demonstrates the use of this method. It accepts the following listed arguments:- HttpRequest request
This must be an object of
com.hcl.unica.system.model.request.HttpRequest
class.HttpRequest
provides a builder interface for constructing the object with required details. This object essentially encapsulates the details required for making an HTTP call, such as absolute URL, HTTP request method, HTTP request headers & HTTP request body or HTTP request payload. - Class<T> expectedResponse
This must tell the type of response expected from remote URL. Jackson and JAXB types can also be used. Deserialization of JSON/XML will happen automatically in such case.
On successful completion, this method returns the object
com.hcl.unica.system.model.response.HttpResponse
, encapsulating the response object from the remote call. The type of response encapsulated by theHttpResponse
will be the same as theexpectedResponse
argument to theexecuteService
method. TheHttpResponse
object gives access to the HTTP response status code, response headers, and response cookies, in addition to the response payload. - HttpRequest request
Both versions of the executeService
method can throw the
com.hcl.unica.system.integration.exception.ServiceExecutionException
or one of its subtypes if anything goes wrong during service execution. The object of
this exception can be consulted for the immediate cause of service execution failure.
Likewise, if the invoked service represents a REST/HTTP service (ad-hoc service
invocations are always HTTP calls), and the failure occurs out of HTTP interaction, an
optional HttpResponse
object can also be obtained from the exception.
In such cases, the HttpServiceExecutionException
is thrown by
the executeService
methods. The presence of
HttpResponse
depends on whether the HTTP interaction happened or
not. The HttpServiceExecutionException
might be received because of an
exception in any logic executed prior to the actual HTTP call, such as
buildRequest
method in a declared service.
The executeService
method can also throw a
SystemNotFoundException
if the plugin for the specified target
system is not present, or the corresponding system is not onboarded in Unica Platform.
Similarly, it can throw a ServiceNotFoundException if the specified service is either
not declared in service declaration file or not implemented by the plugin.
- You will observe that the type of the input to the
custom-service
is same as the type used for service implementation in thecom.example.service.rest.ExampleCustomService
class or thecom.example.service.functional.CustomService
class. The type of output is same as the one used for definingCustomServiceGateway
interface whose class object is returned fromgetServiceInterface
method in both versions ofCustomService
implementations. - The
com.example.service.rest.ExampleCustomService
class and thecom.example.service.functional.ExampleCustomService
class represents the same service implemented with two different approaches. The service declaration files inasset-integration-starter
project namely the META-INF/rest-content-services.yml and the META-INF/functional-content-services.yml have an entry forcustom-service
pointing to the respective versions of thefactoryClass
. These two versions are provided only for illustration purpose. For all practical purposes, only one version of the service implementation is expected by the Content Integration Framework. Irrespective of the approach used for service implementation, the method for service invocation remains the same.
Multi-partitioned clients
From the perspective of service implementation, the ExecutionContext
and SystemConfig
objects, passed to various callback methods,
contain client application and partition specific information. And from the
perspective of service invocation, services executed using
executeService
method, from the SystemGateway
class, runs against the system configured for the right client application and the
partition of the user accessing Unica Content Integration. Hence, neither the
implementation nor the invoker need to work with partitioning and other contextual
details, explicitly. Content Integration Framework
handles it automatically.