EMACPP_DevGuide EMACPP Dev Guide

User Manual: Pdf

Open the PDF directly: View PDF PDF.
Page Count: 42

Document Version: 3.1.2
Date of issue: 31 January 2018
Document ID: EMAC312UM.180
Elektron Message API
C++ Edition
V3.1.X
ELEKTRON MESSAGE API DEVELOPERS GUIDE
Elektron Message API C++ Edition 3.1.X – Developers Guide ii
EMAC312UM.180
Legal Information
© Thomson Reuters 2015 - 2018. All rights reserved.
Thomson Reuters, by publishing this document, does not guarantee that any information contained herein is and will remain accurate or that
use of the information will ensure correct and faultless operation of the relevant service or equipment. Thomson Reuters, its agents and
employees, shall not be held liable to or through any user for any loss or damage whatsoever resulting from reliance on the information
contained herein.
This document contains information proprietary to Thomson Reuters and may not be reproduced, disclosed, or used in whole or part without
the express written permission of Thomson Reuters.
Any Software, including but not limited to, the code, screen, structure, sequence, and organization thereof, and Documentation are protected
by national copyright laws and international treaty provisions. This manual is subject to U.S. and other national export regulations.
Nothing in this document is intended, nor does it, alter the legal obligations, responsibilities or relationship between yourself and Thomson
Reuters as set out in the contract existing between us.
Elektron Message API C++ Edition 3.1.X – Developers Guide iii
EMAC312UM.180
Contents
Contents
Chapter 1 Guide Introduction........................................................................................................... 1
1.1 About this Manual ........................................................................................................................................... 1
1.2 Audience ......................................................................................................................................................... 1
1.3 Programming Language.................................................................................................................................. 1
1.4 Acronyms and Abbreviations .......................................................................................................................... 2
1.5 References...................................................................................................................................................... 3
1.6 Documentation Feedback ............................................................................................................................... 3
1.7 Document Conventions................................................................................................................................... 3
Chapter 2 Product Overview............................................................................................................. 4
2.1 EMA Product Description ................................................................................................................................ 4
2.2 Product Documentation and Learning EMA.................................................................................................... 5
2.2.1 Consumer Examples ................................................................................................................................ 5
2.2.2 Provider Examples.................................................................................................................................... 5
2.3 Supported Features ........................................................................................................................................ 6
2.4 Product Architecture........................................................................................................................................ 9
2.4.1 EMA Consumer Architecture .................................................................................................................... 9
2.4.2 EMA Provider Architecture ....................................................................................................................... 9
2.4.3 EMA Codec Architecture ........................................................................................................................ 10
2.5 Tunnel Streams............................................................................................................................................. 11
Chapter 3 OMM Containers and Messages ................................................................................... 12
3.1 Overview ....................................................................................................................................................... 12
3.2 Classes ......................................................................................................................................................... 13
3.2.1 DataType Class ...................................................................................................................................... 13
3.2.2 DataCode Class...................................................................................................................................... 13
3.2.3 Data Class .............................................................................................................................................. 13
3.2.4 Msg Class............................................................................................................................................... 14
3.2.5 OmmError Class..................................................................................................................................... 14
3.2.6 TunnelStreamRequest and ClassOfService Classes ............................................................................. 14
3.3 Working with OMM Containers ..................................................................................................................... 15
3.3.1 Example: Populating a FieldList Class ............................................................................................... 15
3.3.2 Example: Populating a Map Class Relying on the FieldList Memory Buffer........................................ 16
3.3.3 Example: Populating a Map Class Relying on the Map Class Buffer........................................................ 16
3.3.4 Example: Extracting Information from a FieldList Class ..................................................................... 17
3.3.5 Example: Application Filtering on the FieldList Class......................................................................... 18
3.3.6 Example: Extracting FieldList information using a Downcast Operation ................................................ 18
3.4 Working with OMM Messages ...................................................................................................................... 20
3.4.1 Example: Populating the GenericMsg with an ElementList Payload.................................................... 20
3.4.2 Example: Extracting Information from the GenericMsg Class ................................................................ 20
3.4.3 Example: Working with the TunnelStreamRequest Class ..................................................................... 21
Chapter 4 Consumer Classes......................................................................................................... 22
4.1 OmmConsumer Class................................................................................................................................... 22
4.1.1 Connecting to a Server and Opening Items............................................................................................ 22
4.1.2 Opening Items Immediately After OmmConsumer Object Instantiation ................................................. 22
4.1.3 Destroying the OmmConsumer Object................................................................................................... 23
4.1.4 Example: Working with the OmmConsumer Class................................................................................. 23
4.1.5 Working with Items ................................................................................................................................. 23
4.1.6 Example: Working with Items ................................................................................................................. 24
Elektron Message API C++ Edition 3.1.X – Developers Guide iv
EMAC312UM.180
4.2 OmmConsumerClient Class.......................................................................................................................... 25
4.2.1 OmmConsumerClient Description .......................................................................................................... 25
4.2.2 Example: OmmConsumerClient ............................................................................................................. 25
4.3 OmmConsumerConfig Class ........................................................................................................................ 26
4.3.1 OmmConsumerConfig Description......................................................................................................... 26
4.3.2 Tunneling Configuration.......................................................................................................................... 26
4.3.3 Additional Configurations for HTTPS Tunneling in Linux........................................................................ 26
Chapter 5 Provider Classes ............................................................................................................ 27
5.1 OmmProvider Class ...................................................................................................................................... 27
5.1.1 Connecting to ADH and Submitting Items .............................................................................................. 27
5.1.2 Non-Interactive Providers: Post OmmProvider Object Instantiation....................................................... 29
5.1.3 Interactive Providers: Post OmmProvider Object Instantiation............................................................... 29
5.1.4 Destroying the OmmProvider Object...................................................................................................... 29
5.1.5 Non-Interactive Example: Working with the OmmProvider Class........................................................... 30
5.1.6 Interactive Provider Example: Working with the OmmProvider Class.................................................... 31
5.1.7 Working with Items ................................................................................................................................. 31
5.2 OmmProviderClient Class............................................................................................................................. 32
5.2.1 OmmProviderClient Description ............................................................................................................. 32
5.2.2 Non-Interactive Example: OmmProviderClient....................................................................................... 32
5.2.3 Interactive Example: OmmProviderClient............................................................................................... 33
5.3 OmmNiProviderConfig Class ........................................................................................................................ 34
5.4 OMMIProviderConfig..................................................................................................................................... 35
Chapter 6 Troubleshooting and Debugging.................................................................................. 36
6.1 EMA Logger Usage....................................................................................................................................... 36
6.2 Omm Error Client Classes ............................................................................................................................ 36
6.2.1 Error Client Description........................................................................................................................... 36
6.2.2 Example: Error Client.............................................................................................................................. 36
6.3 OmmException Class.................................................................................................................................... 37
Chapter 1 Guide Introduction
Elektron Message API 3.1.X C++ Edition – Developers Guide 1
EMAC312UM.180
Chapter 1 Guide Introduction
1.1 About this Manual
This document is authored by Elektron Message API architects and programmers. Several of its authors have designed,
developed, and maintained the Elektron Message API product and other Thomson Reuters products which leverage it.
This guide documents the functionality and capabilities of the Elektron Message API C++ Edition. The Elektron Message API
can also connect to and leverage many different Thomson Reuters and customer components. If you want the Elektron
Message API to interact with other components, consult that specific component’s documentation to determine the best way to
configure and interact with these other devices.
1.2 Audience
This document is intended to provide detailed yet supplemental information for application developers writing to the Message
API.
1.3 Programming Language
The Message API is written using the C++ programming language taking advantage of the object oriented approach to design
and development of API and applications.
Chapter 1 Guide Introduction
Elektron Message API 3.1.X C++ Edition – Developers Guide 2
EMAC312UM.180
1.4 Acronyms and Abbreviations
ACRONYM MEANING
ADH Advanced Data Hub is the horizontally scalable service component within Thomson Reuters
Enterprise Platform (TREP) providing high availability for publication and contribution messaging,
subscription management with optional persistence, conflation and delay capabilities.
ADS Advanced Distribution Server is the horizontally scalable distribution component within Thomson
Reuters Enterprise Platform (TREP) providing highly available services for tailored streaming and
snapshot data, publication and contribution messaging with optional persistence, conflation and delay
capabilities.
API Application Programming Interface
ASCII American Standard Code for Information Interchange
EED Elektron Edge Device
EMA Elektron Message API, referred to simply as the Message API
ETA Elektron Transport API, referred to simply as the Transport API. Formerly referred to as UPA.
HTTP Hypertext Transfer Protocol
HTTPS Hypertext Transfer Protocol (Secure)
OMM Open Message Model
QoS Quality of Service
RDM Reuters Domain Model
Reactor The Reactor is a low-level, open-source, easy-to-use layer above ETA. It offers heartbeat
management, connection and item recovery, and many other features to help simplify application
code for users.
RMTES Reuters Multi-Lingual Text Encoding Standard
RSSL Reuters Source Sink Library
RWF Reuters Wire Format, a Thomson Reuters proprietary format.
TR-DFD Thomson Reuters Data Feed Direct
TREP Thomson Reuters Enterprise Platform
UML Unified Modeling Language
UTF-8 8-bit Unicode Transformation Format
Table 1: Acronyms and Abbreviations
Chapter 1 Guide Introduction
Elektron Message API 3.1.X C++ Edition – Developers Guide 3
EMAC312UM.180
1.5 References
1. Elektron Message API C++ Edition RDM Usage Guide
2. API Concepts Guide
3. Elektron Message API C++ Configuration Guide
4. EMA C++ Edition Reference Manual
5. Transport API C Edition Value Added Components Developers Guide
6. Transport API C Edition Developers Guide
7. The Thomson Reuters Professional Developer Community
1.6 Documentation Feedback
While we make every effort to ensure the documentation is accurate and up-to-date, if you notice any errors, or would like to
see more details on a particular topic, you have the following options:
Send us your comments via email at apidocumentation@thomsonreuters.com.
Add your comments to the PDF using Adobe’s Comment feature. After adding your comments, submit the entire PDF to
Thomson Reuters by clicking Send File in the File menu. Use the apidocumentation@thomsonreuters.com address.
1.7 Document Conventions
This document uses the following types of conventions:
C++ classes, methods, in-line code snippets, and types are shown in orange, Courier New font.
Parameters, filenames, tools, utilities, and directories are shown in Bold font.
Document titles and variable values are shown in italics.
When initially introduced, concepts are shown in Bold, Italics.
Longer code examples are shown in Courier New font against an orange background. For example:
AppClient client;
OmmConsumer consumer( OmmConsumerConfig().operationModel(
OmmConsumerConfig::UserDispatchEnum ).host( "localhost:14002" ).username( "user" ) );
consumer.registerClient( ReqMsg().domainType( MMT_MARKET_BY_PRICE ).serviceName(
"DIRECT_FEED" ).name( "BBH.ITC" ).privateStream( true ), client );
unsigned long long startTime = getCurrentTime();
Chapter 2 Product Overview
Elektron Message API 3.1.X C++ Edition – Developers Guide 4
EMAC312UM.180
Chapter 2 Product Overview
2.1 EMA Product Description
The Elektron Message API is a data-neutral, multi-threaded, ease-of-use API providing access to OMM and RWF data. As part
of the Elektron Software Development Kit, or Elektron SDK, the EMA allows applications to consume and provide OMM data at
the message level of the API stack. The message level is set on top of the transport level which is handled by the Elektron
Transport API (also known as the UPA).
The Elektron Message API (EMA):
Provides a set of easy-to-use and intuitive interfaces and features intended to aid in message-level application
development. These interfaces simplify the setting of information in and getting information from OMM containers and
messages. Other interfaces abstract the behavior of consumer-type and provider-type applications.
Enables applications to source market data from, and provide it to, different components that support OMM and/or RWF
(e.g. Elektron, Enterprise Platform, ATS, RDF-D, etc).
Leaves a minimal code footprint in applications written to it. The design of the EMA and its interfaces allows application
development to focus more on the application business logic than on the usage of the EMA.
Includes training applications that provide basic, yet still functional, examples of EMA applications.
Presents applications with simplified access to OMM messages and containers while providing all necessary transport
level functionalities. Generally, EMA applications are meant to process market data items (e.g. open and receive item data
or provide item data).
Abstracts and hides all the transport level functionality minimizing application involvement to just optional transport level
configuration and server address specification.
Provides simple set- and get-type functionality to populate and read OMM containers and messages. EMA takes
advantage of fluent interface design, which users can leverage to set disparate values of the same message or container
by stringing respective interface methods together, one after the other. Fluent interfaces provide the means for visual code
simplification which helps in understanding and debugging applications.
Transport level functionality is abstracted, specialized, and encapsulated by the EMA in a few classes whose functionality is
implied by their class name.
Chapter 2 Product Overview
Elektron Message API 3.1.X C++ Edition – Developers Guide 5
EMAC312UM.180
2.2 Product Documentation and Learning EMA
When learning the EMA, Thomson Reuters recommends you set up a sandbox environment where developers can
experiment with various iterations of EMA applications. EMA is designed to facilitate a hands-on (experiment-based) learning
experience (versus a documentation-based methodology). To support a hands-on learning methodology, the EMA package
provides a set of training examples which showcase the usage of EMA interfaces in increasing levels of complexity and
sophistication. While coding and debugging applications, developers are encouraged to refer to the EMA C++ Edition
Reference ManualC++ and or to the features provided by their IDE (e.g., IntelliSense).
2.2.1 Consumer Examples
The complexity of a consumer example is reflected in its series number as follows:
100-series examples simply open an item and print its received content to the screen (using the Data::toString()
method). Applications in this series illustrate EMA support for stringification, containers, and primitives. Though useful for
learning, debugging, and writing display applications, stringification by itself is not sufficient to develop more sophisticated
applications.
The 200 series examples illustrate how to extract information from OMM containers and messages in native data formats,
(e.g., UInt64, EmaString, and EmaBuffer).
The 300 and 400 series examples depict usage of particular EMA features such as posting, generic message,
programmatic configuration, and etc.
2.2.2 Provider Examples
The complexity of a provider examples are reflected in its series number. Each provider type (i.e., non-interactive versus
interactive) has its own directory structure in the product package:
100-series examples simply create streaming items and submit their refreshes and updates. Applications in this series use
the hardcoded EMA configuration.
The 200 series examples showcase the submission of multiple, streaming items from different market domains.
Applications in this series use the EmaConfig.xml file to modify its configuration.
The 300 series examples depict usage of particular EMA features such as user control of the source directory domain,
login streaming, connection recovery, and etc.
Note: EMA application developers should already be familiar with OMM and Market Data distribution systems.
Chapter 2 Product Overview
Elektron Message API 3.1.X C++ Edition – Developers Guide 6
EMAC312UM.180
2.3 Supported Features
FEATURE DESCRIPTION
New in 3.1.2!
Support for HTTP and
ENCRYPTED Connection Types
EMA provides support for ChannelType::RSSL_HTTP and
ChannelType::RSSL_ENCRYPTED connection types for EMA consumers. For further
details, refer to Section 4.3.
New in 3.1!
Domain Representations for
Admin Domain Login Messages
EMA provides Domain Representations for Admin Domain Login Messages. Domain
Representations are easy-to-use objects which can setup and return encoded OMM
Messages without extensive effort.
For further details, refer to EMA’s RDM Usage Guide.
New in 3.1!
TREP Authentication
EMA provides support for the TREP Authentication feature for consumers and non-
interactive providers. For more information, refer to EMA’s RDM Usage Guide and to
the TREP Authentication user manuala.
New in 3.1!
Enhanced Login Stream Handling
EMA applications can register for Login events when they create OmmConsumer or
non-interactive OmmProvider objects.
New in 3.0.6!
Interactive Provider
EMA provides interactive provider connectivity (e.g., for ADH or other directly-
connected consumers).
New in 3.0.3!
Non-interactive Provider
Applications can connect to an ADH TREP component to non-interactively provide
item data.
Connection Failover You can specify a list of failover servers via the ChannelSet configuration. If a
connection attempt fails, EMA attempts to connect to the next channel in the
ChannelSet list. Both EMA consumers and non-interactive providers support the
connection failover feature.
ADS Multicast Applications can connect to the ADS multicast component by specifying the
connection type RSSL_RELIABLE_MCAST.
Table 2: Supported Features
Chapter 2 Product Overview
Elektron Message API 3.1.X C++ Edition – Developers Guide 7
EMAC312UM.180
Default Admin Domain Messages The EMA consumer uses default login, directory, and dictionary requests when
connecting to a provider or ADS:
The Login request uses the current user’s name and defaults all other login
attributes.
The Directory request calls for all services and filters.
RDM dictionaries are requested from the first available service that accepts
requests.
The EMA non-interactive provider uses the default login request and configured
directory refresh when connecting to ADH:
The login request uses the current user's name and defaults all other login
attributes.
The directory refresh message defaults all message attributes as well as status,
while its payload is either hardcoded or read from the EMA configuration.
The EMA interactive provider can use default, preconfigured directory and dictionary
refresh messages.
The directory refresh message defaults appropriate message attributes as well as
status, while its payload is either hard coded or read from the EMA configuration.
The dictionary refresh message is handled based on either its hard-coded
configuration or read from the EMA configuration.
Configurable Admin Domain
Messages EMA provides the means to modify default Admin domain messages.
Batch Request A consumer application can use a single request message to specify interest in
multiple items via the item list.
Dynamic View A consumer application can specify a subset of fields or elements for a particular item.
Optimized Pause and Resume A consumer application can send a request to the server to pause and resume item
stream.
Single Open The EMA supports application-selected, single-open functionality.
RMTES Decoder The EMA provides a built-in RMTES decoder. If needed, the application can cache
RmtesBuffer objects and apply all received changes to them.
Data::toString() Prints all OMM containers, primitives, and messages to screen in a standardized
output format (called “stringification”).
Data::getAsHex() Applications can obtain binary representations of all OMM containers, primitives, and
messages.
Programmatic Config The application can programmatically specify and overwrite its EMA configuration for
the consumer-side only. EMA C Edition does not support programmatic configuration
with NIProvider and IProvider.
File Configuration An EMA configuration can be specified in an EmaConfig.xml file.
Tunnel Stream (also known as a
Qualified Stream) EMA supports private streams, with additional associated behaviors (e.g., end-to-end
authentication, guaranteed delivery, and flow control).
FEATURE DESCRIPTION
Table 2: Supported Features (Continued)
Chapter 2 Product Overview
Elektron Message API 3.1.X C++ Edition – Developers Guide 8
EMAC312UM.180
File Logger EMA allows the application to turn on / off EMA logging, to specify the desired severity
level of error reporting, and to specify whether to send logger messages to stdout or a
file.
Connected Component
Information Whenever EMA connects to a component, EMA sends its component version
information, and if the connection is successful, EMA logs the component’s version.
a. The TREP Authentication User Manual can be obtained on Thomson Reuters’s MyAccount portal under the DACS product
content set.
FEATURE DESCRIPTION
Table 2: Supported Features (Continued)
Chapter 2 Product Overview
Elektron Message API 3.1.X C++ Edition – Developers Guide 9
EMAC312UM.180
2.4 Product Architecture
2.4.1 EMA Consumer Architecture
The EMA incorporates the ValueAdded Reactor component (called the Transport API VA Reactor) from the Transport API,
which provides the watchlist and transport-level functionality. The EMA wraps up the reactor component in its own class of
OmmConsumer. OmmConsumer provides interfaces to open, modify, and close market items or instruments, as well as submit
Post and Generic messages. To complete the set of consumer application functionalities, the OmmConsumer class provides
the dispatch() method. Depending on its design and configuration, an application might need to call this method to dispatch
received messages. The OmmConsumerConfig class configures the reactor and OmmConsumer.
The OmmConsumerClient class provides the callback mechanism for EMA to send incoming messages to the application.
The application needs to implement a class inheriting from the OmmConsumerClient class to receive and process
messages. By default, OmmConsumerClient callback methods are executed in EMA's thread of control. However, you can
use the OmmConsumerConfig::operationModel() interface to execute callback methods on the application thread. If you
choose to execute callback methods in this manner, the application must also call the OmmConsumer::dispatch() method
to dispatch received messages.
While the OmmConsumer class throws an OmmException to report error conditions, the OmmConsumerErrorClient class
provides an alternate reporting mechanism via callbacks. To use the alternate error reporting, pass the
OmmConsumerErrorClient on the constructor of the OmmConsumer class, which switches the error reporting from
exception throwing to callbacks. In addition to its error reporting mechanisms, EMA provides a logger mechanism which is
useful in monitoring EMA behavior and debugging any issues that might arise.
The EMA consumer will always have at least one thread, which is implemented by the VA Reactor and runs the internal, VA
Reactor logic. For details on this thread, refer to the Transport API C Edition Value Added Component Developers Guide.
Additionally, you can configure the EMA to create a second, internal thread to dispatch received messages. To create a
second thread, set the OmmConsumerConfig operation model to OmmConsumerConfig::ApiDispatchEnum. If the
OmmConsumerConfig operation model is set to the OmmConsumerConfig::UserDispatch, the EMA will not run a second
thread. Without running a second thread, the application is responsible for calling the Ommconsumer::dispatch() method
to dispatch all received messages.
2.4.2 EMA Provider Architecture
The EMA provider incorporates the Value Added (VA) Reactor component from the Transport API, which provides transport-
level functionality. The EMA wraps the reactor component in its own class of OmmProvider. OmmProvider provides
interfaces to submit item messages as well as handling login, directory, and dictionary domains (depending on EMA’s specific
provider role). To complete the set of provider functionalities, the OmmProvider class provides the dispatch() method.
Depending on its design and configuration, an application might need to call this method to dispatch received messages. The
provider configuration class (i.e., OmmNiProviderConfig or OmmIProviderConfig) class configures both the reactor and
OmmProvider.
EMA sends incoming messages to the application using the OmmProviderClient callback mechanism. To receive and
process messages, the application needs to implement a class that inherits from the OmmProviderClient class. By default,
OmmProviderClient callback methods are executed in EMA's thread of control. However, you can use either the
OmmNiProviderConfig::operationModel() or OmmIProviderConfig::operationModel() interface to execute
callback methods on the application’s thread, in which case the application must also call the OmmProvider::dispatch()
method to dispatch received messages.
While the OmmProvider class throws an OmmException to report error conditions, the OmmProviderErrorClient class
provides an alternate reporting mechanism via callbacks. To use the alternate error reporting, pass the
OmmProviderErrorClient on the constructor of the OmmProvider class, which switches the error reporting from
Warning! If the application delays in dispatching messages, it can result in slow consumer behavior.
Chapter 2 Product Overview
Elektron Message API 3.1.X C++ Edition – Developers Guide 10
EMAC312UM.180
exception throwing to callbacks. In addition to its error-reporting mechanisms, EMA provides a logger mechanism which you
can use to monitor EMA behavior and debug any issues that arise.
An EMA provider must always have at least one thread, which is implemented by the VA Reactor and runs the internal, VA
Reactor logic. For details on this thread, refer to the Transport API C Edition Value Added Component Developers Guide.
Additionally, you can configure EMA to create a second internal thread over which to dispatch received messages:
For non-interactive providers, set the OmmNiProviderConfig operation model to
OmmNiProviderConfig::ApiDispatchEnum. If the operation model is set to
OmmNiProviderConfig::UserDispatchEnum, EMA will not run a second thread.
For interactive providers, set the OmmIProviderConfig operation model to
OmmIProviderConfig::ApiDispatchEnum. If the operation model is set to
OmmIProviderConfig::UserDispatchEnum, EMA will not run a second thread.
Without running a second thread, the application is responsible for calling the OmmProvider::dispatch() method to
dispatch all received messages.
The EMA provider includes an internal, hard-coded, and configurable initial source directory refresh message. The application
can either use the internal hard-coded source directory, configure its own internal one via the EmaConfig.xml file, or
programmatically create one and/or disable the internal one. To disable the internal source directory message:
When running EMA as a non-interactive provider: the application must set
OmmNiProviderConfig::UserControlEnum through the OmmNiProviderConfig::adminControlDirectory()
method.
When running EMA as an interactive provider: the application must set OmmIProviderConfig::UserControlEnum
through the OmmIProviderConfig::adminControlDirectory() method. Additionally, you can configure the ability
to disable internal dictionary responses by setting OmmIProviderConfig.AdminControl.USER_CONTROL through the
OmmIProviderConfig::adminControlDirectory() method.
2.4.3 EMA Codec Architecture
The EMA Codec uses the Elektron Transport API decoding and encoding functions to read and populate OMM containers and
messages. Each OMM container and message is represented by a respective EMA interface class, which provides relevant
methods for setting information on, and accessing information from, these containers and messages. All classes representing
OMM containers, messages, and primitives inherit from the common parent class of Data. Through such inheritance, classes
provide the same basic, common, and easy to use functionality that applications might expect from them (e.g., printing
contained data using toString()).
Note: If user control is enabled, the application is responsible for sending the response messages.
Chapter 2 Product Overview
Elektron Message API 3.1.X C++ Edition – Developers Guide 11
EMAC312UM.180
2.5 Tunnel Streams
By leveraging the Transport API Value Added Reactor, the EMA allows users to create and use special tunnel streams. A
tunnel stream is a private stream that has additional behaviors associated with it, such as end-to-end line of sight for
authentication and guaranteed delivery. Because tunnel streams are founded on the private streams concept, these are
established between consumer and provider endpoints and then pass through intermediate components, such as TREP or
EED.
The user creating the tunnel stream sets any additional behaviors to enforce, which EMA sends to the provider application end
point. The provider end point acknowledges creation of the stream as well as the behaviors that it will also enforce on the
stream. Once this is accomplished, the negotiated behaviors will be enforced on the content exchanged via the tunnel stream.
The tunnel stream allows for multiple substreams to exist, where substreams flow and coexist within the confines of a specific tunnel stream.
In the following diagram, imagine the tunnel stream as the orange cylinder that connects the Consumer application and the Provider
application. Notice that this passes directly through any intermediate components. The tunnel stream has end-to-end line of sight so the
Provider and Consumer are effectively talking to each other directly, although they are traversing multiple devices in the system. Each of the
black lines flowing through the cylinder represent a different substream, where each substream is its own independent stream of information.
Each of these could be for different market content, for example one could be a Time Series request while another could be a request for
Market Price content.
Figure 1. Tunnel Stream
Chapter 3 OMM Containers and Messages
Elektron Message API 3.1.X C++ Edition – Developers Guide 12
EMAC312UM.180
Chapter 3 OMM Containers and Messages
3.1 Overview
The EMA supports a full set of OMM containers, messages, and primitives (e.g. FieldList, Map, RefreshMsg, Int). For
simplicity, EMA uses:
The “set / add” type of functionality to populate OMM containers, messages, and primitives
Set functionality is used to specify variables that occur once in an OMM container or message.
Add functionality is used to populate entries in OMM containers.
Set and add type methods return a reference to the modified object (for fluid interface usage).
The “get” type of functionality to read and extract data from OMM containers, messages, and primitives.EMA uses a
simple iterative approach to extract entries from OMM containers, one at a time. Applications iterate over every OMM
container type in the same way.
While iterating, an application can apply a filtering mechanism. For example, while iterating over a FieldList, the application
can specify a field ID or field name in which it is interested; the EMA skips entries without matching identification. Individual
container entries are extracted during iteration. Depending on the container type, the entry may contain:
Its own identity (e.g., field id)
An action to be applied to the received data (e.g., add action)
Permission information associated with the received data
An entry’s load and its data type.
The EMA has two different ways of extracting an entry’s load:
Use ease-of-use interfaces to return references to contained objects (with reference type being based on the load’s data
type)
Use the getLoad interface to return a reference to the base Data class. The getLoad interface enables more advanced
applications to use the down-cast operation (if desired).
For details on ease of use interfaces and the down-cast operation, refer to Section 3.3.
To provide compile time-type safety on the set-type interfaces, EMA provides the following, deeper inheritance structure:
All classes representing primitive / intrinsic data types inherit from the Data class (e.g. OmmInt, OmmBuffer, OmmRmtes,
etc.).
OmmArray class inherits from the Data class. The OmmArray is treated as a primitive instead of a container, because it
represents a set of primitives.
OmmError class inherits from the Data class. OmmError class is not an OMM data type.
All classes representing OMM containers (except OmmArray) inherit from the ComplexType class, which in turn inherits
from the Data class (e.g., OmmXml, OmmOpaque, Map, Series, or Vector).
All classes representing OMM messages inherit from the Msg class, which in turn inherits from the ComplexType class
(e.g., RefreshMsg, GenericMsg, or PostMsg).
Chapter 3 OMM Containers and Messages
Elektron Message API 3.1.X C++ Edition – Developers Guide 13
EMAC312UM.180
3.2 Classes
3.2.1 DataType Class
The DataType class provides the set of enumeration values that represent each and every supported OMM data type,
including all OMM containers, messages, and primitives. Each class representing OMM data identifies itself with an
appropriate DataType enumeration value (e.g., DataType::FieldListEnum, DataType::RefreshMsgEnum). You can
use the Data::getDataType() method to learn the data type of a given object.
The DataType class list of enumeration values contains two special enumeration values, which can only be received when
reading or extracting information from OMM containers or messages:
DataType::ErrorEnum, which indicates an error condition was detected. For more details, refer to Section 3.2.5.
DataType::NoDataEnum, which signifies a lack of data on the summary of a container, message payload, or
attribute.
3.2.2 DataCode Class
The DataCode class provides two enumeration values that indicate the data’s state:
•The DataCode::NoCodeEnum indicates that the received data is valid and application may use it.
•The DataCode::BlankEnum indicates that the data is not present and application needs to blank the respective data
fields.
3.2.3 Data Class
The Data class is a parent abstract class from which all OMM containers, messages, and primitives inherit. Data provides
interfaces common across all its children, which in turn enables down-casting operations. The Data class and all classes that
inherit from it are optimized for efficiency and built so that data can be easily accessed. Though all primitive data types are
represented by classes that inherit from the Data class, the ease-of-use interfaces do not return such references: all primitive
data types are returned by their intrinsic representation.
The EMA does not support immediately retrieving data from freshly created OMM containers or messages. The following code
snippet demonstrates this restriction:
Warning! The Data class and all classes that inherit from it are designed as temporary and short-lived objects. For this
reason, do not use them as storage or caching devices.
FieldList fieldList;
fieldList.addAscii( 1, "ascii" ).addInt( 10, 20 ).complete();
while ( fieldList.forth() )
{
const FieldEntry& fieldEntry = fieldList.getEntry();
...
}
Chapter 3 OMM Containers and Messages
Elektron Message API 3.1.X C++ Edition – Developers Guide 14
EMAC312UM.180
3.2.4 Msg Class
The Msg class is a parent class for all the message classes. It defines all the interfaces that are common across all message
classes.
3.2.5 OmmError Class
The OmmError class is a special purpose class. It is a read only class implemented in the EMA to notify applications about
errors detected while processing received data. This class enables applications to learn what error condition was detected.
Additionally it provides the getAsHex() method to obtain binary data associated with the detected error condition. The sole
purpose of this class is to aid in debugging efforts.
The following code snippet presents usage of the OmmError class while processing ElementList.
3.2.6 TunnelStreamRequest and ClassOfService Classes
The TunnelStreamRequest class specifies request information for use in establishing a tunnel stream. A tunnel stream is a
private stream that provides additional functionalities such as user authentication, end-to-end flow control, guaranteed
delivery, and persistency. You can configure these features on a per-tunnel stream basis. The ClassOfService class
specifies these features and some other related parameters. The identity of the tunnel stream is specified on the
TunnelStreamRequest class.
void decode( const ElementList& elementList )
{
while ( elementList.forth() )
{
const ElementEntry& elementEntry = elementList.getEntry();
if ( elementEntry.getCode() == Data::BlankEnum )
continue;
else
switch ( elementEntry.getLoadType() )
{
case DataType::RealEnum:
cout << elementEntry.getReal().getAsDouble() << endl;
break;
case DataType::ErrorEnum:
cout << elementEntry.getError().getErrorCode() << "( " <<
elementEntry.getError().getErrorCodeAsString() << " )" << endl;
break;
}
}
}
Chapter 3 OMM Containers and Messages
Elektron Message API 3.1.X C++ Edition – Developers Guide 15
EMAC312UM.180
3.3 Working with OMM Containers
EMA supports the following OMM containers: ElementList, FieldList, FilterList, Map, Series, and Vector.
Each of these classes provides set type interfaces for container header information (e.g., dictionary id, element list number,
and the add-type interfaces for adding entries). You must set the container header and optional summary before adding the
first entry.
Though it is treated as an OMM primitive, the OmmArray acts like a container and therefore provides add-type interfaces for
adding primitive entries.
3.3.1 Example: Populating a FieldList Class
The following example illustrates how to populate a FieldList class with fluid interfaces.
Note: OMM Container classes do perform some validation of their usage. If a usage error is detected, an appropriate
OmmException will be thrown.
try {
FieldList fieldList;
fieldList.info( 1, 1 )
.addUInt( 1, 64 )
.addReal( 6, 11, OmmReal::ExponentNeg2Enum )
.addDate( 16, 1999, 11, 7 )
.addTime( 18, 02, 03, 04, 005 )
.complete();
} catch ( const OmmException & excp ) {
cout << excp << endl;
}
Chapter 3 OMM Containers and Messages
Elektron Message API 3.1.X C++ Edition – Developers Guide 16
EMAC312UM.180
3.3.2 Example: Populating a Map Class Relying on the FieldList Memory Buffer
The following code snippet illustrates how to populate a Map class with summary data and a single entry containing a
FieldList. In this example, the FieldList class uses its own memory buffer to store content while it is populated. This
buffer later gets copied to the buffer owned by the Map class. This container population model applies to all OMM containers
that might contain other containers, primitives, or messages.
3.3.3 Example: Populating a Map Class Relying on the Map Class Buffer
The following example illustrates how to populate a Map class with a single entry containing a FieldList. In this case, the
FieldList class uses the memory buffer owned by the Map class to store its own content while it is populated, therefore
avoiding the internal buffer copy described in Section 3.3.2. This container population model applies to iterable containers only
(e.g., OmmArray, ElementList, FieldList, FilterList, Map, Series, and Vector).
try {
FieldList fieldList;
fieldList.addUInt( 1, 64 )
.addReal( 6, 11, OmmReal::ExponentNeg2Enum )
.addDate( 16, 1999, 11, 7 )
.addTime( 18, 02, 03, 04, 005 )
.complete();
Map map;
map .summary( fieldList ).addKeyAscii( "entry_1", MapEntry::AddEnum, fieldList
).complete();
} catch ( const OmmException& excp ) {
cout << excp << endl;
}
try {
FieldList fieldList;
Map map;
map.addKeyAscii( "entry_1", MapEntry::AddEnum, fieldList );
fieldList.addUInt( 1, 64 )
.addReal( 6, 11, OmmReal::ExponentNeg2Enum )
.addDate( 16, 1999, 11, 7 )
.addTime( 18, 02, 03, 04, 005 )
.complete();
map.complete();
} catch ( const OmmException& excp ) {
cout << excp << endl;
}
Chapter 3 OMM Containers and Messages
Elektron Message API 3.1.X C++ Edition – Developers Guide 17
EMAC312UM.180
3.3.4 Example: Extracting Information from a FieldList Class
In the following example illustrates how to use the FieldList::forth() method to extract information from the
FieldList class by iterating over the class. The following code extracts information about all entries.
void decode( const FieldList& fieldList )
{
if ( fieldList.hasInfo() )
{
Int16 dictionaryId = fieldList.getInfoDictionaryId();
Int16 fieldListNum = fieldList.getInfoFieldListNum();
}
while ( fieldList.forth() )
{
const FieldEntry& fieldEntry = fieldList.getEntry();
if ( fieldEntry.getCode() == Data::BlankEnum )
continue;
switch ( fieldEntry.getLoadType() )
{
case DataType::AsciiEnum :
const EmaString& value = fieldEntry.getAscii();
break;
case DataType::IntEnum :
Int64 value = fieldEntry.getInt();
break;
}
}
}
Chapter 3 OMM Containers and Messages
Elektron Message API 3.1.X C++ Edition – Developers Guide 18
EMAC312UM.180
3.3.5 Example: Application Filtering on the FieldList Class
In the following code snippet application filters or extracts select information from FieldList class. The FieldList::forth( Int16 )
method is used to iterate over the FieldList class. In this case only entries with field id of 22 will be extracted; all the other ones
will be skipped.
3.3.6 Example: Extracting FieldList information using a Downcast Operation
The following example illustrates how to extract information from a FieldList object using the down-cast operation.
void decode( const FieldList& fieldList )
{
while ( fieldList.forth( 22 ) )
{
const FieldEntry& fieldEntry = fieldList.getEntry();
if ( fieldEntry.getCode() == Data::BlankEnum )
continue;
switch ( fieldEntry.getLoadType() )
{
case DataType::AsciiEnum :
const EmaString& value = fieldEntry.getAscii();
break;
case DataType::IntEnum :
Int64 value = fieldEntry.getInt();
break;
}
}
}
void AppClient::decodeFieldList( const FieldList& fl )
{
if ( fl.hasInfo() )
cout << "FieldListNum: " << fl.getInfoFieldListNum() << " DictionaryId: " << fl
fl.getInfoDictionaryId() << endl;
while ( fl.forth() )
}
cout << "Load" << endl;
decode( fl.getEntry().getLoad() );
}
}
void AppClient::decode( const Data& data )
{
if ( data.getCode() == Data::BlankEnum )
cout << "Blank data" << endl;
Chapter 3 OMM Containers and Messages
Elektron Message API 3.1.X C++ Edition – Developers Guide 19
EMAC312UM.180
else
switch ( data.getDataType() )
{
case DataType::RefreshMsgEnum :
decodeRefreshMsg( static_cast<const RefreshMsg&>( data ) );
break;
case DataType::UpdateMsgEnum :
decodeUpdateMsg( static_cast<const UpdateMsg&>( data ) );
break;
case DataType::FieldListEnum :
decodeFieldList( static_cast<const FieldList&>( data ) );
break;
case DataType::MapEnum :
decodeMap( static_cast<const Map&>( data ) );
break;
case DataType::NoDataEnum :
cout << "NoData" << endl;
break;
case DataType::TimeEnum :
cout << "OmmTime: " << static_cast<const OmmTime&>( data ).toString() << endl;
break;
case DataType::DateEnum :
cout << "OmmDate: " << static_cast<const OmmDate&>( data ).toString() << endl;
break;
case DataType::RealEnum :
cout << "OmmReal::getAsDouble: " << static_cast<const OmmReal&>( data
).getAsDouble() << endl;
break;
case DataType::IntEnum :
cout << "OmmInt: " << static_cast<const OmmInt&>( data ).getInt() << endl;
break;
case DataType::UIntEnum :
cout << "OmmUInt: " << static_cast<const OmmUInt&>( data ).getUInt() << endl;
break;
case DataType::EnumEnum :
cout << "OmmEnum: " << static_cast<const OmmEnum&>( data ).getEnum() << endl;
break;
case DataType::AsciiEnum :
cout << "OmmAscii: " << static_cast<const OmmAscii&>( data ).toString() << endl;
break;
case DataType::ErrorEnum :
cout << "Decoding error: " << static_cast<const OmmError&>( data
).getErrorCodeAsString() << endl;
break;
default :
break;
}
}
Chapter 3 OMM Containers and Messages
Elektron Message API 3.1.X C++ Edition – Developers Guide 20
EMAC312UM.180
3.4 Working with OMM Messages
EMA supports the following OMM messages: RefreshMsg, UpdateMsg, StatusMsg, AckMsg, PostMsg and GenericMsg.
As appropriate, each of these classes provide set and get type interfaces for the message header, permission, key, attribute,
and payload information.
3.4.1 Example: Populating the GenericMsg with an ElementList Payload
The following example illustrates how to populate a GenericMsg with a payload consisting of an ElementList.
3.4.2 Example: Extracting Information from the GenericMsg Class
The following example illustrates how to extract information from the GenericMsg class.
try {
GenericMsg genMsg;
genMsg.domainType( 200 ).name( "TR.N" ).serviceId( 234 ).payload( ElementList().addAscii(
"entry_1", "value_1" ).complete() );
} catch ( const OmmException& excp ) {
cout << excp << endl;
}
void decode( const GenericMsg& genMsg )
{
if ( genMsg.hasName() )
cout << endl << "Name: " << genMsg.getName();
if ( genMsg.hasHeader() )
const EmaBuffer& header = genMsg.getHeader();
switch ( genMsg.getPayload().getDataType() )
{
case DataType::FieldListEnum :
decode( genMsg.getPayload().getFieldList() );
break
}
}
Chapter 3 OMM Containers and Messages
Elektron Message API 3.1.X C++ Edition – Developers Guide 21
EMAC312UM.180
3.4.3 Example: Working with the TunnelStreamRequest Class
The following code snippet demonstrates using the TunnelStreamRequest class in the consumer application to open a
tunnel stream.
CosAuthentication cosAuthentication;
cosAuthentication.type( CosAuthentication::OmmLoginEnum );
CosDataIntegrity cosDataIntegrity;
cosDataIntegrity.type( CosDataIntegrity::ReliableEnum );
CosFlowControl cosFlowControl;
cosFlowControl.type( CosFlowControl::BidirectionalEnum ).recvWindowSize( 1200
).sendWindowSize( 1200 );
CosGuarantee cosGuarantee;
cosGuarantee.type( CosGuarantee::NoneEnum );
ClassOfService cos;
cos.authentication( cosAuthentication ).dataIntegrity( cosDataIntegrity ).flowControl(
cosFlowControl ).guarantee( cosGuarantee );
TunnelStreamRequest tsr;
tsr.classOfService( cos ).domainType( MMT_SYSTEM ).name( "TUNNEL" ).serviceName( "DIRECT_FEED" );
Chapter 4 Consumer Classes
Elektron Message API 3.1.X C++ Edition – Developers Guide 22
EMAC312UM.180
Chapter 4 Consumer Classes
4.1 OmmConsumer Class
The OmmConsumer class is the main consumer application interface to the EMA. This class encapsulates watchlist
functionality and transport level connectivity. It provides all the interfaces a consumer-type application needs to open, close,
and modify items, as well as submit messages to the connected server (both PostMsg and GenericMsg). The
OmmConsumer class provides configurable admin domain message processing (i.e., login, directory, and dictionary requests).
4.1.1 Connecting to a Server and Opening Items
Applications observe the following steps to connect to a server and open items:
(Optional) Specify a configuration using the EmaConfig.xml file.
This step is optional because the EMA provides a default configuration which is usually sufficient in simple application
cases.
Create OmmConsumerConfig object (for details, refer to Section 4.3).
(Optional) Change EMA configuration using methods on the OmmConsumerConfig class.
If an EmaConfig.xml file is not used, then at a minimum, applications might need to modify the default host address
and port.
Implement an application callback client class that inherits from the OmmConsumerClient class (for details, refer to
Section 4.2).
An application needs to override the default implementation of callback methods and provide its own business logic.
Not all methods need to be overridden; only methods required for the application’s business logic.
(Optional) Implement an application error client class that inherits from the OmmConsumerErrorClient class (for
details, refer to Section 6.2).
The application needs to override default error call back methods to be effectively notified about error conditions.
Create an OmmConsumer object and pass the OmmConsumerConfig object (and if needed, also pass in the
application error client object), and optionally register for Login events by passing in an application callback client
class.
Open items of interest using the OmmConsumer::registerClient() method.
Process received messages.
(Optional) Submit PostMsg and GenericMsg messages and modify / close items using appropriate OmmConsumer
class methods.
•Exit.
4.1.2 Opening Items Immediately After OmmConsumer Object Instantiation
To allow applications to open items immediately after creating the OmmConsumer object, the EMA performs the following steps
when creating and initializing the OmmConsumer object:
Create an internal item watchlist.
Establish connectivity to a configured server / host.
Log into the server and obtain source directory information.
Obtain dictionaries (if configured to do so).
Chapter 4 Consumer Classes
Elektron Message API 3.1.X C++ Edition – Developers Guide 23
EMAC312UM.180
4.1.3 Destroying the OmmConsumer Object
Destroying an OmmConsumer object causes the application to log out and disconnect from the connected server, at which time
all items are closed.
4.1.4 Example: Working with the OmmConsumer Class
The following example illustrates the simplest application managing the OmmConsumer Class.
4.1.5 Working with Items
The EMA assigns all opened items or instruments a unique numeric identifier (e.g. UInt64), called a handle, which is returned
by the OmmConsumer::registerClient() call. A handle is valid as long as its associated item stays open. Holding onto
these handles is important only to applications that want to modify or close particular items, or use the items’ streams for
sending PostMsg or GenericMsg messages to the connected server. Applications that just open and watch several items
until they exit do not need to store item handles.
While opening an item, on the call to the OmmConsumer::registerClient() method, an application can pass an item
closure or an application-assigned numeric value. The EMA will maintain the association of the item to its closure as long as
the item stays open.
Respective closures and handles are returned to the application in an OmmConsumerEvent object on each item callback
method.
try {
AppClient client;
OmmConsumer consumer( OmmConsumerConfig().host( "localhost:14002" ).username( "user" ) );
consumer.registerClient( ReqMsg().serviceName( "DIRECT_FEED" ).name( "IBM.N" ), client );
sleep( 60000 );
} catch ( const OmmException& excp ) {
cout << excp << endl;
}
Chapter 4 Consumer Classes
Elektron Message API 3.1.X C++ Edition – Developers Guide 24
EMAC312UM.180
4.1.6 Example: Working with Items
The following example illustrates using the item handle while modifying an item’s priority and posting modified content.
void AppClient::onRefreshMsg( const RefreshMsg& refreshMsg, const OmmConsumerEvent& event )
{
cout << “Received refresh message for item handle = “ << event.getHandle() << endl;
cout << refreshMsg << endl;
}
try {
AppClient client;
OmmConsumer consumer( OmmConsumerConfig().host( "localhost:14002" ).username( "user" ) );
Int64 closure = 1;
UInt64 itemHandle = consumer.registerClient( ReqMsg().serviceName( "DIRECT_FEED" ).name(
"IBM.N" ), client, (void*)closure );
consumer.reissue( ReqMsg().serviceName( "DIRECT_FEED" ).name( "IBM.N" ).priority( 2, 2 ),
itemHandle );
consumer.submit( PostMsg().payload( FieldList().addInt( 1, 100 ).complete() ), itemHandle
);
sleep( 60000 );
} catch ( const OmmException& excp ) {
cout << excp << endl;
}
Chapter 4 Consumer Classes
Elektron Message API 3.1.X C++ Edition – Developers Guide 25
EMAC312UM.180
4.2 OmmConsumerClient Class
4.2.1 OmmConsumerClient Description
The OmmConsumerClient class provides a callback mechanism through which applications receive OMM messages on
items for which they subscribe. The OmmConsumerClient is a parent class that implements empty, default callback methods.
Applications must implement their own class (inheriting from OmmConsumerClient), and override the methods they are
interested in processing. Applications can implement many specialized client-type classes; each according to their business
needs and design. Instances of client-type classes are associated with individual items while applications register item
interests.
The OmmConsumerClient class provides default implementation for the processing of RefreshMsg, UpdateMsg,
StatusMsg, AckMsg and GenericMsg messages. These messages are processed by their respectively named methods:
onRefreshMsg(), onUpdateMsg(), onStatusMsg(), onAckMsg(), and onGenericMsg(). Applications only need to
override methods for messages they want to process.
4.2.2 Example: OmmConsumerClient
The following example illustrates an application client-type class, depicting onRefreshMsg() method implementation.
class AppClient : public thomsonreuters::ema::access::OmmConsumerClient
{
protected :
void onRefreshMsg( const thomsonreuters::ema::access::RefreshMsg&, const
thomsonreuters::ema::access::OmmConsumerEvent& );
void onUpdateMsg( const thomsonreuters::ema::access::UpdateMsg&, const
thomsonreuters::ema::access::OmmConsumerEvent& );
void onStatusMsg( const thomsonreuters::ema::access::StatusMsg&, const
thomsonreuters::ema::access::OmmConsumerEvent& );
};
void AppClient::onRefreshMsg( const RefreshMsg& refreshMsg, const OmmConsumerEvent& )
{
if ( refreshMsg.hasMsgKey() )
cout << endl << "Item Name: " << refreshMsg.getName() << endl << "Service Name: " <<
refreshMsg.getServiceName();
cout << endl << "Item State: " << refreshMsg.getState().toString() << endl;
if ( DataType::NoDataEnum != refreshMsg.getPayload().getDataType() )
decode( refreshMsg.getPayload().getData() );
}
Chapter 4 Consumer Classes
Elektron Message API 3.1.X C++ Edition – Developers Guide 26
EMAC312UM.180
4.3 OmmConsumerConfig Class
4.3.1 OmmConsumerConfig Description
You can use the OmmConsumerConfig class to customize the functionality of the OmmConsumer class. The default behavior
of OmmConsumer is hard coded in the OmmConsumerConfig class. You can configure OmmConsumer in any of the following
ways:
Using the EmaConfig.xml file
Using interface methods on the OmmConsumerConfig class
Passing OMM-formatted configuration data through the OmmConsumerConfig::config( const Data& ) method.
For more details on using the OmmConsumerConfig class and associated configuration parameters, refer to the EMA
Configuration Guide.
4.3.2 Tunneling Configuration
Consumer applications can establish tunneling Internet connections via either HTTP or HTTPS.
To tunnel using HTTP, EMA must use the connection type: ChannelType::RSSL_HTTP. EMA supports HTTP tunneling
only on the Windows platform.
To tunnel using HTTPS, EMA must use the connection type: ChannelType::RSSL_ENCRYPTED. When using this
connection type, additional configuration parameters apply. EMA supports HTTPS tunneling on both Windows and Linux
platforms.
You configure connection types in the EMA configuration file. After configuring the file with the appropriate tunneling
connection type, to connect the application via a proxy, call the tunnelingProxyHostName() and
tunnelingProxyPort() functions on the OmmconsumerConfig class. To specify an object name to pass along with the
underlying URL in connection messages, call tunnelingObjectName().
The EMA package provides a tunneling training example that showcases the usage of the EMA’s OmmConsumerConfig
interface configured for HTTP tunneling (i.e., ChannelType::RSSL_HTTP).
4.3.3 Additional Configurations for HTTPS Tunneling in Linux
In Linux, clients can also use the OmmConsumerConfig class to call tunnelingSecurityProtocol() to set security
protocols. By default, EMA uses only TLSV1.2. EMA supports several different versions of TLS security, specified by flag in
OmmConsumerConfig::EncryptionProtocolTypes. EMA supports the following flags:
TLSV1 (ENC_TLSV1)
TLSV1.1 (ENC_TLSV1_1)
TLSV1.2 (ENC_TLSV1_2)
If you do not want to use a security protocol, use ENC_NONE
If the encryption handshake fails, EMA automatically rolls back to a lower specified version. For example, you configure EMA
to support TLS1 and TLSV1.2. If EMA connects to a provider that supports TLSV1, EMA will first handshake using TLSV1.2. In
this case, the handshake fails, and EMA rolls back to TLSV1 and reattempts the handshake, which is successful.
Clients can specify alternative names for the OpenSSL and cryptography shared libraries by using the OmmConsumerConfig
class to call tunnelingLibSslName() and tunnelingLibCryptoName() respectively. The OpenSSL library name
defaults to libssl.so.10 while the cryptography library name defaults to libcrypto.so.10. When changing a name for a file, you
must specify both names: if you specify only one name, EMA ignores the new name and continues to use the default.
Chapter 5 Provider Classes
Elektron Message API 3.1.X C++ Edition – Developers Guide 27
EMAC312UM.180
Chapter 5 Provider Classes
5.1 OmmProvider Class
The OmmProvider class is the main provider application interface to the EMA. This class encapsulates transport-level
connectivity. It provides all the interfaces a provider-type application needs to submit item messages (i.e., refresh, update,
status, generic) as well as handle the login, directory, and dictionary domains (depending upon whether or not the application
is an interactive provider). The OmmProvider class provides configurable admin domain message processing (i.e., login,
directory, and dictionary).
5.1.1 Connecting to ADH and Submitting Items
In the following process, the value for ProviderType is dependent on the type of provider with which you are dealing:
For non-interactive providers, ProviderType is NiProvider.
For interactive providers, ProviderType is IProvider.
To establish a connection and submit items:
1. (Optional) Specify a configuration using the EmaConfig.xml file.
Specifying a configuration in EmaConfig.xml is optional because the EMA provides a default configuration which is usually
sufficient in simple application cases.
2. Create the appropriate OmmProviderTypeConfig object (for details, refer to Section 5.3):
For a non-interactive provider, create an OmmNiProviderConfig object.
For an interactive provider, create an OmmIProviderConfig object
3. (Optional) Change the EMA configuration using methods on the OmmProviderTypeConfig class.
If EmaConfig.xml file is not used, then at a minimum:
Non-interactive provider applications might need to modify both the default host address and port.
Interactive provider applications might need to modify the default port.
4. (Conditional) Implement an application callback client class that inherits from the OmmProviderClient class (for
details, refer to Section 5.2).
An application might need to override the default callback implementation and provide its own business logic. Not all
methods need to be overridden: only those that require the application’s business logic.
For non-interactive providers, this step is optional because the application may choose not to open login or dictionary
items. In such cases, the provider application will not receive return messages.
For interactive providers, this step is required, because at a minimum, the application needs to handle all inbound
login domain and item request messages.
5. (Optional) Implement an application error client class that inherits from the OmmProviderErrorClient class (for
details, refer to Section 5.2).
To be effectively notified about error conditions, the application needs to override any default, error callback methods.
6. Create an OmmProvider object and pass the OmmProviderTypeConfig object (and if needed, also pass in the
application error client object), and optionally in NiProvider only, register for Login events by passing in an application
callback client class.
Chapter 5 Provider Classes
Elektron Message API 3.1.X C++ Edition – Developers Guide 28
EMAC312UM.180
7. (Optional) For non-interactive providers, open login and dictionary items using the
OmmProvider::registerClient() method.
8. Process received messages.
9. Create, populate, and submit item messages (refresh, update, status).
For non-interactive providers, the application needs to associate each item with a handle that uniquely identifies the
item.
For interactive providers, the application needs to use the handle from the OMMProviderEvent.
10. (Optional) Submit GenericMsg messages using the appropriate OmmProvider class methods.
11. Exit.
Chapter 5 Provider Classes
Elektron Message API 3.1.X C++ Edition – Developers Guide 29
EMAC312UM.180
5.1.2 Non-Interactive Providers: Post OmmProvider Object Instantiation
After creating an OmmProvider object, the EMA performs the following steps when creating and initializing the OmmProvider
object so that applications can begin submitting items:
Establish connectivity to a configured server / host
Log into ADH and submit source directory information
5.1.3 Interactive Providers: Post OmmProvider Object Instantiation
Before an interactive provider can start submitting items, the application must first accept a login request. Though EMA
accepts connections, it is the responsibility of the application to send the login response. Subsequently, the consumer will
request the source directory, and EMA will respond by submitting the source directory.
After creating an OmmProvider object, the EMA observes the following process when creating and initializing the
OmmProvider object so that applications can begin submitting items:
Accept the connection request from a consumer
Accept the login
Submit the source directory information
5.1.4 Destroying the OmmProvider Object
For non-interactive providers, destroying an OmmProvider object causes the application to log out and disconnect from the
connected ADH, at which time all items are closed.
For interactive providers, destroying an OmmProvider object causes EMA to close all consumer connections.
Chapter 5 Provider Classes
Elektron Message API 3.1.X C++ Edition – Developers Guide 30
EMAC312UM.180
5.1.5 Non-Interactive Example: Working with the OmmProvider Class
The following example illustrates the simplest application managing the OmmProvider class.
try
{
OmmProvider provider( OmmNiProviderConfig().host( "localhost:14003").username
( "user" ) );
UInt64 itemHandle = 5;
provider.submit( RefreshMsg().serviceName( "NI_PUB" ).name( "IBM.N" )
.state( OmmState::OpenEnum, OmmState::OkEnum, OmmState::NoneEnum, "UnSolicited
Refresh Completed" )
.payload( FieldList()
.addReal( 22, 3990, OmmReal::ExponentNeg2Enum )
.addReal( 25, 3994, OmmReal::ExponentNeg2Enum )
.addReal( 30, 9, OmmReal::Exponent0Enum )
.addReal( 31, 19, OmmReal::Exponent0Enum )
.complete() )
.complete(), itemHandle );
sleep( 1000 );
for ( Int32 i = 0; i < 60; i++ )
{
provider.submit( UpdateMsg().serviceName( "NI_PUB" ).name( "IBM.N" )
.payload( FieldList()
.addReal( 22, 3391 + i, OmmReal::ExponentNeg2Enum )
.addReal( 30, 10 + i, OmmReal::Exponent0Enum )
.complete() ), itemHandle );
sleep( 1000 );
}
}
catch ( const OmmException& excp )
{
cout << excp << endl;
}
return 0;
}
Chapter 5 Provider Classes
Elektron Message API 3.1.X C++ Edition – Developers Guide 31
EMAC312UM.180
5.1.6 Interactive Provider Example: Working with the OmmProvider Class
The following example illustrates the simplest interactive application managing the OmmProvider class.
5.1.7 Working with Items
The application assigns unique numeric identifiers, called handles (e.g., UInt64) to all open items it is providing. Application
must pass this identifier along with an item message on the call to submit(). The handles are used to manage item stream
ids. To reassign a handle to a different item, application must first close the item previously associated with the given handle.
try
{
AppClient appClient;
OmmProvider provider( OmmIProviderConfig().port( "14002" ), appClient );
while ( itemHandle == 0 ) sleep(1000);
for ( Int32 i = 0; i < 60; i++ )
{
provider.submit( UpdateMsg().domainType( MMT_MARKET_BY_ORDER ).payload( Map()
.addKeyAscii( OrderNr, MapEntry::UpdateEnum, FieldList()
.addRealFromDouble( 3427, 7.76 + i * 0.1, OmmReal::ExponentNeg2Enum )
.addRealFromDouble( 3429, 9600 )
.addEnum( 3428, 2 )
.addRmtes( 212, EmaBuffer( "Market Maker", 12 ) )
.complete() )
.complete() ), itemHandle );
sleep( 1000 );
}
}
catch ( const OmmException& excp )
{
cout << excp << endl;
}
return 0;
Chapter 5 Provider Classes
Elektron Message API 3.1.X C++ Edition – Developers Guide 32
EMAC312UM.180
5.2 OmmProviderClient Class
5.2.1 OmmProviderClient Description
The OmmProviderClient class provides a callback mechanism through which applications receive OMM messages on
items for which they subscribe. The OmmProviderClient is a parent class that implements empty, default callback methods.
Applications must implement their own class (inheriting from OmmProviderClient), and override the methods they are
interested in processing. Applications can implement many specialized client-type classes; each according to their business
needs and design. Instances of client-type classes are associated with individual items while applications register item
interests. The OmmProviderClient class provides default implementation for the processing of RefreshMsg, StatusMsg,
and GenericMsg messages. These messages are processed by their respectively named methods: onRefreshMsg(),
onStatusMsg(), onGenericMsg(), onRequest()1, onReIssue()1, onClose()1, and onPost()1. Applications only
need to override methods for messages they want to process.
5.2.2 Non-Interactive Example: OmmProviderClient
The following example illustrates an application client-type class, depicting onRefreshMsg() method implementation.
1. Interactive Provider Only
class AppClient : public thomsonreuters::ema::access::OmmProviderClient
{
protected :
void onRefreshMsg( const thomsonreuters::ema::access::RefreshMsg&, const
thomsonreuters::ema::access::OmmProviderEvent& );
void onStatusMsg( const thomsonreuters::ema::access::StatusMsg&, const
thomsonreuters::ema::access::OmmProviderEvent& );
bool _bConnectionUp;
};
void AppClient::onRefreshMsg( const RefreshMsg& refreshMsg, const OmmProviderEvent&
ommEvent )
{
cout << endl << "Handle: " << ommEvent.getHandle() << " Closure: " <<
ommEvent.getClosure() << endl;
cout << refreshMsg << endl;
if ( refreshMsg.getState().getStreamState() == OmmState::OpenEnum )
{
if ( refreshMsg.getState().getDataState() == OmmState::OkEnum )
_bConnectionUp = true;
else
_bConnectionUp = false;
}
else
_bConnectionUp = false;
}
Chapter 5 Provider Classes
Elektron Message API 3.1.X C++ Edition – Developers Guide 33
EMAC312UM.180
5.2.3 Interactive Example: OmmProviderClient
The following example illustrates an application client-type class, depicting onRefreshMsg() method implementation.
void AppClient::processLoginRequest( const ReqMsg& reqMsg, const OmmProviderEvent& event )
{
event.getProvider().submit(RefreshMsg().domainType(MMT_LOGIN).name(reqMsg.getName()).
nameType(USER_NAME).complete().solicited( true ).
state( OmmState::OpenEnum, OmmState::OkEnum, OmmState::NoneEnum,
"Login accepted" ),event.getHandle() );
}
void AppClient::processMarketByOrderRequest( const ReqMsg& reqMsg, const OmmProviderEvent&
event )
{
if ( itemHandle != 0 )
{
processInvalidItemRequest(reqMsg, event);
return;
}
event.getProvider().submit(RefreshMsg().domainType(MMT_MARKET_BY_ORDER).
name(reqMsg.getName()).serviceName(reqMsg.getServiceName()).solicited(true)
.summaryData( FieldList().addEnum( 15, 840 ).addEnum( 53, 1 ).addEnum( 3423, 1 ).
addEnum( 1709, 2 ).complete() )
.addKeyAscii( OrderNr, MapEntry::AddEnum, FieldList()
.addRealFromDouble( 3427, 7.76, OmmReal::ExponentNeg2Enum )
.addRealFromDouble( 3429, 9600 )
.addEnum( 3428, 2 )
.addRmtes( 212, EmaBuffer( "Market Maker", 12 ) )
.complete() )
.complete() )
.complete(), event.getHandle() );
itemHandle = event.getHandle();
}
void AppClient::processInvalidItemRequest( const ReqMsg& reqMsg, const OmmProviderEvent&
event )
{
event.getProvider().submit( StatusMsg().name( reqMsg.getName() ).serviceName(
reqMsg.getServiceName() )
.domainType( reqMsg.getDomainType() )
.state( OmmState::ClosedEnum, OmmState::SuspectEnum, OmmState::NotFoundEnum,
"Item not found" ),
Chapter 5 Provider Classes
Elektron Message API 3.1.X C++ Edition – Developers Guide 34
EMAC312UM.180
5.3 OmmNiProviderConfig Class
In the following section, the value for ProviderType is dependent on the type of provider with which you are dealing:
For non-interactive providers, ProviderType is NiProvider.
For interactive providers, ProviderType is IProvider.
You can use the OmmProviderTypeConfig class to customize the functionality of the OmmProvider class. The default
behavior of OmmProvider is hard coded in the OmmProviderTypeConfig class. You can configure OmmProvider in any of
the following ways:
Using the EmaConfig.xml file
Using interface methods on the OmmProviderTypeConfig class
Passing OMM-formatted configuration data through the OmmProviderTypeConfig::config( const Data& )
method.
For more details on using the OmmProviderTypeConfig class and associated configuration parameters, refer to the EMA
Configuration Guide.
event.getHandle() );
}
void AppClient::onReqMsg( const ReqMsg& reqMsg, const OmmProviderEvent& event )
{
switch ( reqMsg.getDomainType() )
{
case MMT_LOGIN:
processLoginRequest( reqMsg, event );
break;
case MMT_MARKET_BY_ORDER:
processMarketByOrderRequest( reqMsg, event );
break;
default:
processInvalidItemRequest( reqMsg, event );
break;
}
}
Chapter 5 Provider Classes
Elektron Message API 3.1.X C++ Edition – Developers Guide 35
EMAC312UM.180
5.4 OMMIProviderConfig
You can use the OmmNiProviderConfig class to customize the functionality of the OmmProvider class. The default
behavior of OmmProvider is hard coded in the OmmNiProviderConfig class. You can configure OmmProvider in any of
the following ways:
Using the EmaConfig.xml file
Using interface methods on the OmmNiProviderConfig class
Passing OMM-formatted configuration data through the OmmNiProviderConfig::config( const Data& ) method.
For more details on using the OmmNiProviderConfig class and associated configuration parameters, refer to the EMA
Configuration Guide.
Chapter 6 Troubleshooting and Debugging
Elektron Message API 3.1.X C++ Edition – Developers Guide 36
EMAC312UM.180
Chapter 6 Troubleshooting and Debugging
6.1 EMA Logger Usage
The EMA provides a logging mechanism useful for debugging runtime issues. In the default configuration, EMA is set to log
significant events encountered during runtime and direct logging output to a file. If needed, you can turn off logging, or direct its
output to stdout. Additionally, applications can configure the logging level at which the EMA logs event (to log every event,
only error events, or nothing). For further details on managing and configuring the EMS logging function, refer to the EMA
Configuration Guide.
6.2 Omm Error Client Classes
6.2.1 Error Client Description
EMA has two Error Client classes: OmmConsumerErrorClient and OmmProviderErrorClient. These two classes are
an alternate error notification mechanism in the EMA, which you can use instead of the default error notification mechanism
(i.e., OmmException, for details, refer to Section 6.3). Both mechanisms deliver the same information and detect the same
error conditions. To use Error Client, applications need to implement their own error client class, override the default
implementation of each method, and pass this Error Client class on the constructor to OmmConsumer and OmmProvider.
6.2.2 Example: Error Client
The following example illustrates an application error client and depicts simple processing of the onInvalidHandle()
method. In the following example, ClassName is either OmmConsumerErrorClient (for EMA consumer applications) or
OmmProviderErrorClient (for EMA provider applications).
class AppErrorClient : public ClassName
{
public :
void onInvalidHandle( UInt64 handle, const EmaString& text );
void onInaccessibleLogFile( const EmaString& filename, const EmaString& text );
void onMemoryExhaustion( const EmaString& text);
void onInvalidUsage( const EmaString& text);
void onSystemError( Int64 code, void* ptr, const EmaString& text );
};
void AppErrorclient::onInvalidHandle( UInt64 handle, const EmaString& text )
{
cout << "Handle = " << handle << endl << ", text = " << text <<endl;
}
Chapter 6 Troubleshooting and Debugging
Elektron Message API 3.1.X C++ Edition – Developers Guide 37
EMAC312UM.180
6.3 OmmException Class
If the EMA detects an error condition, the EMA might throw an exception. All exceptions in the EMA inherit from the parent
class OmmException, which provides functionality and methods common across all OmmException types.
The EMA supports the following exception types:
OmmInaccessibleLogFileException: Thrown when the EMA cannot open a log file for writing.
OmmInvalidConfigurationException: Thrown when the EMA detects an unrecoverable configuration error.
OmmInvalidHandleException: Thrown when an invalid / unrecognized item handle is passed in on OmmConsumer or
OmmProvider class methods.
OmmInvalidUsageException: Thrown when the EMA detects invalid interface usage.
OmmMemoryExhaustionException: Thrown when the EMA detects an out-of-memory condition.
OmmOutOfRangeException: Thrown when a passed-in parameter lies outside the valid range.
OmmSystemException: Thrown when the EMA detects a system exception.
OmmUnsupportedDomainTypeException: Thrown if domain type specified on a message is not supported.
Tip: Thomson Reuters recommends you use try and catch blocks during application development and QA to quickly
detect and fix any EMA usage or application design errors.
© 2015 - 2018 Thomson Reuters. All rights reserved.
Republication or redistribution of Thomson Reuters content, including by framing or
similar means, is prohibited without the prior written consent of Thomson Reuters.
'Thomson Reuters' and the Thomson Reuters logo are registered trademarks and
trademarks of Thomson Reuters and its affiliated companies.
Any third party names or marks are the trademarks or registered trademarks of the
relevant third party.
Document ID: EMAC312UM.180
Date of issue: 31 January 2018

Navigation menu