|Download tutorial source code||Click here to download|
|Last update||Oct 2022|
|Compilers||JDK 1.7 or greater|
|Prerequisite||Downloaded, installed, compiled, and ran an EMA consumer example|
In this tutorial we will explain and use the EMA Java SDK, to contribute data to the Refinitiv Contribution Channel (RCC) directly, without using the Refinitiv Real-Time Distribution System. The reader must have an understanding of an Refinitiv Real-time SDK (EMA) and be familiar with consuming OMM Market Price data. You should also have a basic understanding of EMA Configuration. To understand the contribution concepts, please refer to this article.
Currently, clients wishing to Contribute data to Refinitiv, typically do so using on-site contribution systems such as MarketLinkIP. In order to meet the evolving needs of the market, Refinitiv has developed a new Contribution service - the Refinitiv Contribution Channel (RCC). Contributions Channel is provided through a cluster of virtual servers that can provide data optimization & conflation capabilities as well as a much higher rate of content onto Refinitiv Real-Time System.
There are two key mechanisms through which an API developer can contribute data to the Refinitiv head-end. Once contributed, this data can be delivered to other customers who have been permissioned to view it. This service is commonly used by banks and funds to make their data available to the trading community.
The first option is to use and configure the Refinitiv Real-Time Distribution System, to take care of contribution specific connection and login details.
The second option, which is discussed in this tutorial, is for clients who do not have an onsite Refinitiv Real-Time Distribution System installation and will connect to RCC through the Internet. To contribute directly to RCC, an EMA application undertakes the following four steps:
Let's look at the EMA Java code starting with application configuration. This tutorial source code is based on EMA sample: series400\ex440_System_TunStrm which ships with the SDK distribution, in the Examples directory.
EMA SDK undertakes all the work required to establish an encrypted connection. All an application developer needs to do, is define the <Consumer>, set its <Channel> type to RSSL_ENCRYPTED and <EncryptedProtocolType> to RSSL_SOCKET, in the EMA configuration file EmaConfig.xml. The hostname and the port of the destination RCC server will have to be specified in the configuration as well.
Now, when an OMMConsumer is created with this configuration, EMA will start an encrypted connection. EMA Java uses the security and encryption framework provided by the Java SDK, and uses the Sun JDK's default TLS. The Java standard way is to store the security certificate and private keys required for encryption, in a password protected keystore file. This filename and password have to be specified when creating the OMMConsumer.
Note: Since Refinitiv Real-Time SDK Java 1.5.1.L1 (ETA Java 3.5.1.L1), specifying the Keystore file in the code is optional. The API can get certificates from the default Certificate Authority Keystore location in the Java directory.
// Create an OMM consumer
OmmConsumer consumer = EmaFactory.createOmmConsumer(EmaFactory.createOmmConsumerConfig());
// Create a request for a tunnel stream
TunnelStreamRequest tsr = EmaFactory.createTunnelStreamRequest()
// Send the request and register for events from tunnel stream
long tunnelStreamHandle = consumer.registerClient(tsr, appClient);
Here, we used the OMMConsumer defined earlier (which is connected to RCC server by now), and open a tunnel stream to contribution service using the system domain. The tunnel stream handle will be used in the next step to login.
For production applications, it is recommended to establish two simultaneous connections, to two different servers. An application should only contribute to a single stream at any given time. The second stream is for redundancy purposes, and should only be used if there are issues with the first one.
A successful opening of tunnel stream is followed by a status event callback: onStatusMsg, with state OmmState.StreamState.OPEN. The application should then perform a client login using the provided contribution user's username and password. The password field is no longer required to be obfuscated before sending.
// create a login request message
ElementList elementList = EmaFactory.createElementList();
ReqMsg rMsg = EmaFactory.createReqMsg()
// get events from login substream
_subStreamHandle = _ommConsumer.registerClient(rMsg, this, 1, _tunnelStreamHandle);
If the login is accepted by the RCC server, application will receive a refresh callback: onRefreshMsg with state OmmState.StreamState.OPEN. At this point, the application should store the stream handle, and is ready to contribute data.
The client's login response will include a maximum message rate in the refresh response and this message rate must be obeyed.
The TRCE:MaxMessagesPerSecond element is present in all Contributions Channel environments and the message rate posted by the connecting application must not exceed this number.
To contribute, application can use off-stream posting - i.e. send post messages on the login stream. Application begins by creating the field list for the FID's it intends to contribute to; packs the field list into an update message, and sends this update message as a PostMessage payload. Following snippet shows how to send an update message containing a BID (FID 22) and an ASK (FID 25).
// populate the contributed FIDs and values
FieldList nestedFieldList = EmaFactory.createFieldList();
nestedFieldList.add(EmaFactory.createFieldEntry().real(22, _bid++, OmmReal.MagnitudeType.EXPONENT_NEG_1));
nestedFieldList.add(EmaFactory.createFieldEntry().real(25, _ask++, OmmReal.MagnitudeType.EXPONENT_NEG_1));
// create an update message for our item
UpdateMsg nestedUpdateMsg = EmaFactory.createUpdateMsg()
// post this market price message
Here, the application is also requesting, that the contributions be acknowledged by the system, by setting solicitAck(true). Setting this flag will cause the application to receive acknowledgment callbacks: onAckMsg. The callback acknowledgment message AckMsg, will contain attributes nackCode and text reason if the contribution is denied.
text="Symbol posted has not been recognised"
Since this tutorial is based on EMA Example: series400\ex440_System_TunStrm, follow the same build process, to compile this source code.
keytool -genkey -alias mydomain -keyalg RSA -keystore KeyStore.jks -keysize 2048
3. Add the Comodo certificate authority to the keystore, if its not trusted. Refer to troubleshooting section on how to enable Java SSL logging and add Comodo CA.
4. Modify the source code to reflect this keystore file name and the keystore password.
5. Run output:
Contributing to Refinitiv Contributions Channel
Starting encrypted connection...
Starting tunnel stream...
----- Status message ----
state="Open / Ok / None / ''"
Sending client login request...
----- Refresh message ----
state="Open / Ok / None / 'Login accepted by host c226fmrdbcata'"
ElementEntry name="Password" dataType="Ascii" value="******"
Login accepted, starting posting...
----- Ack message ----
----- Ack message ----
----- Ack message ----
Data which is contributed to the production RCC, can be viewed by subscribing to that RIC in either desktop applications or any other consumer applications, like EMA Consumer sample.
Sample logging.properties file for storing log files in /log subdirectory:
# write logs in console and in file
# dump warning messages on console
# capture debug trace in the file
# Write 100000 bytes before rotating this file
# Number of rotating files to be used
# Format timestamp as date/time with millisecond
java.util.logging.SimpleFormatter.format=%1$tY-%1$tm-%1$td %1$tH:%1$tM:%1$tS.%1$tL %4$-7s %2$s %n%5$s
EMA Java logging can be enabled, by passing above properties file to JVM at run time. In addition, it might be helpful to turn on the JDK network logging, to view the security and encryption handshake messages, between the API and the server. Following command line parameters to JVM will enable verbose network and EMA logs.
java -cp %CLASSPATH% %LOGGING_CONFIG% %NET_DEBUGGING% Contributor
For an encrypted tunneling connection type, you might encounter trust issues with Comodo certificates. If you encounter this issue, manually download and import the certificate to your keystore file.
Alias name: comodo
Creation date: 23-Oct-2018
Entry type: trustedCertEntry
Owner: CN=COMODO RSA Organization Validation Secure Server CA, O=COMODO CA Limited, L=Salford, ST=Greater Manchester, C=GB
Issuer: CN=COMODO RSA Certification Authority, O=COMODO CA Limited, L=Salford, ST=Greater Manchester, C=GB
Serial number: 36825e7fb5a481937ef6d1736bb93ca6
Valid from: Tue Feb 11 19:00:00 EST 2014 until: Sun Feb 11 18:59:59 EST 2029
Signature algorithm name: SHA384withRSA
Subject Public Key Algorithm: 2048-bit RSA key
2. Backup your keystore file in case there is a problem importing the certificate.
3. Download the Comodo certificate: http://crt.comodoca.com/COMODORSAOrganizationValidationSecureServerCA.crt
4. Import into your keystore file: keytool -import -alias comodo -keystore KeyStore.jks -file COMODORSAOrganizationValidationSecureServerCA.crt
For more information on the use of keystores or understanding encryption in Java language, please refer to the Java Keystore file for Encryption - Article.