Create a Java-based Transformer Service blade
Here we explain how to create a simple Service blade for Transformer, where the blade is written as a Transformer modulein the Java programming language. The core of Transformer is written in C, so to create a module in Java, you use Transformer’s Java Module API.
If you’ve already read How Can I… Create a Lua-based Transformer Service blade, you’ll notice that the Lua blade described there does exactly the same thing as the blade we create here. This is entirely deliberate, and should allow you to see the differences and similarities between using Java and Lua for creating Transformer Service blades. |
Before you start
This example shows how to create a Java-based Service blade called SpreadJavaBlade that calculates the spread between Bid and Ask prices. At run time, the Transformer receives the prices from a Pricing Adapter (an Integration Adapter), and passes them on to the SpreadJavaBlade Transformer module, which calculates the price spread from the Bid and Ask prices. The Transformer sends the prices, including the new spread
field, on to a Liberator, which forwards them to subscribing client applications, as shown in this diagram:
You’ll need a Transformer and Liberator to help test your Service blade while you develop it, and a Pricing Adapter that can supply the Bid and Ask prices. In this example we’ve assumed that the corresponding record fields are called bidPrice
and askPrice
respectively.
If you don’t have Transformer and Liberator already deployed on a machine for this purpose, you’ll need to deploy one or both of these components to the Deployment Framework on your development machine. To do this, follow the instructions in How can I… Deploy Platform components to the Framework. You won’t need to set up HTTPS connections or KeyMaster while you’re developing the blade, so you can ignore the topics about those things.
If you need to develop a suitable Pricing Adapter first, see How can I… Create a Java-based Adapter blade.
Blade structure
What’s in a Java Service blade? Assuming the blade is located in in the Deployment Framework at <Framework-root>/
-
the blade type and blade compatibility information are in the control file
-
the blade’s field definitions are in blade_
config/ fields. conf -
Liberator related configuration for the blade is in Liberator/
etc/ rttpd. conf -
Transformer related configuration for the blade is in Transformer/
etc/ and Transformer/java. conf etc/ spreadjava. conf -
the Transformer module’s Java JAR file compiled from the Java source file is in Transformer/
lib/ java
Overview
In brief, you create the blade using the following steps, which are given in more detail further down the page:
Create the blade’s directory structure
In a directory that’s outside the Deployment Framework (say Temp_
At this stage, you don’t need to create the control file and the
Define the new fields
The blade must define any new fields that it will use, which in this instance means our new Spread
field.
You don’t have to list in the fields.BidPrice
and AskPrice
fields used in the code samples further down this page would have been defined there. When you deploy your new SpreadJavaBlade blade, the Deployment Framework will make the Pricing Adapter’s field definitions available to it (since the Pricing Adapter will also have been deployed as a blade).
For more about defining fields, see Field definitions in the DataSource Features and Concepts, and Field definition format.
Include configuration for Liberator and Transformer
The new blade has to include configuration for the core Platform components that it interacts with. In this case, the core components are: Liberator, which will subscribe to data supplied by the Transformer module, and Transformer, which houses the module.
Define additional Liberator configuration
Configuration details for the Liberator are stored in the rttpd.
This configuration defines a data service through which the Liberator requests the data supplied by the SpreadJavaBlade. It also defines, through the add-source-group … end-source-group
block, how the Liberator should fail the data service over to an alternate Liberator (this only applies if failover has been enabled for the deployment - see How can I… Set up server failover capability).
This is fairly standard configuration. The important points to note are:
-
The
service-name
configuration item defines the name of the data service, which in this case is (by convention) the name of the blade, SpreadJavaBlade, that supplies the data. -
The
include-pattern
item specifies that the data service is to supply data for all subscriptions whose subjects start with the string/FX/ -
The macros
THIS_
andLEG OTHER_
are used to differentiate the configuration of primary and secondary failover legs.LEG
Define the Java module configuration in Transformer
Configuring Transformer for a Java module is a bit more involved than doing so for a Lua module, as the Transformer has to know the location of the Java Virtual Machine (JVM) in order to start it.
Add the blade control file
The Deployment Framework needs to take some specific actions to allow a Java Transformer module blade to work correctly. So the Framework needs to have a way of knowing the blade is a Java Transformer module. This is done through a blade control file located in the root directory of the blade.
That’s all the configuration changes you need for the time being.
Deploy configuration to the Deployment Framework
Now you’ve created the initial configuration for the core components that use your Transformer Service blade, you can deploy this configuration in your development environment.
At this stage, the Liberator and Transformer are running with the new configuration. The new blade won’t run of course, because no executable code has been written for the Java module.
In a Web browser, navigate to the Liberator’s status page, where you should see the SpreadJavaBlade data service:
The URL of the Liberator is of the form http://<URL_of_liberator_server>:<liberator_port>. You can find the <URL_ . In a development enviroment, the URL would typically be http://localhost:18080. When the Liberator home page is displayed, select the View Status button.
|
Write the Java module
This is the functional part of the Java module that defines the actions you need it to perform. In this example, the Java source is in a single file called SpreadModule.
The example code is quite long, so we’ll break it up into sections in order to explain it. It uses Transformer’s Java Module API.
Section 1:
package example.spreadmodule;
import com.caplin.transformer.module.*;
public class SpreadModule implements TransformerModule, SubscriptionListener
{
private int bidFieldNumber;
private int askFieldNumber;
private int spreadFieldNumber;
@Override
public void initialise(String moduleName, TransformerAccessor transformerAccessor)
{
bidFieldNumber = transformerAccessor.getFieldManager().getFieldByName("BidPrice").getNumber();
askFieldNumber = transformerAccessor.getFieldManager().getFieldByName("AskPrice").getNumber();
spreadFieldNumber = transformerAccessor.getFieldManager().getFieldByName("Spread").getNumber();
transformerAccessor.getSubscriber().addSubscriptionListener("/FX/*", this);
}
This first section identifies defines the SpreadModule
class which implements the TransformerModule
and SubscriptionListener
interfaces of the Transformer Java Module API. It defines three integers to contain the numbers of the relevant record fields, and, in the initialise()
method, populates these integers using the getFieldByName()
method. initialise()
also creates a subscription listener, to listen for messages from the Pricing Adapter that have subjects in the "/FX/" namespace.
Section 2:
@Override
public void setFileReading(boolean b) {
}
@Override
public void shutdown() {
}
@Override
public String getLoggerName() {
return "example.spreadmodule.SpreadModule";
}
@Override
public void objectDeleted(String objectName) {
}
@Override
public void status(String objectName, ObjectStatus objectStatus) {
}
The above method implementations just define the default settings for some methods of the TransformerModule
and SubscriptionListener
interfaces.
Section 3:
@Override
public void update(DataSourceUpdateEvent dataSourceUpdateEvent) {
String bidValue =
dataSourceUpdateEvent.getTransformerData().getFieldByFieldNumber(bidFieldNumber).getValue();
String askValue =
dataSourceUpdateEvent.getTransformerData().getFieldByFieldNumber(askFieldNumber).getValue();
This implementation of the SubscriptionListener
interface’s update()
method obtains the AskPrice
and BidPrice
field values from an incoming record message with a subject that begins with "/FX/". It uses the field numbers obtained when the module was initialised (see section 1 of the example).
Section 4:
if ( askValue != null && bidValue != null ) { double spreadValue = Double.parseDouble(askValue) - Double.parseDouble(bidValue); dataSourceUpdateEvent.getTransformerData().addData(spreadFieldNumber, spreadValue); } } }
Having retrieved the AskPrice
and BidPrice
field values, the subscription listener’s update()
method checks that neither of them are null, calculates spreadValue
, by subtracting one value from the other, and uses the addData()
method to add this calculated spread value to the Spread
field that was defined earlier.
When you’ve completed the code in the SpreadModule.
Package the new blade
When you’ve developed and tested the new blade to your satisfaction, you’ll need to package it up so it can be deployed on your production system - see How can I… Package a custom blade.
See also: