Testing EMA Consumer and Provider Applications

Umer Nalla
Developer Advocate Developer Advocate

Knowledge Prerequisite – Must have a working knowledge of using Enterprise Message API to develop Consumer and/or Provider applications.

 

As part of the Real-Time SDK, the Enterprise Message API is the go-to choice for the majority of developers writing or migrating a real-time streaming data Consumer or Provider application in Java or C++. Its high-level implementation and high-performance characteristics make it the ideal candidate for most of these development scenarios.

 

Testing your code

Under normal circumstances, EMA Consumer applications can be tested against easily by connecting to a live feed - either delivered over the internet or via a deployed Refinitiv Real-Time Distribution System (RTDS). 

For Provider type applications, it generally requires an RTDS to publish the data to and for a test consumer to consume the published data from.

However, there can be scenarios where you as a developer may want to test your code without a live feed or access to an RTDS - for example:

  • no access to an internet connection
  • no credentials or user ID required to consume data
  • test with a specific payload/content set
  • no access to your corporate network
  • your market Data team has not yet configured your RTDS system to receive data from your Provider
  • you want to test with different payloads etc without causing any issue on the RTDS system
  • and so on...

In this article, I will cover a few different options available to you for testing your consumer and provider examples away from a live feed or RTDS system.

 

Consumer Testing

For much of your testing, a Consumer application would be connecting to a live streaming feed via either an Advance Distribution Server (ADS) component of your RTDS or cloud-based Refinitiv Real-Time Optimised feed. However, suppose you don’t yet have access to the above, or want to do some repeat testing with a controlled data set – where you can determine the content either in terms of a specific set of fields or payload size or tick update rate etc. In cases like these, there are a few options available to you.

Direct Connect to a Provider example

One of the most common test methods – often used when a developer does not yet have access to a live feed but wants to get started with running a Consumer example - seeing how it behaves, what the data looks like etc – is to connect the Consumer to a Provider application.

This is made incredibly easy due to the Direct Connect functionality of EMA – you can just start an Interactive Provider example running and then configure your Consumer to connect directly to the IProvider. The IProvider could be running on the same PC or on a separate device on the same network.

Assuming both Consumer and IProvider applications can be run on the same PC, it is simply a case of ensuring the config for both applications are configured to connect to each other.

As you may know, an IProvider example waits for an incoming login/connection request (which would normally be the AHD component of the RTDS system).

So, in your IProvider code, you would have something like this:

    	
            provider = EmaFactory.createOmmProvider(config.port("14002"), appClient);
        
        
    

where 14002 is the port that the IProvider is listening for the incoming connection.

Therefore, in your Consumer application you set the host name to connect to IProvider as follows:

    	
            consumer  = EmaFactory.createOmmConsumer(config.host("localhost:14002").username("user"));
        
        
    

If you have RT-SDK Java installed, you can test out the above scenario easily – as follows:

  • Open up two terminals or cmd consoles, and navigate each to the Java folder where you have unpacked/installed your RT-SDK e.g. in c:\Refinitiv\RTSDK-JAVA\Java
  • In console one run:
    	
            c:\Refinitiv\RTSDK-JAVA\Java>gradlew runiProvider100
        
        
    

In console two run:

    	
            c:\Refinitiv\RTSDK-JAVA\Java>gradlew runConsumer100
        
        
    

You should see the IProvider startup and wait for an incoming connection. Once the Consumer is up and running, you will see a ‘ChannelUp’ message in both the IProvider and Consumer console. After which you will see some dummy BID and ASK values for IBM.N being received by the Consumer. When you stop the consumer, you would see a 'ChannelDown' message in the IProvider console.

NOTE: if you happen to be developing an IProvider and there is already an ADH configured to connect to the IProvider on your PC, then you should change the above ports from 14002 to something else like 14005 – to avoid any conflicts

Whilst we ran EMA Java examples in the above test scenario, you can do the same for EMA C++ too - as shown below, where I built and ran the Cons100 and IProv100 targets in two Linux consoles:

Modifying the IProvider source code

Whilst the above test scenario is quite limited, as we include several IProvider examples, you can quite easily put together a more suitable test IProvider which mimics your testing requirements in terms of update rate, payload field content - for example., the IProvider 200_MP_Streaming sample demonstrates how to publish an Enumerated field as well as a String field - and so on.

Looking at the IProvider examples, however, you may note that most of them only handle a single Market Data Item request - and will reject any subsequent requests you make - which limits testing considerably. However, this can be addressed with relatively little coding effort - as demonstrated in the 170_MP_ConnectedClientInfo (C++) and ex170_MP_ConnectedClientInfo (Java)  IProvider examples. 

Both these 170 examples accept all incoming item requests and send out a Refresh Msg for each one. The handle for each item request is stored in a map - and in the main() method (running in the main application thread), the code loops through the handles and submits an Update Msg for each item at a defined interval.

So, if I run the IProvider 170 example alongside the 370_MP_Batch consumer example - I get the following output - where the 370 Consumer is requesting multiple instruments and the 170 IProvider example is fulfilling the requests: 

 

Performance testing

If you want to focus more on performance/stress testing - you can also explore the more advanced PerfTools examples - which allow you to monitor things like latency, memory and CPU usage.  And since the source code is provided - you can use these as the starting point for your testing and modify them as required.

Testing with 'real' data - Record and Playback

Alternatively, if you want to test with some more realistic data - this is also possible - using some utilities from the Infrastructure tools package (available in the RT-SDK Downloads section).

Using the testclient tool you can capture real-time streaming data to a file when you do have access to a live feed and then play the data back later using the testserver tool.

If you don't yet have access to a real-time feed (in order to capture the data), you can still test with the 'canned data' files we provide for the various regions.
Instructions for using the testclient + testserver tools can be found in this detailed article - Quick Start Guide to Recording and Playback of Refinitiv Real-Time Data | Refinitiv Developers and canned data files can also be found in the  RT-SDK Downloads section.

Capturing/Logging low-level Trace

On occasions, it may also be useful to capture the low-level trace of the data being consumed or published - so that you can study it for verification or debugging purposes. 

Both EMA C++ and Java allow you to generate low-level trace - which can be output to the console or redirected to a file. This can be done by enabling the XmlTraceToStdout (Java and C++) or XmlTraceToFile (C++) parameter in your EMA Channel configuration as shown in the snippet below. For EMA Java, you can manually redirect the console output to a file using standard Java techniques (one example shown below).

    	
            

// Channel Config to enable low level trace to Std Out

<Channel>

    <Name value="Channel_2"/>

    <ChannelType value="ChannelType::RSSL_SOCKET"/>

    <CompressionType value="CompressionType::None"/>

    <GuaranteedOutputBuffers value="5000"/>

    <Host value="myADS1"/>

    <Port value="14002"/>

    <XmlTraceToStdout value="1" />

</Channel>

 

// One way of redirecting console output to a file in Java 

try { 
    System.setOut(new PrintStream(new BufferedOutputStream(new FileOutputStream("output.txt")))); 

} catch (FileNotFoundException e) 


    // TODO Auto-generated catch block e.printStackTrace(); 

}

 

Provider Testing

Testing an Interactive Provider

Whilst discussing how to test a Consumer, we have also referenced Interactive Providers - so much of the same advice above can be applied to IProvider testing i.e. directly connecting a Consumer to your IProvider. 

You can also use the testclient tool to record your IProvider data and playback later if required. For example, if your provider is relying on upstream data which is time-constrained - such as market open or other events when market data volumes increase due to specific figures being released. You can capture whatever derived data is published by your Provider at these key moments and then use then for stress testing etc. 

So, for example, assuming I was running the earlier IProvider 170 example or my own IProvider application, I could run the testclient to capture the data in a replayable XML format (see the above article for details on the various parameters).

    	
            ./testclient -S DIRECT_FEED -ef RicFile -rf 8 -hs localhost -p 14002 -ct rssl -u rtds -of recIprovXml.dat
        
        
    

I could then playback the captured data later using testserver and connect up a Consumer (or testclient) to request the data (see the above article for details on the various parameters).

    	
            ./testserver -S DIRECT_FEED -Q recIprovXml.dat -U 1 -N 14002 -K -ik
        
        
    

Testing a Non-Interactive Provider

Whilst testing an IProvider is relatively straightforward - since it accepts incoming login and data requests, it is not as simple for Non-Interactive Providers.

A Non-Interactive Provider by its very nature acts as a client application and therefore, does not accept incoming connections or data requests - it makes an outbound connection to the Advance Distribution Hub component of an RTDS system and publishes whatever data it sees fit - regardless of any current interest in that data.

Until recently, the only way option I was aware of for most developers to test a NIProvider was the official one i.e. to get access to an ADH which had been configured to accept a connection from the NIProvider including details of the service(s) that the NIProvider publishes. This is less than ideal because

  • as a developer, this means you have a dependency on the Market Data Admin team who maintain the ADH - to initially configure the ADH and for any config changes you require during the development of your NIProvider
  • whilst developing your NIProvider there is always the chance you could cause adverse issues on the ADH by publishing invalid data

One alternative, for me, has been to use the Refinitiv Real-Time Connector product (which in simple terms is a cut-down ADH+ADS component) - running in a Docker session, which I can configure as and when required. However, as RTC is a licensed product - it may not be an option for you. I would recommend checking with your Market Data team if they have a corporate licence for RTC and if so, refer to my article on Docker + RTC for more details.

A Clever 'Hack'

Luckily for you (and me!), I work with some pretty clever people here at Refinitiv - one of them being my colleague Jirapongse Phuriphanvichai - who figured out a neat hack for one of the ETA examples - which allows some rudimentary testing of a NIProvider application.

The hack involves modifying the code for the ETA Provider example:

  • com.refinitiv.eta.examples.provider for Java
  • Eta\Applications\Examples\Provider for C++

 to trick it into accepting an incoming NIProvider connection.
NOTE: Whilst this is not a supported scenario and may not work fully, it should certainly be sufficient to do some basic NIProvider testing e.g.

  • waiting for your Market Data team to configure an ADH for you
  • don't have network access to an ADH
  • diagnosing a bug with your NIProvider and wish to avoid any negative impact on a shared ADH instance

Below I have laid out the basic changes required to the above examples that should allow you to connect your NIProvider to the ETA Provider examples - all credit to Jirapongse who detailed the 'hack' for the ETA Java version on our Q&A Forum - and I just applied the same hack to the ETA C version.

ETA Java Provider 'Hack'

Lets start with the Java version hack:

1. Modify the ProviderDirectoryHandler.processRequest method to return CodecReturnCodes.SUCCESS when it receives unhandled source directory messages (refresh and status messages):

    	
            

ProviderDirectoryHandler.processRequest():

....
....

            }

            default:

                error.text("Received unhandled Source Directory msg type: " + msg.msgClass());

                return CodecReturnCodes.SUCCESS;

                // return CodecReturnCodes.FAILURE;

        }

    }

2. Make similar modifications to  ItemHandler.processRequest method to again return CodecReturnCodes.SUCCESS when receiving unhandled item messages (refresh and status messages)

    	
            

ItemHandler.processRequest():

 

....
....

 default:

                error.text("Received Unhandled Item Msg Class: " + MsgClasses.toString(msg.msgClass()));

                return CodecReturnCodes.SUCCESS;

                // return CodecReturnCodes.FAILURE;

        }

3. Run the modified interactive provider with the following options "-x -p 14003".

  • -x option enables the XML tracing so you can see the received message.
  • -p 14003 sets the IProvider to listen on TCP port 14003 which is the default TCP port used by NIProviders for their outbound connection.

4. Finally, run your NIProvider application (or an EMA example such as NIProv100) to connect to the modified IProvider 

On the IProvider console, you will be able to see the Login request/response and Data messages received from/sent to the NIProvider - to help you validate the expected behaviour of your NIProvider application.

    	
            

connectionType: null

portNo: 14003

interfaceName: null

serviceName: DIRECT_FEED

serviceId: 1

enableRTT: false

protocolList: rssl.rwf, rssl.json.v2

 

Server bound on port 14003

New client: java.nio.channels.SocketChannel[connected local=/127.0.0.1:14003 remote=/127.0.0.1:49849]

Client channel is now ACTIVE

Channel Info:

  Connected Hostname: WIN-GI91KPII1FA

  Connected IP: 192.168.2.10

  Max Fragment Size: 6142

  Output Buffers: 500 Max, 500 Guaranteed

  Input Buffers: 10

  Send/Recv Buffer Sizes: 65536/65536

  Ping Timeout: 30

  Client To Server Pings: true

  Server To Client Pings: true

  Connected component version: ETA Java Edition|EMA Java Edition

 

Read message: 

<!-- rwfMajorVer="14" rwfMinorVer="1" -->

<REQUEST domainType="LOGIN" streamId="1" containerType="NO_DATA" flags="0x04 (STREAMING)" dataSize="0">

    <key flags="0x26 (HAS_NAME|HAS_NAME_TYPE|HAS_ATTRIB)" name="user" nameType="1" attribContainerType="ELEMENT_LIST">

        <attrib>

            <elementList flags="0x08 (HAS_STANDARD_DATA)">

                <elementEntry name="ApplicationId" dataType="ASCII_STRING" data="256"/>

                <elementEntry name="ApplicationName" dataType="ASCII_STRING" data="ema"/>

                <elementEntry name="Position" dataType="ASCII_STRING" data="192.168.2.10/WIN-GI91KPII1FA"/>

                <elementEntry name="Role" dataType="UINT" data="1"/>

            </elementList>

        </attrib>

    </key>

    <dataBody>

    </dataBody>

</REQUEST>

 

Received Login Request for Username: user

LoginRequest: 

streamId: 1

userName: user

streaming: true

nameType: 1

applicationId: 256

applicationName: ema

position: 192.168.2.10/WIN-GI91KPII1FA

role: 1

 

 

Write message (RWF): 

<!-- rwfMajorVer="14" rwfMinorVer="1" -->

<REFRESH domainType="LOGIN" streamId="1" containerType="NO_DATA" flags="0x68 (HAS_MSG_KEY|SOLICITED|REFRESH_COMPLETE)" groupId="0" State: Open/Ok/None - text: "Login accepted by host localhost" dataSize="0">

    <key flags="0x26 (HAS_NAME|HAS_NAME_TYPE|HAS_ATTRIB)" name="user" nameType="1" attribContainerType="ELEMENT_LIST">

        <attrib>

            <elementList flags="0x08 (HAS_STANDARD_DATA)">

                <elementEntry name="ApplicationId" dataType="ASCII_STRING" data="256"/>

                <elementEntry name="ApplicationName" dataType="ASCII_STRING" data="ETA Provider"/>

                <elementEntry name="Position" dataType="ASCII_STRING" data="192.168.2.10/WIN-GI91KPII1FA"/>

                <elementEntry name="SingleOpen" dataType="UINT" data="0"/>

                <elementEntry name="SupportOMMPost" dataType="UINT" data="1"/>

                <elementEntry name="SupportBatchRequests" dataType="UINT" data="1"/>

            </elementList>

        </attrib>

    </key>

    <dataBody>

    </dataBody>

</REFRESH>

 

....
// Omitted the Source Directory which would be here

....

 

 

Read message: 

<!-- rwfMajorVer="14" rwfMinorVer="1" -->

<REFRESH domainType="MARKET_PRICE" streamId="-1" containerType="FIELD_LIST" flags="0x48 (HAS_MSG_KEY|REFRESH_COMPLETE)" groupId="0" State: Open/Ok/None - text: "UnSolicited Refresh Completed" dataSize="25">

    <key flags="0x03 (HAS_SERVICE_ID|HAS_NAME)" serviceId="0" name="IBM.N"/>

    <dataBody>

        <fieldList flags="0x08 (HAS_STANDARD_DATA)">

            <fieldEntry fieldId="22" dataType="REAL" data="39.90"/>

            <fieldEntry fieldId="25" dataType="REAL" data="39.94"/>

            <fieldEntry fieldId="30" dataType="REAL" data="9.0"/>

            <fieldEntry fieldId="31" dataType="REAL" data="19.0"/>

        </fieldList>

    </dataBody>

</REFRESH>

 

 

Read message: 

<!-- rwfMajorVer="14" rwfMinorVer="1" -->

<UPDATE domainType="MARKET_PRICE" streamId="-1" containerType="FIELD_LIST" flags="0x08 (HAS_MSG_KEY)" updateType="0" dataSize="14">

    <key flags="0x03 (HAS_SERVICE_ID|HAS_NAME)" serviceId="0" name="IBM.N"/>

    <dataBody>

        <fieldList flags="0x08 (HAS_STANDARD_DATA)">

            <fieldEntry fieldId="22" dataType="REAL" data="39.91"/>

            <fieldEntry fieldId="30" dataType="REAL" data="10.0"/>

        </fieldList>

    </dataBody>

</UPDATE>

 

NOTE: The above hack provides a rudimentary testing scenario – for when you don’t have access to your ADH – or during early development phase.
It is in no way meant to be a replacment for full testing with an ADH. Always test your NIProvider thoroughly with a real ADH configured correctly as per your requirements – before deploying in production etc.

 

ETA C Provider 'Hack'

If you are using C/C++ of RT-SDK - then you can apply very similar changes to the ETA Provider example too.

1. Modify the processSourceDirectoryRequest() in Cpp-C\Eta\Applications\Examples\Provider\rsslDirectoryHandler.c file to comment out the RSSL_RET_FAILURE return value, when it receives unhandled source directory messages (refresh and status messages):

    	
            

processSourceDirectoryRequest() in rsslDirectoryHandler.c

....
....

        break;

 

    default:

        printf("\nReceived Unhandled Source Directory Msg Class: %d\n", msg->msgBase.msgClass);

        // return RSSL_RET_FAILURE;

    }

 

    return RSSL_RET_SUCCESS;

}

2. Build and run the above modified ETA interactive provider with the same command line as aboe i.e. "-x -p 14003"

3. As per above, run your NIProvider application (or an EMA example such as NIProv100) to connect to the modified ETA  Provider.

On the IProvider console, you will be able to see the Login request/response and Data messages received from/sent to the NIProvider - so you can validate the behaviour of your NIProvider application.

    	
            

>Provider.exe -x -p 14003

portNo: 14003

serviceName: DIRECT_FEED

serviceId: 1

Server IPC descriptor = 220 bound on port 14003

Server fd=220: New client on Channel fd=224

Channel 224 connection in progress

<!-- Connection Established (Channel IPC descriptor = 224) -->

<!-- Time: 16:37:32:817 -->

Client Channel fd=224 is now ACTIVE

Connection is from ETA Java Edition|EMA Java Edition device.

<!-- Incoming Message (Channel IPC descriptor = 224) -->

<!-- Time: 16:37:32:909 -->

<!-- rwfMajorVer="14" rwfMinorVer="1" -->

<requestMsg domainType="RSSL_DMT_LOGIN" streamId="1" containerType="RSSL_DT_NO_DATA" flags="0x4 (RSSL_RQMF_STREAMING)" dataSize="0">

    <key  flags="0x26 (RSSL_MKF_HAS_NAME|RSSL_MKF_HAS_NAME_TYPE|RSSL_MKF_HAS_ATTRIB)"  name="user" nameType="1" attribContainerType="RSSL_DT_ELEMENT_LIST">

        <attrib>

            <elementList flags="0x8 (RSSL_ELF_HAS_STANDARD_DATA)">

                <elementEntry name="ApplicationId" dataType="RSSL_DT_ASCII_STRING" data="256"/>

                <elementEntry name="ApplicationName" dataType="RSSL_DT_ASCII_STRING" data="ema"/>

                <elementEntry name="Position" dataType="RSSL_DT_ASCII_STRING" data="192.168.2.10/WIN-GI91KPII1FA"/>

                <elementEntry name="Role" dataType="RSSL_DT_UINT" data="1"/>

            </elementList>

        </attrib>

    </key>

    <dataBody>

    </dataBody>

</requestMsg>

<!-- End Message (Channel IPC descriptor = 224) -->

Received Login Request for Username: user

<!-- Outgoing Message (Channel IPC descriptor = 224) -->

<!-- Time: 16:37:32:934 -->

<!-- rwfMajorVer="14" rwfMinorVer="1" -->

<refreshMsg domainType="RSSL_DMT_LOGIN" streamId="1" containerType="RSSL_DT_NO_DATA" flags="0x168 (RSSL_RFMF_HAS_MSG_KEY|RSSL_RFMF_SOLICITED|RSSL_RFMF_REFRESH_COMPLETE|RSSL_RFMF_CLEAR_CACHE)" groupId="0" dataState="RSSL_DATA_OK" streamState="RSSL_STREAM_OPEN" code="RSSL_SC_NONE" text="Login accepted by host WIN-GI91KPII1FA"  dataSize="0">

    <key  flags="0x26 (RSSL_MKF_HAS_NAME|RSSL_MKF_HAS_NAME_TYPE|RSSL_MKF_HAS_ATTRIB)"  name="user" nameType="1" attribContainerType="RSSL_DT_ELEMENT_LIST">

        <attrib>

            <elementList flags="0x8 (RSSL_ELF_HAS_STANDARD_DATA)">

                <elementEntry name="ApplicationId" dataType="RSSL_DT_ASCII_STRING" data="256"/>

                <elementEntry name="ApplicationName" dataType="RSSL_DT_ASCII_STRING" data="rsslProvider"/>

                <elementEntry name="Position" dataType="RSSL_DT_ASCII_STRING" data="192.168.2.10/WIN-GI91KPII1FA"/>

                <elementEntry name="ProvidePermissionProfile" dataType="RSSL_DT_UINT" data="1"/>

                <elementEntry name="ProvidePermissionExpressions" dataType="RSSL_DT_UINT" data="1"/>

                <elementEntry name="SingleOpen" dataType="RSSL_DT_UINT" data="0"/>

                <elementEntry name="AllowSuspectData" dataType="RSSL_DT_UINT" data="1"/>

                <elementEntry name="SupportPauseResume" dataType="RSSL_DT_UINT" data="0"/>

                <elementEntry name="SupportOptimizedPauseResume" dataType="RSSL_DT_UINT" data="0"/>

                <elementEntry name="SupportOMMPost" dataType="RSSL_DT_UINT" data="1"/>

                <elementEntry name="SupportViewRequests" dataType="RSSL_DT_UINT" data="0"/>

                <elementEntry name="SupportBatchRequests" dataType="RSSL_DT_UINT" data="5"/>

                <elementEntry name="SupportStandby" dataType="RSSL_DT_UINT" data="0"/>

            </elementList>

        </attrib>

    </key>

    <dataBody>

    </dataBody>

</refreshMsg>

 

<!-- End Message (Channel IPC descriptor = 224) -->

// Omitted the Source directory which would be here //

Received Unhandled Source Directory Msg Class: 2

Compression Stats Bytes In: 778 Uncompressed Bytes In: 778

<!-- Incoming Message (Channel IPC descriptor = 224) -->

<!-- Time: 16:37:33:015 -->

<!-- rwfMajorVer="14" rwfMinorVer="1" -->

<refreshMsg domainType="RSSL_DMT_MARKET_PRICE" streamId="-1" containerType="RSSL_DT_FIELD_LIST" flags="0x48 (RSSL_RFMF_HAS_MSG_KEY|RSSL_RFMF_REFRESH_COMPLETE)" groupId="0" dataState="RSSL_DATA_OK" streamState="RSSL_STREAM_OPEN" code="RSSL_SC_NONE" text="UnSolicited Refresh Completed"  dataSize="25">

    <key  flags="0x3 (RSSL_MKF_HAS_SERVICE_ID|RSSL_MKF_HAS_NAME)"  serviceId="0" name="IBM.N"/>

    <dataBody>

        <fieldList flags="0x8 (RSSL_FLF_HAS_STANDARD_DATA)">

            <fieldEntry fieldId="22" data="0C0F 96"/>

            <fieldEntry fieldId="25" data="0C0F 9A"/>

            <fieldEntry fieldId="30" data="0E09"/>

            <fieldEntry fieldId="31" data="0E13"/>

        </fieldList>

    </dataBody>

</refreshMsg>

<!-- End Message (Channel IPC descriptor = 224) -->

Received Unhandled Item Msg Class: 2

Compression Stats Bytes In: 83 Uncompressed Bytes In: 83

<!-- Incoming Message (Channel IPC descriptor = 224) -->

<!-- Time: 16:37:33:978 -->

<!-- rwfMajorVer="14" rwfMinorVer="1" -->

<updateMsg domainType="RSSL_DMT_MARKET_PRICE" streamId="-1" containerType="RSSL_DT_FIELD_LIST" flags="0x8 (RSSL_UPMF_HAS_MSG_KEY)" updateType="0 (RDM_UPD_EVENT_TYPE_UNSPECIFIED)" dataSize="14">

    <key  flags="0x3 (RSSL_MKF_HAS_SERVICE_ID|RSSL_MKF_HAS_NAME)"  serviceId="0" name="IBM.N"/>

    <dataBody>

        <fieldList flags="0x8 (RSSL_FLF_HAS_STANDARD_DATA)">

            <fieldEntry fieldId="22" data="0C0F 97"/>

            <fieldEntry fieldId="30" data="0E0A"/>

        </fieldList>

    </dataBody>

</updateMsg>

As before, in the IProvider console, you will see the Login request/response and Data messages received from/sent to the NIProvider - helping in your effort to validate the behaviour of your NIProvider application.

NOTE: Just to re-iterate, the above hack provides a rudimentary testing scenario – for when you don’t have access to your ADH – or during the early development phase.
It is in no way meant to be a replacement for full testing with an ADH. Always test your NIProvider thoroughly with a real ADH configured correctly as per your requirements – before deploying in production etc.

 

Refinitiv Real-Time Connector

As mentioned earlier, I do recommend checking with your Market Data team if they have a corporate licence for RTC and if so, refer to my article on Docker + RTC for more details on using RTC for testing Consumers, Providers and Contributors.

Closing Summary

I hope I have been able to illustrate some useful techniques to aid you in testing your EMA Consumer and/or Provider applications:

  • using the examples to connect to each other
  • via the record and playback facility available using the Infrastructure tools
  • capturing low-level trace output to validate the payloads being sent or received
  • using the supplied canned data files + playback tool
  • modifying EMA Provider examples to mimic typical data you may be consuming
  • using the PerfTools suite of examples included with RT-SDK
  • modifying the ETA Interactive Provide to provide a basic stand-in for an ADH

In addition to the above, you may also find the RT-SDK + DockerAmazon EC2 and WSL related articles useful - see the right-hand sidebar for links

If you have further questions, please feel free to reach out to us on our Q&A Forum