Posted Apr 12 by Rhys Evans.
Updated Apr 14.

AppWorks services are server-side applications that typically provide support for AppWorks managed mobile applications (AppWorks apps), forming part of a wider mobile solution. They are deployed by the AppWorks Gateway within its host container (Apache Tomcat 8) along with the aforementioned apps. They are built using the AppWorks Service Development Kit (SDK).

Last activity Apr 14 by Rhys Evans.
6861 views. 0 comments.

OpenText AppWorks 16 Service Development Kit

AppWorks services are server-side applications that typically provide support for AppWorks managed mobile applications (AppWorks apps), forming part of a wider mobile solution. They are deployed by the AppWorks Gateway within its host container (Apache Tomcat 8) along with the aforementioned apps.

AppWorks services are written in Java (Java 8) using standard Java web technology (Servlets, etc.). They are structured in the same way as a standard Java WAR (Web application archive), utilizing WEB-INF/web.xml to configure the web application when deployed. Details on the structure and requirements for an AppWorks service are discussed in the service checklist section.

AppWorks services can also be used independently, they do not need to be part of a mobile solution at all. They are as flexible and useful as you wish to make them. Java has a rich well established eco-system to exploit, and AppWorks services can be strategically deployed in key positions within your OpenText solution architecture.

Who should read this?

This document is primarily aimed at developers looking to implement an AppWorks service, but can also be useful to product managers interested in evaluating the AppWorks platform.

  • Perhaps you have an existing product that exposes web services that you now want to be consumed from a mobile application in a RESTful manner.
  • Perhaps you have multiple existing products in a customer deployment and want to combine their resources (web services + REST APIs + whatever else…) to provide a consolidated API (façade).
  • Perhaps you are developing a new product and want to build in mobile capabilities up-front.
  • Perhaps you have existing mobile applications and want to standardize on a supported OpenText platform to ease future development and deployment concerns.

AppWorks Service Platform

The AppWorks service platform has a number of wider concepts that should be discussed before diving into the details of the code. The AppWorks Service Devleopment Kit (SDK) is explored in full later in its own section. The SDK code can be found on GitHub here. The SDK is also available via the Maven Central Repository, please use the following dependency entry for the 16 release.

<dependency>
   <groupId>com.opentext.otag.sdk</groupId>
   <artifactId>otag-service-development-kit</artifactId>
   <version>16</version>
   <scope>provided</scope>
</dependency>

Note:
A <scope> of provided is used as AppWorks provides the libraries during deployment.

Some of the AppWorks 16 service fundamentals are found in this section, so it is definitely worth reading at least once even if you are familiar with AppWorks as some things differ from the previous versions.

The minimum requirements for an AppWorks service are discussed in detail next. Some of the concepts may seem unfamiliar, but links to the relevant sections of the document are included.

AppWorks Service Checklist

The following is a complete list of the requirements for your AppWorks service to be considered valid for deployment by the AppWorks Gateway. The Gateway will reject artifacts that do not meet these requirements.

The requirements are minimal, in keeping with the original intention of giving the developer as much flexibility as possible when working with the AppWorks platform.

A summarized version of this section is included for reference in the appendices, please see Appendix D: AppWorks Service Checklist Cheat Sheet.

Artifact name

The service artifact must be named in the following format,

name_{numeric.separated.version}.zip

There are no restrictions on the number of “components” (major.minor.hotfix.etc…) that make up the version, but they will be compared by the AppWorks Gateway to determine whether an upgrade or downgrade is being performed.

The following are all examples of valid artifact names:

myService_1.zip
myService_1.2.0.zip
myService_11.2.33.68.zip

app.properties

The app.properties file should be at the root of the AppWorks service zip file. It should indicate that it is an AppWorks service by setting the type=service, and any required configuration settings are also added. The version in particular must match that specified in the artifact name, and there is a minimum set of required properties to be aware of as described in the Service Meta-Data section below.

A template file is available on request, and the full AppWorks service example we provide contains a fully formed app.properties file.

Dependencies

The SDK and associated JAR files contain the code and tools required to develop an AppWorks service. They can be optionally included in the lib folder of the Service zip artifact WEB-INF/lib/. When the Gateway deploys a Service, it actually provides these dependencies, so it is better to omit them to reduce the overall size of the artifact you upload. The individual JAR files and full Javadoc are available for development purposes.

When the JAR files are omitted, the Gateway will catch any inconsistencies in the versions of the classes/JARs the Service was compiled against from those being used by the Gateway the Service is being deployed to.

Note:
The version of the Gateway, SDK, and associated JAR files must match.

The otag-service-context-16.jar JAR contains tooling to manage the services local context, including the component management features for the AWComponentContext.

The otag-service-development-kit-16.jar JAR contains the classes and tools used to leverage the Gateway's dedicated support for AppWorks services. Including the full set of types required to use the SDK.

Warning:
Do not add the SDK and associated JAR fils to Tomcat's {tomcat_home}/lib/ folder. Doing so will prevent the Gateway and your AppWorks service from working correctly.

Service Deployment

You must supply a single method within one of your classes that is annotated with @AWServiceStartupComplete, which reports the outcome of the deployment as either good or bad. Our provided ServiceClient has a convenient completeDeployment method to carry out this required task. The service will not be enabled by the AppWorks Gateway until we know the deployment has completed successfully.

The AppWorks Gateway User Interface provides deployment monitoring features that will report the status of your service deployment in the Gateway.

The service deployment procedure is described in detail in Appendix A.

Service Structure

The service artifact should be structured in the same way as a standard Java WAR file.

AppWorks Service Root
| app.properties
| icon.png
|_ WEB-INF
    | web.xml
    |_ classes
    |   | log4j.properties
    |   |_ ??? *.class [your packages]
    |_ lib
        ??? *.jar [your libraries]

Service Meta-Data

The Gateway needs information about your AppWorks service in order to deploy it and validate the contents of the supplied Service zip file. Developers are expected to provide this information in the app.properties file.

This app.properties file must reside at the root of the service zip file. The file must also contain the following mandatory properties, but can be used for extended functionality such as creating configuration settings, which is discussed in detail later.

app.properties required fields:

  • displayName=<name> Name that appears in the admin UI title
  • description=<desc> Description shown in the admin UI and on devices
  • version=16.n.n... The version number of the app
  • type=[app|service|component|eimconnector] The type of the service
  • awgPlatformVersion=16

Note:
The version supplied in the app.properties must match the version supplied in the file name, as described in the Service Checklist section.

Note:
The awgPlatformVersion is given as a period separated numeric string. The minimum acceptable version for this release is 16. This prevents legacy Apps and Services that are not compatible with the AppWorks Gateway 16 release from being installed.

Note:
This set of properties is also required in an AppWorks apps app.properties file. In fact, all deployable artifacts need to include app.properties with these minimum details.

The app.properties file can also be used to internationalize certain properties that are displayed to end users in the AppWorks Gateway UI using i18n syntax. For example, the displayName and description could be configured as shown below:

displayName.de=Testanwendung
description.de=Meine Testanwendung
displayName.ja=???????????
description.ja=?????????????
displayName.ru=Test Application
description.ru=??? Test Application
displayName.zh-Hans=??????
description.zh-Hans=????????
displayName.zh-Hant=??????
description.zh-Hant=????????

Configuration Setting Management

AppWorks services may need a number of configuration parameters depending on what the Service actually does. Common uses for settings include:

  • collaborating service URLs
  • service/database credentials (password type fields are supported)
  • HTTP client configuration, socket timeout values, logging modes
  • thread pool sizes, worker intervals

These settings are stored by the Gateway and can be edited from the AppWorks Gateway's UI when the service is deployed.

Note:
The service settings are retained when the service is uninstalled and will be re-instated in the case where the service is reinstalled at a later date.


An example of a service that has a number of different kinds of settings

Setting Creation

Configuration settings can be created for you using the app.properties file, or you can use our supplied SettingsClient to do this work. The app.properties file doesn't give you as much control over the resulting settings individual fields, but it is very convenient.

Each setting can be defined with the following syntax:

<setting-name>.type=[string|password|multiline|integer|bool|json]
<setting-name>.displayName=<setting display name>
<setting-name>.descriptions=<desc>
<setting-name>.default=<default value>
<setting-name>.seqNo=n (defines placement in UI)
<setting-name>.readOnly=[true|false]

Note:
If you wish to use the settings created via app.properties with an SDK settings handler then the <setting-name> must not contain periods (.). Use mySetting instead of my.setting.

An example of the relevant section from an app.properties file, that is specifying the property named url is shown below:

url.type=string
url.displayName=My URL
url.description=My description
url.default=
url.seqNo=1
url.readOnly=true|false

On deployment of an AppWorks service, each setting contained in the app.properties file will be created if it doesn't already exist. The setting id, or key as it is known, will be created using the name provided for the app from the artifact name name_version.zip and the property name value in the app.properties file.

For example, if the service zip was named myService_1.1.58.zip, the above sample would create a new setting with a key of myService.url.

Note:
If you wish to manually remove the settings stored by a particular AppWorks service from the Gateway's database then use the appName column of the Settings table to do so easily.

The properties in the app.properties file are used as follows:

  • type defines not only the kind of data but how the setting will be presented to a user.
  • displayName and description are presented to mobile users in the case of apps, and to the Gateway administrators within their respective UIs.
  • default property allows you to set an appropriate default value.
  • seqNo [optional] allows you to order the settings when they are presented in the AppWorks Gateway UI.
  • readOnly [optional] flag is used to present a disabled HTML input field in the AppWorks Gateway UI. API clients can change this value as they please.

The settings that are created can then be edited from the AppWorks Gateway UI. The setting type is interpreted as follows.

  • string plain text HTML input
  • multiline HTML text area provided
  • password password HTML input provided
  • bool HTML checkbox
  • integer number type HTML input
  • json free form JSON text in an HTML text area

Because editing the service's configuration settings happens in the AppWorks Gateway UI, we need a way to keep the service informed of the changes. The AppWorks service is an independent web application after all. The SDK supplies the SettingChangeHandler and MultiSettingChangeHandler for this exact reason.

Non-Service related properties

The app.properties file is used by AppWorks apps as well as services. The isAvailableOffline flag is used by the AppWorks mobile clients to control the behavior of the AppWorks apps they host. If set to false the AppWorks mobile client will prevent the AppWorks app from being used when it loses connectivity.

isAvailableOffline=[true|false]

Logging

The SDK tooling makes use of the SLF4J logging façade http://www.slf4j.org. You need to include the appropriate binding jar for your chosen implementation if you want to see output from the SDK classes.

In order to constrain service developers in the least way possible, SLF4J was a natural choice as it is compatible with a number of popular logging frameworks.

AppWorks Service Development Kit (SDK)

One of the aims of the AppWorks Gateway platform is to aid in the development of solutions that integrate with other OpenText products. The AppWorks SDK attempts to fulfil the server-side part of this promise by providing a set of Java-based tools that allow developers to quickly build the pieces of their application that work with the Gateway and the services it offers.

The tools are intended to be as lightweight as possible, with their set of dependencies carefully considered. We want to encourage innovation by letting developers do what they need to do with minimal interference and platform buy-in. The service checklist provides information on the minimum requirements of an AppWorks service.

Javadoc documentation is available for the AppWorks SDK, and there is an accompanying sample AppWorks service project. The project utilizes the supplied tooling (classes/interfaces/annotations), and can be used as a template to bootstrap your AppWorks service development.

Service to Gateway Communication

AppWorks services act independently for the most part, fulfilling the needs of their clients, but sometimes they carry out these responsibilities with the aid of the Gateway. The Gateway offers a set of dedicated APIs for this interaction. It covers authentication, service configuration management, push notifications, and even email.

The Gateway however must also exert control over a deployed AppWorks service. It is actively managing access to the deployments and it must also keep a Service informed of some of the things happening within the Gateway. Messages are passed to AppWorks services from the Gateway over HTTP. In these instances, the Gateway is telling the service something, usually how to behave, or sometimes that an event of interest has occurred.

Please see Appendix B for a visual representation of the Gateway and AppWorks service communication.

We therefore have a natural division within the SDK. For service requests, there are classes that developer's just instantiate, our AppWorks Service Clients. For example, we can directly retrieve a configuration setting my.setting.key:

SettingsClient settingsClient = new SettingsClient();
Setting mySetting = settingsClient.getSetting("my.setting.key");

For Gateway to Service communications, there are classes that AppWorks service developers create that respond to messages from the Gateway. Provide an implementation like this in order to receive notifications upon settings being changed:

Public class MyHandler implements SettingChangeHandler {
  ...
  @Override
  public void onSettingChanged(SettingsChangeMessage message) {
    // do something with the updated value
  }
  ...
}

Gateway to Service Communication

Messages passed to a deployed AppWorks service may be control messages, such as the enable/disable message, or informational messages such as telling the service that one of the configuration settings it is interested in has been updated by an administrator in the AppWorks Gateway UI. Message resolution and handling/routing is taken care of by a dedicated management agent we deploy alongside the AppWorks service we are given.

Note:
As mentioned previously, we ask that a web.xml file is included in your service and that it is actually used. We do not support web.xml-less (programmatically configured) applications, and will actually augment the web.xml file provided with security, communications, and monitoring features by injecting the management agent mentioned.

To respond to the Gateway when it is trying to tell our AppWorks service something, the SDK provides interfaces, annotations, and abstract implementations of message handlers that service developers can implement/extend. The AppWorks SDK will register these handlers with the management agent (and the managing Gateway) on the developer's behalf allowing their service to react accordingly. More on this information is presented in the AWComponent section later.

AppWorks Service Clients

com.opentext.otag.sdk.client

AppWorks Service Clients are HTTP clients that talk to a dedicated section of the AppWorks Gateway's APIs. The Deployments Service API, as it is known, deals exclusively with servicing the requests that come from AppWorks services that are being managed. It does not deal with requests from users/mobile clients/etc.

This API is protected using its own authentication mechanism, whereby management meta-data is written to the service's configuration files when the service is installed. This writing is performed by the managing Gateway itself within the same container (Tomcat instance). This meta-data is created per service deployment, not per service, because the Gateway and therefore the services within it may be deployed in a clustered fashion. If this is the case then the service will be automatically deployed at each node.

As the Gateway manages AppWorks Service Client access, the Gateway must be started and ready before the Service Clients can be used. Service Clients will typically throw an Exception if instantiated before the Gateway is ready. Creation should occur in an onStart method within your service, or in the single AWServiceStartupComplete method. Please review Appendix A for a visual representation of the deployment process.

Details of the request and response are embedded in each response type returned by the AppWorks Service Clients to aid in debugging. An appropriate checked Exception will be thrown by the Service Clients in the case of an error, the Exception will also contain relevant debugging information.

Provided Clients

AppWorks Service Clients make use of the dedicated API mentioned above (v3 in the AppWorks Gateway 16 release) and are guaranteed to work correctly with a specific version of the Gateway API. The Service Clients make use of the supplied management meta-data written into the deployment to initiate secure communications with the Gateway. The clients are usually instantiated by an AppWorks service developer in their code for use by their own service classes. The Service Clients retains no state apart from the connection meta-data so can be deployed as singletons and made highly available if needs be.

Note:
Although a full constructor is available for each of the clients provided please use the default no-args constructor, this will derive the required information to initiate communications. The Gateway provides these details on installation of the service as mentioned above.

The full constructor should only be used in tests, allowing you to mock out the management meta-data resolution and even HTTP client.

We provide a number of clients out of the box.

AuthClient

The AuthClient is useful for authenticating requests a service receives using the Gateway's auth mechanism. This also allows registration of custom auth handlers.

MailClient

Makes use of the Gateway's managed SMTP connection where emails can be sent in a fire-and-forget fashion or can await the response of the SMTP server being used.

NotificationsClient

Sends notifications to connected users/clients using the Gateway, which includes native push notifications. See the Push Notification section below for details on the client and how this feature works.

ServiceClient

Management functions allow a service to relay the outcome of its deployment to the Gateway (success/failure + message). This is mandatory. For details, see the @AWServiceStartupComplete section below. We can also use this client to grab the available EIMConnectors etc.

SettingsClient

Services can manage their own configuration settings. The client provides creation and update facilities and it also allows a service to register interest in a setting's value. Therefore, the Gateway will relay any changes. Handling changes are a separate activity.

RuntimesClient

Provides access to the Runtimes registered with the Gateway. Runtimes represent client applications that interact with the Gateway. They identify their users to the Gateway with their Runtime name during the authentication process. Examples of Runtimes include the AppWorks iOS client and the AppWorks Android client. Administrators may choose to limit access to apps and services to specific Runtimes.

TrustedProviderClient

Allows a service to create and retrieve trusted provider (API) keys on behalf of an EIM (Enterprise Information Management) system that wants to use a limited subset of the Gateways APIs. This concept is discussed more detail the Trusted Providers sections below.

Note:
A utility class is included in the SDK to provide instant centralized access to all of the AppWorks Service Clients com.opentext.otag.sdk.client.GatewayClientRegistry. Call the static init method when your service starts and the registry will be available in the component context for use by your Service classes.

Push Notification Services

One of the new features added to the AppWorks platform in this release is native push notification support for iOS and Android. Notifications can be delivered directly to AppWorks apps running within the AppWorks mobile clients through the Gateway. We support sending these notifications from the SDK as well as the Gateway's administration REST API. This section offers some general information about this feature and hopes to set developers expectations.

Please see Appendix B for an overview of the implementation.

Note:
A test page is available in the Gateway administration console to send push notifications to connected clients. This page allows you to set the content of the notification, and even target an AppWorks App, passing it a JSON payload if you so wish.

AppWorks Support for Push Notifications

The AppWorks push notification feature makes use of the Google Cloud Messaging (GCM) service. Details are available at Google Cloud Messaging Services . This service is used as an intermediary between the AppWorks Gateway and the connected AppWorks mobile clients. Messages bound for mobile clients are sent from the Gateway to the GCM service, which in turn sends them to the clients listed in the request issued from the Gateway.

This implies that the GCM service is aware of both the AppWorks Gateway and the mobile clients, which is actually true. The AppWorks mobile clients (iOS and Android) automatically register with the GCM service, indicating that the Gateway is the 'server' they are interested in receiving messages from. They receive a token from the GCM service, which they pass to the Gateway. The Gateway then uses this token if it is asked to send a notification to this particular client.

Push Notification Requests

The SDK offers the ClientPushNotificationRequest type, which can be passed to the com.opentext.otag.sdk.client.NotificationsClient#sendPushNotification method in order to send a push notification request. We must however identify the notifications recipient/s, and are given the following options as part of the request.

Client Ids

If we know the identifier of the client, this can be retrieved using the Gateway's administration API. Typically the user search is used as it allows us to associate a user with the physical client.

User IDs

The username used by the client when it is connected to the Gateway and provided its GCM token. We take the provided IDs and cross reference them against OTDS to aid in our location of the client details (GCM token).

OTDS (Open Text Directory Services) Group IDs

OTDS group IDs may be passed in the request. The usernames associated with those groups will then be combined with those passed in 'User IDs' in order to resolve connected clients.

Runtime IDs

We can send a notification to all clients that are using a particular Runtime. The RuntimesClient allows you to retrieve the available Runtimes. AppWorks app audiences can be set using Runtimes, which useful to send to a particular audience.

The broadcast option will send the notification to all clients that are connected to the Gateway. We keep track of the last communication from any given client, and clients that have not contacted the Gateway within the last six months are not included in the broadcast.

Targeted Payload

As mentioned, push notifications can be targeted at specific AppWorks Apps running inside of an AppWorks mobile client. A custom JSON payload can be passed directly into the application allowing it to react to the content of the message. The details around implementing such an AppWorks App are outside the scope of this document. The AppWorks mobile (JavaScript) framework, appworks.js, is publically available on GitHub and the specific section on notification handling can be found here.

AppWorks Components

Before moving onto the AppWorks handlers, it's worth discussing their super-type, the AWComponent. AppWorks Components are created by AppWorks service developers and are simply classes that implement the AWComponent marker interface.

In general, these components (handlers) are picked up automatically by the agent we use to manage the AppWorks service, where we instantiate a single instance of each type and place it in the AWComponentContext, which is discussed next. As the framework (injected management agent) is responsible for creating the AppWorks components, we ask that a default no-argument constructor is supplied.

The AWComponentContext does however permit developers to inject their components at runtime using the AWComponentContext#add method. There is no limitation of the constructors these component classes use because the developer, not the framework, is responsible for creating them.

The processes described here can be seen in the AppWorks service Deployment Flow Chart found in Appendix A.

Astute readers will realize that the component context is a home for Singleton instances. The components deposited within should therefore be stateless or be able to manage concurrent access (Thread-safe).

AWComponentContext

The component context provides a very lightweight registry mechanism that allows service developers to access the AWComponents they create from anywhere inside of their Service, which is isolated to the ClassLoader for their particular service.

As the component context is populated with handlers before the service startup message is passed (see AWServiceContextHandler#onStart) the instances of the components will be available on start. An instance of any component can be retrieved directly using:

AWComponentContext#getComponent(java.lang.Class<T>)

Components can be looked up using their class, like a simplified version of the application context provided by Dependency Injection frameworks such as Spring and Google Guice. This means that you will overwrite an entry if you add an entry for a class that has already been stored in the component context.

As mentioned, the component context allows retrieval from the class directly or you can ask it for all classes that implement a certain type. For example, give me all of the settings handlers using:

AWComponentContext#getComponents(java.lang.Class<T>)

AppWorks Handlers Interfaces/Annotations

com.opentext.otag.sdk.handlers

A number of handlers can be implemented to respond to messages from the managing Gateway. In many cases, an abstract implementation of the handler has been provided as part of the SDK for the developer to kick-start their implementation. You are still free however to provide your own implementation of a handler interface.

We provide the following handlers, which are grouped roughly by functional area. The classes mentioned can be found under the com.opentext.otag.sdk.handlers package. Annotations are listed as such using @. All other classes mentioned are Java interfaces.

Service Lifecycle Handlers

AWServiceContextHandler

This handler is informed when the AppWorks service has started and stopped. It implements this interface to receive these callbacks and acts upon them.

As AppWorks Service Clients and AppWorks services in general communicate with their managing Gateway through HTTP/S, we need to ensure that the Gateway has started first before initiating communications from the Service. As its name suggests, the Gateway is protecting an entry point to an OpenText customer deployment, so we want to make sure we are managing exposed resources appropriately.

Any code executed after the AWServiceContextHandler#onStart() method has begun is guaranteed to work with the Gateway. General use of javax.servlet.ServletContextListeners is permitted, but we advise developers to implement an AWServiceContextHandler instead if possible when working with the Gateway's services.

Note:
You may see warnings in the service logs if something potentially unsafe is found by the management agent in the service on deployment. These warnings will not prevent the service from starting, but if you find the service is not deploying correctly, they should be reviewed.

@AWServiceStartupComplete

This annotation must be placed on the method that will 'complete' the deployment of the service.

Note:
There must be one method, and one method only per AppWorks service annotated with @AWServiceStartupComplete or the management agent will not allow the service to start.

This annotation serves as a reminder that without telling the Gateway that a deployment is complete, it will never be accessible and will reject incoming requests indefinitely.

In order to complete the deployment, successfully or not as the case may be, the SDK's ServiceClient provides a handy completeDeployment method to fulfill this responsibility. AppWorks [mobile] Apps are not required to do this as they have no server side component. We actually perform this action on their behalf.

LifecycleCallbackHandler

This handler interface can be implemented to hook into the post-installation, post-upgrade/downgrade and pre-uninstall actions carried out by admin users at the AppWorks Gateway UI.

Authentication Handlers

AuthRequestHandler

AuthResquestHandler is an interface that can be implemented to delegate authentication to a back-end server other than OTDS. The handler must provide means to handle a username/password combination, or a session ticket, which could be OTDS or some other identity provider's ticket.

Note:
The back-end server must implement a scheme that guarantees at least the same level of protection that OTDS offers because it can be promoted to the primary authentication mechanism within the Gateway. This is responsibility of the service implementer and administrators managing the deployment of said service.

Implementations can be optionally annotated with AuthResponseDecorator to indicate that they should be used to decorate authentication responses when they are not being used as the Gateway's primary handler. This allows the Service to augment the initial response with data that will be delivered securely to the client as soon as they establish a connection.

This interface can be used as part of an EIM Connector or independently.

@AuthResponseDecorator

An AuthRequestHandler implementation that can be used to decorate authentication responses returned from the Gateway with extra cookies or data. If the annotated handler is being used as the primary authentication mechanism in the Gateway then this annotation is ignored as we will have the cookies in the response anyway.

Any additional fields added to the response will appear in the body of the Gateway's authentication response under the addtl property. The values are then further keyed under the name of the Service that added them because there is a potential for multiple AuthResponseDecorators to be deployed and enabled at once. We also avoid the issue where multiple decorator developers use the same names for their extra fields.

An example auth response containing additional data from two decorator services:

{
  [Omitted auth response fields ...]

  "addtl": {
    "decorator1": { "customProp": "some value" },
    "decorator2": { "customProp": "some value" }
  }
}

Settings

SettingChangeHandler

Implementations of this interface received updates regarding changes made to AppWorks configuration settings. When an AppWorks service is started any implementations of this handler found by the management agent will be automatically registered with the AppWorks Gateway for notifications about the configuration setting they are interested in. This is defined by the handler's implementation of the SettingChangeHandler#getSettingKey method.

MultiSettingChangeHandler

As its name suggests, this is a similar handler to our SettingChangeHandler, but it is able to respond to multiple setting keys as opposed to one using its getSettingKeys method.

This handler was designed to be used with its provided abstract implementation, AbstractMultiSettingChangeHandler, which offers the addHandler method. This method can take advantage of the Java 8 lambda syntax by allowing us to pass in a function as the handler. For example, in our handler implementation we might do the following:

Handling updates to multiple related settings in one place:

public class MySettingHandler extends AbstractMultiSettingChangeHandler {

  private String myFirstSetting;
  private String mySecondSetting;

  public MySettingHandler() {
    addHandler("my.first.setting.key", s -> {
      LOG.debug("my.first.setting.key was updated");
      myFirstSetting = s.getNewValue();
    });
    addHandler("my.second.setting.key",
      MySettingHandler::handleSecondSettingUpdate);
  }
  ...
  @Override
  public Set<String> getSettingKeys() {
    return Sets.newHashSet(Arrays.asList(
      "my.first.setting.key", "my.second.setting.key"));
  }
  ...
}

Advanced AppWorks Handlers

There are some features of the AppWorks SDK that are more involved than those presented thus far. They tend to provide well understood integration with OpenText EIM (Enterprise Information Management) products, such as Content Server, which allow rapid development of consistent solutions on top of our customer's existing investments.

Implementations of this kind of service are usually undertaken by engineers that are very familiar with the products involved, but we do provide a general abstraction that it easy to follow.

EIM Connectors

EIM Connectors provide a connection to a specific version of an EIM back-end service. The connection it provides is the base URL of the service endpoint, which is exposed by the EIM service to AppWorks. Multiple services can be built on top of an EIM solution that share an EIM connector (URL) to that system.

Apart from providing the connection string, the EIM Connector also provides abstractions around custom auth handling, and the Gateway's Trusted Provider access. An EIM Connector can contain an authentication handler, but this is really just an association. No extra functionality is afforded in the auth handler just because it is part of a service that happens to be an EIM Connector, and auth handlers can be deployed independently of EIM Connectors.

Trusted Providers

EIM Connector implementations can integrate with the Gateway's Trusted Provider functionality. This is another form of service to service communication involving the Gateway that is similar to the way in which the Gateway and AppWorks services interact.

A Trusted Provider key can be generated for a given provider name. This key then acts as an API key the EIM service can use to identify itself to a limited subset of the Gateway's APIs. The EIMConnectorService#registerTrustedServerKey should be implemented to pass the key generated through a TrustedProviderClient instance to the backing EIM system.

EIMConnectorClient

A connector client is provided as part of the SDK, EIMConnectorClientImpl. It is constructed by passing the name and the version of the connector. For example, "ContentServer", "10.5". Its connect method can be called to attempt to retrieve the EIMConnectorService for the provided details.

A ConnectionResult object will be returned letting the client know whether we have been successful or not.

The connector client should be retained by the service using it because its connectionString value is actually kept in line with the value maintained by the EIM connector itself. We take advantage of our configuration settings handling to keep the connector client abreast of the changes made to this value through the AppWorks Gateway UI. This ensures that when a service's code asks the connector client for the EIM connection string, it has the current and correct value.

Note:
An eimconnector-type service, just like any other service, must be enabled for use. As connectors are used by other services, make sure these client services can react accordingly when the connector is enabled/disabled.

Custom Authentication Handlers

The authentication handling pieces of the SDK were discussed in the Authentication Handlers_ section earlier, but this section describes the usage of services hosting an implementation of such a handler.

An authentication handler implementation can be promoted to be the primary auth mechanism for the Gateway once it has registered itself. See the AuthClient section. As a result, OTDS will no longer be used and all authentication requests will be passed to the handler implementation.

If a handler is promoted to be the primary handler, then the Gateway will not allow an administrator to disable this service because it is obviously fulfilling an important role. Once the primary authentication mechanism has been reset to OTDS or some other registered handler, the service can then be safely disabled.

Note:
EIM Connectors can contain a custom authentication handler, but they can be created outside of this context and implemented in an independent service. Sometimes the whole connector is not necessary if you just want to provide the authentication handling for instance.

Appendix A: AppWorks Service Deployment

Appendix B: AppWorks Gateway/Service Interaction

Appendix C: AppWorks Push Notifications

Appendix D: AppWorks Service Checklist Cheat Sheet

  1. The service artifact must be named in the following format name_{numeric.separated.version}.zip.

  2. A single method must be annotated with @AWServiceStartupComplete, it should report the outcome of the service initialization via the ServiceClient's completeDeployment method.

  3. The app.properties file should be at the root of the AppWorks service zip file.

  4. app.properties should have its mandatory properties populated

  5. displayName=<name> that appears in the admin UI title

  6. description=<desc> shown in the admin UI and on devices

  7. version=16.n... The version number of the app

  8. type=[app|service|component|eimconnector]

  9. awgPlatformVersion=16

About OpenText

OpenText™ (NASDAQ: OTEX, TSX: OTC) is a global leader in Enterprise Information Management (EIM). OpenText is enabling the digital world by creating a better way for organizations to work with information and achieve-actionable results.

OpenText is driving the digital transformation our customers need to better manage information, better integrate their business networks and make better business decisions with analytics. The OpenText EIM strategy enables organizations to discover and manage information to spur growth and innovation, and decrease time to competitive advantage. OpenText is enabling the digital world for more than 100,000 customers, with the OpenText Cloud processes over 18 billion transactions per year for more than 64,000 customers around the world. OpenText solutions consist of four on-premises suites representing the next generation of innovation in Enterprise Content Management (ECM), Business Process Management (BPM), Customer Experience Management (CEM) and Analytics.

OpenText's next generation of Enterprise Information Management (EIM) solutions address key business goals that drive digital transformation, and are designed for deployment in the cloud, on-premises and in hybrid (cloud and on-premises) environments.

Contact information

OpenText Corporation

275 Frank Tompa Drive
Waterloo, Ontario
Canada, N2L 0A1

Support: https://support.opentext.com
Knowledge Center: https://knowledge.opentext.com
For more information, visit www.opentext.com

Copyright © 2016 Open Text SA and/or Open Text ULC. All Rights Reserved.


Table of Contents