EMAJ_DevGuide EMAJ Dev Guide
User Manual:
Open the PDF directly: View PDF .
Page Count: 48
Download | |
Open PDF In Browser | View PDF |
Elektron Message API Java Edition V3.3.X ELEKTRON MESSAGE API DEVELOPERS GUIDE Document Version: 3.3.0 Date of issue: 26 March 2019 Document ID: EMAJ330UM.190 Legal Information © Thomson Reuters 2016 - 2019. 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 Java Edition 3.3.X - Developers Guide EMAJ330UM.190 2 Contents Contents Chapter 1 1.1 1.2 1.3 1.4 1.5 1.6 1.7 Guide Introduction ........................................................................................................... 5 About this Manual ........................................................................................................................................... Audience ......................................................................................................................................................... Programming Languages................................................................................................................................ Acronyms and Abbreviations .......................................................................................................................... References...................................................................................................................................................... Documentation Feedback ............................................................................................................................... Document Conventions................................................................................................................................... 5 5 5 6 7 7 7 Chapter 2 Product Overview............................................................................................................. 8 2.1 2.2 EMA Product Description ................................................................................................................................ 8 Product Documentation and Learning EMA.................................................................................................... 9 Consumer Examples ................................................................................................................................ 9 Provider Examples.................................................................................................................................... 9 Supported Features ...................................................................................................................................... 10 Product Architecture...................................................................................................................................... 12 EMA Consumer Architecture .................................................................................................................. 12 EMA Provider Architecture ..................................................................................................................... 12 EMA Codec Architecture ........................................................................................................................ 14 Tunnel Streams............................................................................................................................................. 14 2.2.1 2.2.2 2.3 2.4 2.4.1 2.4.2 2.4.3 2.5 Chapter 3 3.1 3.2 3.2.1 3.2.2 3.2.3 3.2.4 3.2.5 3.2.6 3.3 3.3.1 3.3.2 3.3.3 3.4 3.4.1 3.4.2 3.4.3 Chapter 4 4.1 4.1.1 4.1.2 4.1.3 4.1.4 4.1.5 4.1.6 4.1.7 4.1.8 4.2 OMM Containers and Messages ................................................................................... 15 Overview ....................................................................................................................................................... Classes ......................................................................................................................................................... DataType Class ...................................................................................................................................... DataCode Class...................................................................................................................................... Data Class .............................................................................................................................................. Msg Class ............................................................................................................................................... OmmError Class ..................................................................................................................................... TunnelStreamRequest and ClassOfService Classes ............................................................................. Working with OMM Containers ..................................................................................................................... Example: Populating a FieldList Class ............................................................................................... Example: Extracting Information from a FieldList Class ..................................................................... Example: Extracting FieldList information using a Downcast operation ................................................. Working with OMM Messages ...................................................................................................................... Example: Populating the GenericMsg with an ElementList Payload.................................................... Example: Extracting Information from the GenericMsg class ................................................................. Example: Working with the TunnelStreamRequest Class ...................................................................... 15 16 16 16 16 16 17 17 18 18 18 19 21 21 21 22 Consumer Classes ......................................................................................................... 23 OmmConsumer Class................................................................................................................................... Connecting to a Server and Opening Items............................................................................................ Opening Items Immediately After OmmConsumer Object Instantiation ................................................. Destroying the OmmConsumer Object................................................................................................... Example: Working with the OmmConsumer Class................................................................................. Working with Items ................................................................................................................................. Example: Working with Items ................................................................................................................. Working with Tunnel Streams................................................................................................................. Example: Working with Tunnel Streams................................................................................................. OmmConsumerClient Class.......................................................................................................................... Elektron Message API Java Edition 3.3.X - Developers Guide EMAJ330UM.190 23 23 23 24 24 24 25 26 26 28 3 4.2.1 4.2.2 4.3 4.3.1 4.3.2 4.3.3 Chapter 5 5.1 5.1.1 5.1.2 5.1.3 5.1.4 5.1.5 5.1.6 5.1.7 5.2 5.2.1 5.2.2 5.2.3 5.3 Chapter 6 6.1 6.2 6.3 6.3.1 6.3.2 6.4 6.5 6.6 6.6.1 6.6.2 Chapter 7 7.1 7.2 7.2.1 7.2.2 7.3 OmmConsumerClient Description .......................................................................................................... Example: OmmConsumerClient ............................................................................................................. OmmConsumerConfig Class ........................................................................................................................ OmmConsumerConfig Description ......................................................................................................... Tunneling Configuration.......................................................................................................................... Debugging a Tunneling Connection ....................................................................................................... 28 28 28 28 29 29 Provider Classes ............................................................................................................ 30 OmmProvider Class ...................................................................................................................................... Submitting Items ..................................................................................................................................... Non-Interactive Providers: Post OmmProvider Object Instantiation ....................................................... Interactive Providers: Post OmmProvider Object Instantiation............................................................... Uninitialize the OmmProvider Object...................................................................................................... Non-Interactive Example: Working with the OmmProvider Class........................................................... Interactive Provider Example: Working with the OmmProvider Class .................................................... Working with Items ................................................................................................................................. OmmProviderClient Class............................................................................................................................. OmmProviderClient Description ............................................................................................................. Non-Interactive Example: OmmProviderClient ....................................................................................... Interactive Provider Example: OmmProviderClient ................................................................................ OmmNiProviderConfig and OmmIProviderConfig Classes ........................................................................... 30 30 31 31 31 31 34 35 36 36 36 37 39 Consuming Data from the Cloud .................................................................................. 40 Overview ....................................................................................................................................................... Encrypted Connections ................................................................................................................................. Authentication Token Management .............................................................................................................. Obtaining a Token .................................................................................................................................. Login Reissue ......................................................................................................................................... Service Discovery ......................................................................................................................................... Consuming Market Data ............................................................................................................................... Cloud Connection Use Cases ....................................................................................................................... Session Management Use Case ............................................................................................................ Query Service Discovery ........................................................................................................................ 40 40 41 41 42 43 44 45 45 45 Troubleshooting and Debugging.................................................................................. 46 EMA Logger Usage....................................................................................................................................... OMM Error Client Classes ............................................................................................................................ OmmConsumerErrorClient and OmmProviderErrorClient Descriptions ................................................. Example: OmmConsumerErrorClient ..................................................................................................... OmmException Class.................................................................................................................................... Elektron Message API Java Edition 3.3.X - Developers Guide EMAJ330UM.190 46 46 46 46 47 4 Chapter 1 Guide Introduction 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 Java 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 Languages The Message API is written using the Java programming language taking advantage of the object oriented approach to design and development of API and applications. Elektron Message API Java Edition 3.3.X - Developers Guide EMAJ330UM.190 5 Chapter 1 1.4 Guide Introduction 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 EDP Elektron Data Platform 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 Elektron Message API Java Edition 3.3.X - Developers Guide EMAJ330UM.190 6 Chapter 1 1.5 Guide Introduction References 1. Elektron Message API Java Edition RDM Usage Guide 2. API Concepts Guide 3. Elektron Message API Java Configuration Guide 4. EMA Java Edition Reference Manual 5. Transport API Java Edition Value Added Components Developers Guide 6. Transport API Java 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 • Java 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 = new AppClient(); OmmConsumerConfig config = EmaFactory.createOmmConsumerConfig(); OmmConsumer consumer = EmaFactory.createOmmConsumer(config.operationModel(OperationModel.USER_DISPATCH) .host("localhost:14002").username("user")); ReqMsg reqMsg = EmaFactory.createReqMsg(); consumer.registerClient(reqMsg.domainType(EmaRdm.MMT_MARKET_BY_PRICE).serviceName ("DIRECT_FEED").name("BBH.ITC"), client); Elektron Message API Java Edition 3.3.X - Developers Guide EMAJ330UM.190 7 Chapter 2 Product Overview 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. • Abstracts and hides all the transport level functionality minimizing application involvement to just optional transport level configuration and server address specification. • Provides simple accessor 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. 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). Transport level functionality is abstracted, specialized, and encapsulated by the EMA in a few classes whose functionality is implied by their class name. Elektron Message API Java Edition 3.3.X - Developers Guide EMAJ330UM.190 8 Chapter 2 2.2 Product Overview 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 Java Edition Reference ManualJava and or to the features provided by their IDE (e.g., Eclipse). Note: EMA application developers should already be familiar with OMM and Market Data distribution systems. 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., int, String, and Buffer). • 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 an example is 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- and 400- series examples depict usage of particular EMA features such as user control of the source directory domain, login streaming, connection recovery, programmatic configuration, and etc. Elektron Message API Java Edition 3.3.X - Developers Guide EMAJ330UM.190 9 Chapter 2 2.3 Product Overview Supported Features FEATURE New in 3.1.2! Support for Programmatic Configuration of Provider and Consumer New in 3.1.2! Support for HTTP and ENCRYPTED Connection Types New in 3.1! Domain Representations for Admin Domain Login Messages DESCRIPTION You can use EMA to programmatically configure parameters for interactive and noninteractive providers as well as consumers in the EMA configuration file. For details, refer to the Elektron Message API Java Configuration Guide. EMA provides support for ChannelType::RSSL_HTTP and ChannelType::RSSL_ENCRYPTED connection types for EMA consumers. For further details, refer to Section 4.3. 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 New in 3.1! Enhanced Login Stream Handling New in 3.0.4! Interactive Provider New in 3.0.3! Non-interactive Provider New in 3.0.3! Connection Failover EMA provides support for the TREP Authentication feature for consumers and noninteractive providers. For more information, refer to EMA’s RDM Usage Guide and to the TREP Authentication user manuala. EMA applications can register for Login events when they create OmmConsumer or non-interactive OmmProvider objects. EMA provides interactive provider connectivity (e.g., for ADH or other directlyconnected consumers). Applications can connect to an ADH TREP component to non-interactively provide item data. 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. Table 2: Supported Features Elektron Message API Java Edition 3.3.X - Developers Guide EMAJ330UM.190 10 Chapter 2 FEATURE Default Admin Domain Messages Product Overview DESCRIPTION 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. 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::asHex() Applications can obtain binary representations of all OMM containers, primitives, and messages. Programmatic Configuration The application can programmatically specify and overwrite its EMA configuration for the consumer for the consumer, 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, reliable delivery, and flow control). Table 2: Supported Features (Continued) a. The TREP Authentication User Manual can be obtained on Thomson Reuters’s MyAccount portal under the DACS product content set. Elektron Message API Java Edition 3.3.X - Developers Guide EMAJ330UM.190 11 Chapter 2 2.4 Product Architecture 2.4.1 EMA Consumer Architecture Product Overview 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 Java 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.OperationModel.API_DISPATCH. If the OmmConsumerConfig operation model is set to the OmmConsumerConfig.OperationModel.USER_DISPATCH, 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. Warning! If the application delays in dispatching messages, it can result in slow consumer behavior. 2.4.2 EMA Provider Architecture The EMA provider incorporates the Value Added (VA) Reactor component from the Transport API, which provides transportlevel 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 Elektron Message API Java Edition 3.3.X - Developers Guide EMAJ330UM.190 12 Chapter 2 Product Overview OmmProviderErrorClient on the constructor of the OmmProvider class, which switches the error reporting from 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 Java 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.OperationModel.API_DISPATCH. If the operation model is set to OmmNiProviderConfig.OperationModel.USER_DISPATCH, EMA will not run a second thread. • For interactive providers, set the OmmIProviderConfig operation model to OmmIProviderConfig.OperationModel.API_DISPATCH. If the operation model is set to OmmIProviderConfig.OperationModel.USER_DISPATCH, 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.AdminControl.USER_CONTROL through the OmmNiProviderConfig::adminControlDirectory() method. • When running EMA as an interactive provider: the application must set OmmIProviderConfig.AdminControl.USER_CONTROL 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::adminControlDictionary() method. Note: If the user control is enabled, the application is responsible for sending the response messages. An EMA provider also supports the programmatic configuration of a source directory refresh of dictionary information, which overrides any configuration in EmaConfig.xml. To programmatically configure a source directory refresh: • When running EMA as a non-interactive provider: the application must set OmmNiProviderConfig::ApiControlEnum through the OmmNiProviderConfig::adminControlDirectory() method. An EMA non-interactive provider does not support programmatically configuring dictionary information. • When running EMA as an interactive provider: the application must set OmmIProviderConfig.AdminControl.API_CONTROL through the OmmIProviderConfig::adminControlDirectory() method. Additionally, you can programmatically configure dictionary information, which overrides any dictionary information defined from EmaConfig.xml. To programmatically configure dictionary information, set OmmIProviderConfig.AdminControl.API_CONTROL through the OmmIProviderConfig::adminControlDictionary() method. Elektron Message API Java Edition 3.3.X - Developers Guide EMAJ330UM.190 13 Chapter 2 2.4.3 Product Overview 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()). 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 reliable 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 Elektron Message API Java Edition 3.3.X - Developers Guide EMAJ330UM.190 14 Chapter 3 OMM Containers and Messages 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 Java Collections Framework approach is used to iterate over every OMM container. 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 load() interface to return a reference to the base Data class. The load() 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). Elektron Message API Java Edition 3.3.X - Developers Guide EMAJ330UM.190 15 Chapter 3 3.2 Classes 3.2.1 DataType Class OMM Containers and Messages 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.DataTypes.FIELD_LIST, DataType.DataTypes.REFRESH_MSG). You can use the Data::dataType() 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.DataTypes.ERROR, which indicates an error condition was detected. For more details, refer to Section 3.2.5. • DataType.DataTypes.NO_DATA, 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.NO_CODE indicates that the received data is valid and application may use it. • The DataCode.BLANK 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. 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. 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. Elektron Message API Java Edition 3.3.X - Developers Guide EMAJ330UM.190 16 Chapter 3 3.2.5 OMM Containers and Messages 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 asHex() 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. void decode( ElementList elementList ) { for (ElementEntry elementEntry : elementList) { if ( elementEntry.code() != Data.DataCode.BLANK ) switch (elementEntry.loadType()) { case DataTypes.REAL: System.out.println(elementEntry.real().asDouble()); break; case DataTypes.ERROR: System.out.println(elementEntry.error().errorCode() + " (" + elementEntry.error().errorCodeAsString() + ")"); break; } } } 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 and reliable delivery. 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. Elektron Message API Java Edition 3.3.X - Developers Guide EMAJ330UM.190 17 Chapter 3 3.3 OMM Containers and Messages Working with OMM Containers EMA supports the following OMM containers: ElementList, FieldList, FilterList, Map, Series, and Vector. Each of these classes extends the Java collections framework and 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. Note: OMM Container classes do perform some validation of their usage. If a usage error is detected, an appropriate OmmException will be thrown. 3.3.1 Example: Populating a FieldList Class The following example illustrates how to populate a FieldList class with fluid interfaces. FieldList fieldList = EmaFactory.createFieldList(); fieldList.info( 1, 1 ); fieldList.add( EmaFactory.createFieldEntry().uintValue( 1, 64 ) ); fieldList.add( EmaFactory.createFieldEntry().real( 6, 11, OmmReal.MagnitudeType.EXPONENT_NEG_2) ); fieldList.add( EmaFactory.createFieldEntry().date( 16, 1999, 11, 7 ) ); fieldList.add( EmaFactory.createFieldEntry().time( 18, 02, 03, 04, 005 ) ); 3.3.2 Example: Extracting Information from a FieldList Class In the following example illustrates how to extract information from the FieldList class by iterating over the class. The following code extracts information about all entries. void decode( FieldList fieldList ) { if ( fieldList.hasInfo() ) { int dictionaryId = fieldList.infoDictionaryId(); int fieldListNum = fieldList.infoFieldListNum(); } for( FieldEntry fieldEntry : fieldList ) { if( fieldEntry.code() != Data.DataCode.BLANK ) switch( fieldEntry.loadType() ) { case DataTypes.ASCII: System.out.println(fieldEntry.ascii()); break; case DataTypes.ERROR: System.out.println( elementEntry.error().errorCode() + " (" + Elektron Message API Java Edition 3.3.X - Developers Guide EMAJ330UM.190 18 Chapter 3 OMM Containers and Messages elementEntry.error().errorCodeAsString() + ")" ); break; } } } 3.3.3 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 decodeFieldList( FieldList fl) { if (fl.hasInfo()) System.out.println("FieldListNum: " + fl.infoFieldListNum() + " DictionaryId: " + fl.infoDictionaryId()); for (FieldEntry fieldEntry : fl) { System.out.println("Load"); decode(fieldEntry.load()); } } void decode(Data data) { if (Data.DataCode.BLANK == data.code()) System.out.println("Blank data"); else switch (data.dataType()) { case DataTypes.REFRESH_MSG : decodeRefreshMsg( (RefreshMsg)data ); break; case DataTypes.UPDATE_MSG : decodeUpdateMsg( (UpdateMsg)data ); break; case DataTypes.FIELD_LIST : decodeFieldList( (FieldList)data ); break; case DataTypes.MAP : decodeMap((Map)data); break; case DataTypes.NO_DATA : System.out.println("NoData"); break; case DataTypes.TIME : System.out.println("OmmTime: " + ((OmmTime)data).toString()); break; case DataTypes.DATE : Elektron Message API Java Edition 3.3.X - Developers Guide EMAJ330UM.190 19 Chapter 3 OMM Containers and Messages System.out.println("OmmDate: " + ((OmmDate)data).toString()); break; case DataTypes.REAL : System.out.println("OmmReal::asDouble: " + ((OmmReal)data).asDouble()); break; case DataTypes.INT : System.out.println("OmmInt: " + ((OmmInt)data).intValue()); break; case DataTypes.UINT : System.out.println("OmmUInt: " + ((OmmUInt)data).longValue()); break; case DataTypes.ENUM : System.out.println("OmmEnum: " + ((OmmEnum)data).enumValue()); break; case DataTypes.ASCII : System.out.println("OmmAscii: " + ((OmmAscii)data).ascii()); break; case DataTypes.ERROR : System.out.println("Decoding error: " + ((OmmError)data).errorCodeAsString()); break; default : break; } } Elektron Message API Java Edition 3.3.X - Developers Guide EMAJ330UM.190 20 Chapter 3 3.4 OMM Containers and Messages 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. GenericMsg genMsg = EmaFactory.createGenericMsg(); FieldList nestedFieldList = EmaFactory.createFieldList(); nestedFieldList.add(EmaFactory.createFieldEntry().real(22, 34, OmmReal.MagnitudeType.EXPONENT_POS_1)); genMsg.domainType( 200 ).name( "TR.N" ).serviceId( 234 ).payload( nestedFieldList ); 3.4.2 Example: Extracting Information from the GenericMsg class The following example illustrates how to extract information from the GenericMsg class. void decode( GenericMsg genMsg ) { if ( genMsg.hasName() ) System.out.println("Name: " + genMsg.name()); if ( genMsg.hasExtendedHeader() ) { ByteBuffer header = genMsg.extendedHeader(); } switch ( genMsg.payload().dataType() ) { case DataTypes.FIELD_LIST : decode( genMsg.payload().fieldList() ); break; } } Elektron Message API Java Edition 3.3.X - Developers Guide EMAJ330UM.190 21 Chapter 3 3.4.3 OMM Containers and Messages Example: Working with the TunnelStreamRequest Class The following example illustrates how to use a TunnelStreamRequest class in a consumer application to open a tunnel stream. ClassOfService cos = EmaFactory.createClassOfService(). authentication(EmaFactory.createCosAuthentication().type (CosAuthentication.CosAuthenticationType.OMM_LOGIN)) .dataIntegrity(EmaFactory.createCosDataIntegrity().type (CosDataIntegrity.CosDataIntegrityType.RELIABLE)) .flowControl(EmaFactory.createCosFlowControl().type (CosFlowControl.CosFlowControlType.BIDIRECTIONAL).recvWindowSize(1200)); TunnelStreamRequest tsr = EmaFactory.createTunnelStreamRequest().classOfService(cos) .domainType(EmaRdm.MMT_SYSTEM).name("TUNNEL").serviceName("DIRECT_FEED"); Elektron Message API Java Edition 3.3.X - Developers Guide EMAJ330UM.190 22 Chapter 4 Consumer Classes 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. • (Optional) Implement an application error client class that inherits from the OmmConsumerErrorClient class (for details, refer to Section 7.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 by calling OmmConsumer::uninitialize(). 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). Elektron Message API Java Edition 3.3.X - Developers Guide EMAJ330UM.190 23 Chapter 4 4.1.3 Consumer Classes Destroying the OmmConsumer Object Calling uninitialize() on 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. OmmConsumer consumer = null; try { AppClient client = new AppClient(); OmmConsumerConfig config = EmaFactory.createOmmConsumerConfig(); consumer = EmaFactory.createOmmConsumer( config.host("localhost:14002").username("user") ); ReqMsg reqMsg = EmaFactory.createReqMsg(); consumer.registerClient( reqMsg.serviceName("DIRECT_FEED").name("IBM.N"), client ); Thread.sleep( 60000 ); } catch (InterruptedException | OmmException excp) { System.out.println(excp.getMessage()); } finally { if (consumer != null) consumer.uninitialize(); } 4.1.5 Working with Items The EMA assigns all opened items or instruments a unique numeric identifier (e.g. long), 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. Elektron Message API Java Edition 3.3.X - Developers Guide EMAJ330UM.190 24 Chapter 4 4.1.6 Consumer Classes Example: Working with Items The following example illustrates using the item handle while modifying an item’s priority and posting modified content. void onRefreshMsg( RefreshMsg refreshMsg, OmmConsumerEvent event ) { System.out.println(“Received refresh message for item handle = “ + event.handle()); System.out.println(refreshMsg); } public static void main(String[] args) { OmmConsumer consumer = null; try { AppClient client = new AppClient(); OmmConsumerConfig config = EmaFactory.createOmmConsumerConfig(); consumer = EmaFactory.createOmmConsumer( config.host("localhost:14002").username("user") ); ReqMsg reqMsg = EmaFactory.createReqMsg(); long closure = 1; long itemHandle = consumer.registerClient( reqMsg.serviceName( "DIRECT_FEED" ).name( "IBM.N" ), client, closure ); consumer.reissue( reqMsg.serviceName( "DIRECT_FEED" ).name( "IBM.N" ).priority( 2, 2 ), itemHandle ); reqMsg.clear(); PostMsg postMsg = EmaFactory.createPostMsg(); FieldList nestedFieldList = EmaFactory.createFieldList(); nestedFieldList.add( EmaFactory.createFieldEntry().uintValue(1, 100) ); consumer.submit( postMsg.payload(nestedFieldList), itemHandle ); Thread.sleep( 60000 ); } catch (InterruptedException | OmmException excp) { System.out.println(excp.getMessage()); } finally { if (consumer != null) consumer.uninitialize(); } } Elektron Message API Java Edition 3.3.X - Developers Guide EMAJ330UM.190 25 Chapter 4 4.1.7 Consumer Classes Working with Tunnel Streams EMA assigns all tunnel streams a unique numeric identifier (e.g., long), called a parent handle, which is returned by the call: OmmConsumer.registerClient(TunnelStreamRequest,…). A parent handle is valid only as long as its associated tunnel stream is open. You can use parent handles to open substreams (as illustrated in Section 4.1.8). When opening a tunnel stream, on the call to the OmmConsumer.registerClient(TunnelStreamRequest,…) method, an application can pass a tunnel stream closure or an application-assigned numeric value. The EMA will maintain the association of the tunnel stream to its closure as long as the tunnel stream stays open. Respective closures and parent handles are returned to the application in an OmmConsumerEvent object on each tunnel stream callback method. For more details on a TunnelStreamRequest and how to create it, refer to Section 3.2.6 and Section 3.4.3. 4.1.8 Example: Working with Tunnel Streams The following example illustrates the use of a parent handle (as returned by OmmConsumer::registerClient(TunnelStreamRequest,…)) to open a substream from the OmmConsumerClient::onStatusMsg() callback. public void onStatusMsg(StatusMsg statusMsg, OmmConsumerEvent event) { if (event.getHandle() == _tunnelStreamHandle && statusMsg.hasState() && statusMsg.getState().getStreamState() == OmmState::OpenEnum ) { // open substream with parent handle returned when opening tunnel stream below _ommConsumer.registerClient(EmaFactory.createReqMsg().name("TUNNEL_IBM").serviceId(1), this, 1, _tunnelStreamHandle ); } } public static void main(String[] args) { OmmConsumer consumer = null; try { AppClient appClient = new AppClient(); _ommConsumer = EmaFactory.createOmmConsumer(EmaFactory.createOmmConsumerConfig().username("user")); ClassOfService cos = EmaFactory.createClassOfService().authentication(EmaFactory. createCosAuthentication().type(CosAuthentication.CosAuthenticationType.OMM_LOGIN)) .dataIntegrity(EmaFactory.createCosDataIntegrity().type(CosDataIntegrity. CosDataIntegrityType.RELIABLE)).flowControl(EmaFactory.createCosFlowControl(). type(CosFlowControl.CosFlowControlType.BIDIRECTIONAL).recvWindowSize(1200)); TunnelStreamRequest tsr = EmaFactory.createTunnelStreamRequest().classOfService(cos) .domainType(EmaRdm.MMT_SYSTEM).name("TUNNEL").serviceName("DIRECT_FEED"); /* open tunnel stream and save tunnel stream parent handle to be used for opening substreams Elektron Message API Java Edition 3.3.X - Developers Guide EMAJ330UM.190 26 Chapter 4 Consumer Classes in onStatusMsg() callback above */ _tunnelStreamHandle = _ommConsumer.registerClient(tsr, appClient)); Thread.sleep(60000); // API calls onRefreshMsg(), onUpdateMsg() and onStatusMsg() } catch (InterruptedException | OmmException excp) { System.out.println(excp.getMessage()); } finally { if (consumer != null) consumer.uninitialize(); } } Elektron Message API Java Edition 3.3.X - Developers Guide EMAJ330UM.190 27 Chapter 4 4.2 OmmConsumerClient Class 4.2.1 OmmConsumerClient Description Consumer Classes 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(). The onAllMsg() method processes any of these messages. 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 implements OmmConsumerClient { public void onRefreshMsg( RefreshMsg refreshMsg, OmmConsumerEvent event) { if ( refreshMsg.hasMsgKey() ) System.out.println("Item Name: " +refreshMsg.name() +"Service Name: " + refreshMsg.serviceName()); System.out.println("Item State: " + refreshMsg.state().toString()); if ( refreshMsg.payload().dataType() != DataTypes.NO_DATA ) decode( refreshMsg.payload().data() ); } } 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 For more details on using the OmmConsumerConfig class and associated configuration parameters, refer to the EMA Configuration Guide. Elektron Message API Java Edition 3.3.X - Developers Guide EMAJ330UM.190 28 Chapter 4 4.3.2 Consumer Classes Tunneling Configuration EMA supports tunneling across all platforms. 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. To tunnel using HTTPS, EMA must use the connection type: ChannelType::RSSL_ENCRYPTED. When using this connection type, additional configuration parameters apply. 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(). When tunneling, clients can use the OmmConsumerConfig class to specify security parameters such as: KeystoreType, KeystoreFile, KeystorePasswd, SecurityProvider, KeyManagerAlgorithm, and TrustManagerAlgorithm. The EMA uses the JDK java.security package. If the parameters KeystoreType, SecurityProvider, KeyManagerAlgorithm, or TrustManagerAlgorithm are not specified, the JDK java.security package provides default settings. Clients can also use the OmmConsumerConfig class to call tunnelingSecurityProtocol() to set a cryptographic protocol. EMA uses the Sun JDK default value of TLS (which will use the latest JDK-supported version of TLS). Warning! If you use an encrypted tunneling connection type, you might encounter trust issues with DigiCert certificates. JRE8 Update 91 and higher support DigiCert certificates. If you encounter problems with DigiCert certificates, upgrade to JRE8 Update 91 or higher. A tunneling connection might use proxy devices as it tunnels through the Internet. Client can configure some proxy servers to authenticate client applications before they pass through the proxy. The EMA API supports Negotiate(Kerberos), Kerberos, NTLM, and Basic authentication schemes. You also use the OmmConsumerConfig class to set credential parameters such as CredentialUsername, CredentialPasswd, CredentialDomain, CredentialKRB5ConfigFile, CredentialLocalHostName for Proxy Authentication. Note: If a consumer application needs NTLM authentication, the application must add the Apache jar files (in the load’s Libs/ Apache directory) to the CLASSPATH. 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 Debugging a Tunneling Connection To debug a tunneling consumer connection, add the following JVM argument when running the consumer: -Djavax.net.debug=all Debugging a tunneling connection with this argument provides SSL/TLS details that can be useful if the SSL/TLS handshake fails. Elektron Message API Java Edition 3.3.X - Developers Guide EMAJ330UM.190 29 Chapter 5 Provider Classes 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 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. Elektron Message API Java Edition 3.3.X - Developers Guide EMAJ330UM.190 30 Chapter 5 Provider Classes 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. 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 Uninitialize the OmmProvider Object For non-interactive providers, calling the OmmProvider.uninitialize() method causes the application to log out and disconnect from the connected ADH, at which time all items are closed. For interactive providers, calling the OmmProvider.uninitialize() method causes EMA to close all consumer connections. 5.1.5 Non-Interactive Example: Working with the OmmProvider Class The following example illustrates the simplest non-interactive application managing the OmmProvider class. OmmProvider provider = null; try { OmmNiProviderConfig config = EmaFactory.createOmmNiProviderConfig(); provider = EmaFactory.createOmmProvider( config.host( "localhost:14003" ).username( "user" ) ); Elektron Message API Java Edition 3.3.X - Developers Guide EMAJ330UM.190 31 Chapter 5 Provider Classes long itemHandle = 5; FieldList mapSummaryData = EmaFactory.createFieldList(); mapSummaryData.add( EmaFactory.createFieldEntry().enumValue( mapSummaryData.add( EmaFactory.createFieldEntry().enumValue( mapSummaryData.add( EmaFactory.createFieldEntry().enumValue( mapSummaryData.add( EmaFactory.createFieldEntry().enumValue( 15, 840 53, 1 ) 3423, 1 1709, 2 ) ); ); ) ); ) ); FieldList mapKeyAscii = EmaFactory.createFieldList(); mapKeyAscii.add( EmaFactory.createFieldEntry().realFromDouble( 3427, 7.76, MagnitudeType.EXPONENT_NEG_2 ) ); mapKeyAscii.add( EmaFactory.createFieldEntry().realFromDouble( 3429, 9600 ) ); mapKeyAscii.add( EmaFactory.createFieldEntry().enumValue( 3428, 2 ) ); mapKeyAscii.add( EmaFactory.createFieldEntry().rmtes( 212, ByteBuffer.wrap( "Market Maker".getBytes() ) ) ); Map map = EmaFactory.createMap(); map.summaryData( mapSummaryData ); map.add( EmaFactory.createMapEntry().keyAscii( "100", MapEntryActions.ADD, mapKeyAscii ) ); provider.submit( EmaFactory.createRefreshMsg().domainType( DomainTypes.MARKET_BY_ORDER ).serviceName( "NI_PUB" ).name( "AAO.V" ) .state( OmmState.StreamState.OPEN, OmmState.DataState.OK, OmmState.StatusCode.NONE, "UnSolicited Refresh Completed" ) .payload( map ).complete( true ), itemHandle ); Thread.sleep( 1000 ); for ( int i = 0; i < 60; i++ ) { mapKeyAscii = EmaFactory.createFieldList(); mapKeyAscii.add( EmaFactory.createFieldEntry().realFromDouble( 3427, 7.76 + i * 0.1, MagnitudeType.EXPONENT_NEG_2 ) ); mapKeyAscii.add( EmaFactory.createFieldEntry().realFromDouble( 3429, 9600 ) ); mapKeyAscii.add( EmaFactory.createFieldEntry().enumValue( 3428, 2 ) ); mapKeyAscii.add( EmaFactory.createFieldEntry().rmtes( 212, ByteBuffer.wrap( "Market Maker".getBytes() ) ) ); map = EmaFactory.createMap(); map.add( EmaFactory.createMapEntry().keyAscii( "100", MapEntryActions.ADD, mapKeyAscii ) ); provider.submit( EmaFactory.createUpdateMsg().serviceName( "NI_PUB" ).name( "AAO.V" ).domainType( DomainTypes.MARKET_BY_ORDER ).payload( map ), itemHandle ); Thread.sleep( 1000 ); Elektron Message API Java Edition 3.3.X - Developers Guide EMAJ330UM.190 32 Chapter 5 Provider Classes } } catch ( InterruptedException | OmmException excp ) { System.out.println( excp.getMessage() ); } finally { if ( provider != null ) provider.uninitialize(); } Elektron Message API Java Edition 3.3.X - Developers Guide EMAJ330UM.190 33 Chapter 5 5.1.6 Provider Classes Interactive Provider Example: Working with the OmmProvider Class The following example illustrates the simplest interactive application managing the OmmProvider class. OmmProvider provider = null; try { AppClient appClient = new AppClient(); FieldList fieldList = EmaFactory.createFieldList(); Map map = EmaFactory.createMap(); OmmIProviderConfig config = EmaFactory.createOmmIProviderConfig(); provider = EmaFactory.createOmmProvider(config.port("14002"), appClient); while(appClient.itemHandle == 0) Thread.sleep(1000); for( int i = 0; i < 60; i++ ) { fieldList.add(EmaFactory.createFieldEntry().realFromDouble(3427, 7.76 + i * 0.1, MagnitudeType.EXPONENT_NEG_2)); fieldList.add(EmaFactory.createFieldEntry().realFromDouble(3429, 9600)); fieldList.add(EmaFactory.createFieldEntry().enumValue(3428, 2)); fieldList.add(EmaFactory.createFieldEntry().rmtes(212, ByteBuffer.wrap("Market Maker".getBytes()))); map.add(EmaFactory.createMapEntry().keyAscii(appClient.OrderNr, MapEntry.MapAction.ADD, fieldList)); provider.submit( EmaFactory.createUpdateMsg().domainType(EmaRdm.MMT_MARKET_BY_ORDER).payload( map ), appClient.itemHandle ); map.clear(); fieldList.clear(); Thread.sleep(1000); } Thread.sleep(60000); } catch (InterruptedException | OmmException excp) { System.out.println(excp.getMessage()); } finally { if (provider != null) provider.uninitialize(); } Elektron Message API Java Edition 3.3.X - Developers Guide EMAJ330UM.190 34 Chapter 5 5.1.7 Provider Classes Working with Items The application assigns unique numeric identifiers, called handles (e.g., long) 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. Elektron Message API Java Edition 3.3.X - Developers Guide EMAJ330UM.190 35 Chapter 5 5.2 OmmProviderClient Class 5.2.1 OmmProviderClient Description Provider Classes 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. class AppClient implements OmmProviderClient { boolean _connectionUp; boolean isConnectionUp() { return _connectionUp; } public void onRefreshMsg(RefreshMsg refreshMsg, OmmProviderEvent event) { System.out.println("Received Refresh. Item Handle: " + event.handle() + " Closure: " + event.closure()); System.out.println("Item Name: " + (refreshMsg.hasName() ? refreshMsg.name() : "")); System.out.println("Service Name: " + (refreshMsg.hasServiceName() ? refreshMsg.serviceName() : " ")); System.out.println("Item State: " + refreshMsg.state()); if ( refreshMsg.state().streamState() == OmmState.StreamState.OPEN) { if (refreshMsg.state().dataState() == OmmState.DataState.OK) _connectionUp = true; else _connectionUp = false; } else 1. Interactive Provider Only Elektron Message API Java Edition 3.3.X - Developers Guide EMAJ330UM.190 36 Chapter 5 Provider Classes _connectionUp = false; } public void onStatusMsg(StatusMsg statusMsg, OmmProviderEvent event) { System.out.println("Received Status. Item Handle: " + event.handle() + " Closure: " + event.closure()); System.out.println("Item Name: " + (statusMsg.hasName() ? statusMsg.name() : " ")); System.out.println("Service Name: " + (statusMsg.hasServiceName() ? statusMsg.serviceName() : " ")); if (statusMsg.hasState()) { System.out.println("Item State: " +statusMsg.state()); if ( statusMsg.state().streamState() == OmmState.StreamState.OPEN) { if (statusMsg.state().dataState() == OmmState.DataState.OK) _connectionUp = true; else { _connectionUp = false; } } else _connectionUp = false; } } public void onGenericMsg(GenericMsg genericMsg, OmmProviderEvent event){} public void onAllMsg(Msg msg, OmmProviderEvent event){} } 5.2.3 Interactive Provider Example: OmmProviderClient class AppClient implements OmmProviderClient { public long itemHandle = 0; public String OrderNr="100"; public void onReqMsg(ReqMsg reqMsg, OmmProviderEvent event) { switch (reqMsg.domainType()) { case EmaRdm.MMT_LOGIN : Elektron Message API Java Edition 3.3.X - Developers Guide EMAJ330UM.190 37 Chapter 5 Provider Classes processLoginRequest(reqMsg, event); break; case EmaRdm.MMT_MARKET_BY_ORDER : processMarketByOrderRequest(reqMsg, event); break; default : processInvalidItemRequest(reqMsg, event); break; } } public public public public public public public void void void void void void void onRefreshMsg(RefreshMsg refreshMsg,OmmProviderEvent event){} onStatusMsg(StatusMsg statusMsg, OmmProviderEvent event){} onGenericMsg(GenericMsg genericMsg, OmmProviderEvent event){} onPostMsg(PostMsg postMsg, OmmProviderEvent event){} onReissue(ReqMsg reqMsg, OmmProviderEvent event){} onClose(ReqMsg reqMsg, OmmProviderEvent event){} onAllMsg(Msg msg, OmmProviderEvent event){} void processLoginRequest(ReqMsg reqMsg, OmmProviderEvent event) { event.provider().submit( EmaFactory.createRefreshMsg().domainType(EmaRdm.MMT_LOGIN). name(reqMsg.name()).nameType(EmaRdm.USER_NAME).complete(true).solicited(true). state(OmmState.StreamState.OPEN, OmmState.DataState.OK, OmmState.StatusCode.NONE, "Login accepted"), event.handle() ); } void processMarketByOrderRequest(ReqMsg reqMsg, OmmProviderEvent event) { if( itemHandle != 0 ) { processInvalidItemRequest(reqMsg, event); return; } FieldList mapSummaryData = EmaFactory.createFieldList(); mapSummaryData.add(EmaFactory.createFieldEntry().enumValue(15, 840)); mapSummaryData.add(EmaFactory.createFieldEntry().enumValue(53, 1)); mapSummaryData.add(EmaFactory.createFieldEntry().enumValue(3423, 1)); mapSummaryData.add(EmaFactory.createFieldEntry().enumValue(1709, 2)); FieldList entryData = EmaFactory.createFieldList(); entryData.add(EmaFactory.createFieldEntry().realFromDouble(3427, 7.76, MagnitudeType.EXPONENT_NEG_2)); entryData.add(EmaFactory.createFieldEntry().realFromDouble(3429, 9600)); entryData.add(EmaFactory.createFieldEntry().enumValue(3428, 2)); entryData.add(EmaFactory.createFieldEntry().rmtes(212, ByteBuffer.wrap("Market Maker".getBytes()))); Map map = EmaFactory.createMap(); Elektron Message API Java Edition 3.3.X - Developers Guide EMAJ330UM.190 38 Chapter 5 Provider Classes map.summaryData(mapSummaryData); map.add(EmaFactory.createMapEntry().keyAscii(OrderNr, MapEntry.MapAction.ADD, entryData)); event.provider().submit( EmaFactory.createRefreshMsg(). domainType(EmaRdm.MMT_MARKET_BY_ORDER).name(reqMsg.name()). serviceName(reqMsg.serviceName()).solicited(true). state(OmmState.StreamState.OPEN, OmmState.DataState.OK, OmmState.StatusCode.NONE, "Refresh Completed").payload(map).complete(true), event.handle() ); itemHandle = event.handle(); } void processInvalidItemRequest(ReqMsg reqMsg, OmmProviderEvent event) { event.provider().submit( EmaFactory.createStatusMsg().name(reqMsg.name()). serviceName(reqMsg.serviceName()).state(OmmState.StreamState.CLOSED, OmmState.DataState.SUSPECT,OmmState.StatusCode.NOT_FOUND, "Item not found"), event.handle() ); } } 5.3 OmmNiProviderConfig and OmmIProviderConfig Classes 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 For more details on using the OmmProviderTypeConfig class and associated configuration parameters, refer to the EMA Configuration Guide. Elektron Message API Java Edition 3.3.X - Developers Guide EMAJ330UM.190 39 Chapter 6 Consuming Data from the Cloud Chapter 6 Consuming Data from the Cloud 6.1 Overview You can use the Elektron Message API to consume data from a cloud-based ADS server. The API interacts with cloud-based servers using the following work flows: • • • • Obtaining a Token (for details, refer to Section 6.3.1) Service Discovery (for details, refer to Section 6.4) Consuming Market Data (for details, refer to Section 6.5) Login Reissue (for details, refer to Section 6.3.2) By default, for cloud connections the Elektron Message API connects to a server in the us-east cloud location. For further details on Elektron as it functions within the cloud, refer to the Elektron Real Time in Cloud: Installation and Configuration for Client Use. For details on the parameters you use to configure cloud connections, refer to the EMA Java Edition Configuration Guide. 6.2 Encrypted Connections When connecting to an ADS in the cloud, you must use a ChannelType of RSSL_ENCRYPTED (for details on ChannelType, refer to the EMA Java Configuration Guide). Elektron Message API 3.3.X Java Edition – Developers Guide EMAJ330UM.190 40 Chapter 6 6.3 Authentication Token Management 6.3.1 Obtaining a Token Consuming Data from the Cloud Obtaining an authentication token consists of an ESDK API sending its client ID and username and password in a single message to the EDP Gateway. Client ID is optional, and the Elektron Message API will use the username if the client ID is missing. In response, the EDP sends an authentication token, its expiration timeout, and a refresh token for use in the login reissue process (for details on the expiration timeout and login reissue process, refer to Section 6.3.2). The API must obtain a token before executing a service discovery or obtaining market data. The following diagram illustrates the process by which the ESDK API obtains its token: Figure 2. Obtaining an Authentication Token Elektron Message API 3.3.X Java Edition – Developers Guide EMAJ330UM.190 41 Chapter 6 6.3.2 Consuming Data from the Cloud Login Reissue When the Elektron Message API obtains a token from the EDP, the EDP also sends a refresh token and an expiration timeout. The expiration timeout sets the length of time for which the token is valid. The Elektron Message API multiplies the timeout by 4/5 (i.e., 0.8) to calculate the frequency with which the Elektron Message API initiates the login reissue process. To keep the connection alive, the Elektron Message API sends the refresh token to initiate the login reissue process. The EDP Gateway responds with a new token, the expiration timeout, and a new refresh token. If the ADS does not receive a refresh token before the end of the expiration timeout, the ADS closes the connection. The login reissue process is illustrated in the following diagram: Figure 3. Login Reissue Elektron Message API 3.3.X Java Edition – Developers Guide EMAJ330UM.190 42 Chapter 6 6.4 Consuming Data from the Cloud Service Discovery After obtaining a token (for details, refer to Section 6.3.1), the Elektron Message API can perform a service discovery against the EDP Gateway (whose URL is set in OmmConsumerConfig) to obtain connection details for the ADS in the cloud. In response to a service discovery, the EDP returns transport and data format protocols and a list of hosts and associated ports for the requested service(s) (i.e., an ADS running in the cloud). Refinitiv provides multiple cloud locations based on region, which is significant in how an Elektron Message API chooses the IP address and port to use when connecting to the cloud. From the list sent by the EDP Gateway, the Elektron Message API identifies an ADS (i.e., an endpoint) set up for failover and whose regional location matches the API’s location setting in ChannelGroup (for details, refer to Section 3.3.2). If you do not specify a location, the Elektron Message API defaults to the us-east cloud location. An endpoint setup for failover lists multiple locations in its location field (e.g., location: [us-east-1a, us-east-1b]). If multiple endpoints are set up for failover, the Elektron Message API chooses to connect to the first endpoint listed. Figure 4. Service Discovery Elektron Message API 3.3.X Java Edition – Developers Guide EMAJ330UM.190 43 Chapter 6 6.5 Consuming Data from the Cloud Consuming Market Data After obtaining its login token (for details, refer to Section 6.3.1) and running a service discovery (for details, refer to Section 6.4), the API can connect to the ADS in the cloud and obtain market data. While consuming market data, the API must periodically renew its token via the login reissue workflow (for details, refer to Section 6.3.2). Elektron Message API 3.3.X Java Edition – Developers Guide EMAJ330UM.190 44 Chapter 6 6.6 Consuming Data from the Cloud Cloud Connection Use Cases You can connect to the cloud and consume data according to the following use cases: • • Start to finish session management (for details, refer to Section 6.6.1) Query service discovery (for details, refer to Section 6.6.2) 6.6.1 Session Management Use Case In the session management use case, the Elektron Message API manages the entire connection from start to finish. To use session management, you need to configure the API to enable session management (i.e., in the ChannelGroup, set the Channel entry parameter EnableSessionManagement). The API exhibits the following behavior (listed in order) when operating in a session management use case: • • • • Obtains a token (according to the details in Section 6.3.1) Queries service discovery (according to the details in Section 6.4) Consumes market data (according to the details in Section 6.5) Manages login reissues when needed on a cyclical basis (according to the details in Section 6.3.2) EMA’s Consumer example (113__MarketPrice__SessionManagement example) provides sample source to illustrate session management. A special use case exists for connecting to a specific (i.e., non-default) host. As described in Section 6.4, by default the Elektron Message API connects to whichever host is setup for failover in the location specified by the API. If you want to connect to a specific, non-default host (perhaps your Refinitiv representative assigned you a specific host), you must set this in the ChannelGroup parameters: Host and Port. In this case, the Elektron Message API exhibits the same behavior listed above, but ignores the endpoints it receives from the service discovery. 6.6.2 Query Service Discovery In the query service discovery use case, the API user wants to connect to the EDP Gateway only for a service discovery, and does not necessarily want to consume market data. The API exhibits the following behavior (listed in order) when operating in a query service discovery use case: • • Obtains a token (according to the details in Section 6.3.1) Queries service discovery (according to the details in Section 6.4) EMA’s Consumer example (450__MarketPrice__QueryServiceDiscovery) provides sample source that discovers an endpoint using the service discovery feature and establishes an encrypted connection to consume data. Elektron Message API 3.3.X Java Edition – Developers Guide EMAJ330UM.190 45 Chapter 7 Troubleshooting and Debugging Chapter 7 Troubleshooting and Debugging 7.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. The EMA uses the SLF4J logging API, in which you can have the underlying logging backend be the Java standard logger utility package (java.util.logging), log4j, or other logger adapters which implement the SLF4J logging interface. 7.2 OMM Error Client Classes 7.2.1 OmmConsumerErrorClient and OmmProviderErrorClient Descriptions 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 7.3). 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. 7.2.2 Example: OmmConsumerErrorClient The following example illustrates an application error client and depicts simple processing of the onInvalidHandle() method. class AppErrorClient implements OmmConsumerErrorClient { public void onInvalidHandle( long handle, String text ) { System.out.println("Handle = " + handle + ", text = " + text); } public void onInvalidUsage( String text ) { System.out.println("Invalid Usage: " + text); } } Elektron Message API Java Edition 3.3.X - Developers Guide EMAJ330UM.190 46 Chapter 7 7.3 Troubleshooting and Debugging 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. 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. The EMA supports the following exception types: • • OmmInvalidConfigurationException: Thrown when the EMA detects an unrecoverable configuration error. • • • OmmInvalidUsageException: Thrown when the EMA detects invalid interface usage. OmmInvalidHandleException: Thrown when an invalid / unrecognized item handle is passed in on OmmConsumer or OmmProvider class methods. OmmOutOfRangeException: Thrown when a passed-in parameter lies outside the valid range. OmmUnsupportedDomainTypeException: Thrown if domain type specified on a message is not supported. Elektron Message API Java Edition 3.3.X - Developers Guide EMAJ330UM.190 47 © 2016 - 2019 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: EMAJ330UM.190 Date of issue: 26 March 2019
Source Exif Data:
File Type : PDF File Type Extension : pdf MIME Type : application/pdf PDF Version : 1.6 Linearized : No Author : U0116273 Create Date : 2019:03:25 17:07:42Z Modify Date : 2019:03:25 17:31:50-05:00 Language : en Tagged PDF : Yes XMP Toolkit : Adobe XMP Core 5.4-c006 80.159825, 2016/09/16-03:31:08 Format : application/pdf Creator : U0116273 Title : EMAJ_DevGuide.book Creator Tool : FrameMaker 2015.1 Metadata Date : 2019:03:25 17:31:50-05:00 Producer : Acrobat Distiller 11.0 (Windows) Document ID : uuid:b2ad4d46-cc5c-4d26-885e-030ccd6861db Instance ID : uuid:9652762a-a83f-4817-a881-984e1a637c3b Page Mode : UseOutlines Page Count : 48EXIF Metadata provided by EXIF.tools