Download tutorial source code |
Click here to download |
---|---|
Last update | Dec 2020 |
Environment | Windows, Linux |
Compilers | JDK 1.7 or greater |
Prerequisite | Quick Start Guide |
The goal of this tutorial is to define a basic ETA shell interface to be used in subsequent tutorials allowing us to consume real-time market data. Based on our shell interface, we will walk through the general steps within subsequent tutorials to properly establish communication to our real-time server allowing us to log in, query services, and ultimately request for real-time data. To support these goals, we must first establish an appropriate Java build environment to successfully build and run our series of tutorials.
For these tutorials, it is important to familiarize yourself with the contents of the ETA package. The ETA components are packaged as part of the Real-Time SDK bundle for Java. Included within this component, are value-added libraries that enable the developer to leverage OMM-based APIs with more ease and simplicity. These series of tutorials will utilize these value-added libraries.
Located under the Applications/Examples directory contain a series of examples to demonstrate many powerful features available to the developer. The examples have been broken out into 2 main categories as identified by the sub-directories: examples and valueadd. The examples contain feature-rich and highly configurable examples of ETA functionality. However, they are extremely low-level and require a significant amount of code to achieve the desired result. While there are reasons why a developer may choose to go to this level of coding, it is beyond the scope of these tutorials. Instead, these series of tutorials will utilize some very useful, and powerful, capabilities packaged under the valueadd directory.
It is worth noting that although we will be utilizing the ValueAdd ETA components, the amount of code is still somewhat significant. As a result, these tutorials will highlight the relevant sections to give the developer a sense of operation.
As previously outlined, the goal of this tutorial is to define a build environment, implement a shell that performs basic ETA ValueAdd initialization, build and run the example successfully. The steps include:
The series of tutorials come packaged with 2 convenient scripts: buildConsmer and runConsumer - see Build and Run below for more details. Because Real-Time SDK Java can be installed anywhere within your environment, our build and run scripts make an assumption about how to resolve the location of ETA's JAR packages. While there are multiple ways to configure the setup, this project assumes the following:
Once you have set this up, future tutorials will work without further configuration.
The basic shell utilizes a single source file basicConsumer.java. The basicConsumer class represents the main interface for our consumer. The class implements the ETA ValueAdd interface ConsumerCallback which manages all communication events we will define in subsequent tutorials. ETA utilizes an asynchronous model when communicating with external servers or Providers, such as Real-Time servers. As such, we have set up the basic framework to prepare our communication:
public class basicConsumer implements ConsumerCallback
{
...
//****************************************************************************************************
// ConsumerCallback interfaces
//
// The following methods are required to capture the consumer-related events that typically occur
// during a normal consumer role life cycle. Specifically:
//
// reactorChannelEventCallback - capture all conneciton/channel communication events
// rdmLoginMsgCallback - capture the result of our login
// rdmDirectoryMsgCallback - capture the result of the service directory retrieval
// rdmDictionaryMsgCallback - capture the result of the dictionary retrieval, if requested
// defaultMsgCallback - capture all other events, such as data events.
//****************************************************************************************************
// reactorChannelEventCallback
// Capture all connection-related channel events to our provider. At startup, we initiate an
// synchronous connection to the provider. The ValueAdd layer will manage connection failure,
// connection retry, disconnect automatically. In the event we successfully connect, we will receive
// the connected channel file descriptor required for us to register interest within our own event
// polling. The ValueAdd layer will begin the normal cycle of submitting the RDM requests (login,
// directory, dictionary) to the provider and once successfully completed will present a ready event
// (CHANNEL_READY) which is our notification we can begin requesting for real-time data.
@Override
public int reactorChannelEventCallback(ReactorChannelEvent event)
{
return ReactorCallbackReturnCodes.SUCCESS;
}
// rdmLoginMsgCallback
// Report the results of the login request. Because the ValueAdd layer is managing the session
// establishment on our behalf, it will decide if it needs to continue with the normal life cycle or
// not. We simply report the results.
@Override
public int rdmLoginMsgCallback(RDMLoginMsgEvent event)
{
// Process the login response placeholder
return( ReactorCallbackReturnCodes.SUCCESS );
}
// rdmDirectoryCallback
// Once we have successfully logged in, the ValueAdd layer will submit the service directory request
// on our behalf. The response is captured here and we off-load the processing within a separate
// module.
@Override
public int rdmDirectoryMsgCallback(RDMDirectoryMsgEvent event)
{
// Process the directory response placeholder
return( ReactorCallbackReturnCodes.SUCCESS );
}
// rdmDictionaryMsgCallback
// If we decided we wanted to request for the field definition dictionaries from the provider, the
// ValueAdd layer will request once we have completed our service directory processing. We manage the
// response within a separate module.
@Override
public int rdmDictionaryMsgCallback(RDMDictionaryMsgEvent event)
{
// Process the dictionary details placeholder
return(ReactorCallbackReturnCodes.SUCCESS);
}
// defaultMsgCallback
// Once we receive our channel is ready event within the 'reactorChannelEventCallback', we can begin to
// submit data requests to our provider. All responses are captured here and off-loaded within a separate
// module.
@Override
public int defaultMsgCallback(ReactorMsgEvent event)
{
// Process the data msg details placeholder
return(ReactorCallbackReturnCodes.SUCCESS);
}
}
The above structure outlines 5 mandatory interfaces that will manage a typical ETA consumer life cycle. As we move through the series of tutorials, each interface will be implemented with the goal of connecting, establishing a session and requesting and receiving data.
Within our initization routine below, we establish the main ETA Reactor component which drives the logic flow and dispatching of events that we will utilize in later tutorials. For now, we simply create it.
// Supporting variables
private Reactor reactor;
private ReactorOptions reactorOptions = ReactorFactory.createReactorOptions();
...
private void init()
{
...
// Create reactor - the reactor drives the logic flow and dispatching of events to our defined callbacks
reactor = ReactorFactory.createReactor(reactorOptions, errorInfo);
if (errorInfo.code() != ReactorReturnCodes.SUCCESS)
{
System.out.println("createReactor() failed: " + errorInfo.toString());
System.exit(ReactorReturnCodes.FAILURE);
}
}
While our tutorial is designed to be simple, the ValueAdd components will hide a lot of complexity, such as multiple threads, to handle its work. Following tutorials will go into greater depth the details of the ValueAdd components we will be using.
The package includes convenient scripts to build and run the tutorials with any ETA versions:
- buildConsumer.bat and runConsumer.bat:
set VERSION=3.6.0.0
- buildConsumer.ksh and runConsumer.ksh:
VERSION=3.6.0.0
For this series of tutorials:
To Build:
To Run:
Eg (Windows):
> buildConsumer 1
> runConsumer 1
When we run this tutorial, we want to see that we have displayed some general startup details, initialized our reactor then exit gracefully by uninitializing without error. If so, we have successfully built and executed our ETA application
Enterprise Transport API (ETA), Java Edition, LibraryVersionInfo
productVersion: 3.6.0.0
productInternalVersion: etaj3.6.0.L1.all.rrg
productDate: Fri Oct 16 12:25:01 CDT 2020
basicConsumer initializing...
Uninitializing basicConsumer and exiting...
For more information, refer to the ETA Java Development Guides.