question

Upvotes
Accepted
1 0 1 1

How to decode RefreshMsg for unittesting purposes

I am writing unittests for our application, How do I decode the "payload()" part of RefreshMsg? TA similar question was asked some years ago here: https://community.developers.refinitiv.com/questions/6594/what-is-the-preferred-way-to-unit-test-decoding-of.html


However none of the links and suggestions here work anymore.

elektronrefinitiv-realtimeelektron-sdkrrtema-api
icon clock
10 |1500

Up to 2 attachments (including images) can be used with a maximum of 5.0 MiB each and 10.0 MiB total.

12 Answers

Upvotes
Accepted
13k 32 12 18

No, its not supported in the EMA layer, and app will get this message:

Decoding of just encoded object in the same application is not supported

as implemented here - https://github.com/Refinitiv/Real-Time-SDK/blob/465c6d6e85549a53ecd07cb1d9743a7dc5be8942/Java/Ema/Core/src/main/java/com/refinitiv/ema/access/RefreshMsgImpl.java#L477

It is however possible to create a refresh message and decode it in the same app, but requires the use of ETA layer. See a complete working sample of this in this Unit Test example as mentioned previously by @jirapongse.phuriphanvichai.

https://github.com/Refinitiv/Real-Time-SDK/blob/465c6d6e85549a53ecd07cb1d9743a7dc5be8942/Java/Ema/Core/src/test/java/com/refinitiv/ema/unittest/RefreshMsgTests.java#L30

icon clock
10 |1500

Up to 2 attachments (including images) can be used with a maximum of 5.0 MiB each and 10.0 MiB total.

Upvotes
13k 32 12 18

Hi @martin.eriksen,

Refresh message payload could be anything depending on the instrument, asset class and the venue that you subscribe to. Even if you unit test one type, say L1 US equities the actual application might fail if it receives L2 data, because payload will not contain a very different object.

Best way to test the application is with Dev/QA credentials or use infrastructure tools to playback some simulated market activity. You may also try to use a EMA provider to connect your EMA consumer to test the application locally. See provider examples in https://github.com/Refinitiv/Real-Time-SDK/tree/master/Cpp-C/Ema/Examples/Training and follow these tutorials.


icon clock
10 |1500

Up to 2 attachments (including images) can be used with a maximum of 5.0 MiB each and 10.0 MiB total.

Upvotes
38.1k 71 35 53

@martin.eriksen

Unit test examples are available in the packages.

  • Java: \Java\Ema\Core\src\test\java\com\refinitiv\ema\unittest
  • C++: Cpp-C\Ema\Examples\Test\UnitTest


icon clock
10 |1500

Up to 2 attachments (including images) can be used with a maximum of 5.0 MiB each and 10.0 MiB total.

Upvotes
1 0 1 1

Thanks for your input. I don't quite the see question answered. Do you know if there is a way to decode the payload without sending it over the network or isn't there one?

icon clock
10 |1500

Up to 2 attachments (including images) can be used with a maximum of 5.0 MiB each and 10.0 MiB total.

Upvotes
13k 32 12 18

@martin.eriksen, You could manually create a Refresh message and call your onRefreshMsg method with this object, if thats what you are interested in.

See example of creating a refresh message here - https://github.com/Refinitiv/Real-Time-SDK/blob/master/Java/Ema/Examples/src/main/java/com/refinitiv/ema/examples/training/iprovider/series100/ex100_MP_Streaming/IProvider.java

FieldList fieldList = EmaFactory.createFieldList();
fieldList.add( EmaFactory.createFieldEntry().real(22, 3990, OmmReal.MagnitudeType.EXPONENT_NEG_2));
fieldList.add( EmaFactory.createFieldEntry().real(25, 3994, OmmReal.MagnitudeType.EXPONENT_NEG_2));
fieldList.add( EmaFactory.createFieldEntry().real(30, 9,  OmmReal.MagnitudeType.EXPONENT_0));
fieldList.add( EmaFactory.createFieldEntry().real(31, 19, OmmReal.MagnitudeType.EXPONENT_0));

RefreshMsg rmsg = EmaFactory.createRefreshMsg().name(reqMsg.name())
  .serviceId(reqMsg.serviceId())
  .solicited(true)
  .state(OmmState.StreamState.OPEN, OmmState.DataState.OK, OmmState.StatusCode.NONE, "Refresh Completed")
  .payload(fieldList)
  .complete(true);

__yourapplication_decoder__.onRefreshMsg(rmsg, null);


This approach suffers from the shortcomings that I mentioned previously.

icon clock
10 |1500

Up to 2 attachments (including images) can be used with a maximum of 5.0 MiB each and 10.0 MiB total.

Upvotes
1 0 1 1

Thanks! Can you provide a line of code that decodes the payload to get its contents? Instead of the

  
                
  1. __yourapplication_decoder__.onRefreshMsg(rmsg, null);

?

icon clock
10 |1500

Up to 2 attachments (including images) can be used with a maximum of 5.0 MiB each and 10.0 MiB total.

Upvotes
13k 32 12 18

Please see the consumer sample series100/ex120_MP_FieldListWalk/Consumer.java which ships with SDK.

icon clock
10 |1500

Up to 2 attachments (including images) can be used with a maximum of 5.0 MiB each and 10.0 MiB total.

Upvotes
1 0 1 1

Thanks for your input. However, the example you provided decodes after connecting to a server. I want to decode IN THE SAME PROCESS. For unittesting purposes. Is this possible? we have gone over examples etc but not been able to find a way to do it. So I am looking for a line or a few lines of code that can be put instead of "

  1. __yourapplication_decoder__.onRefreshMsg(rmsg, null);"


Which will decode the payload. So I am looking for a function DecodePayload so that this works:


FieldList decodedFields=DecodePayload(rmsg)


Can you write this function, DecodePayload, for me? Or can such a function not be made without elaborate network / interthread communication that would be overkill for unittesting purposes?

icon clock
10 |1500

Up to 2 attachments (including images) can be used with a maximum of 5.0 MiB each and 10.0 MiB total.

Upvotes
13k 32 12 18

@martin.eriksen, Seems like you are trying to program without understanding the system and it is liable to run into issues. You can extract the decode() method from previous linked example and use it unit test.

If you are just interested in extracting the FieldList from refresh message, then do the following:

if(rmsg.payload().dataType() == DataType.DataTypes.FIELD_LIST)
    FieldList fl = rmsg.payload().fieldList();
icon clock
10 |1500

Up to 2 attachments (including images) can be used with a maximum of 5.0 MiB each and 10.0 MiB total.

Upvotes
1 0 1 1

Hi Gurpreet, Thanks for your answer, it seems now we are homing in on the core of the issue we experience so that is very nice :-) I just tried to run the code from our case, like this:

FieldList fieldList = EmaFactory.createFieldList();
fieldList.add( EmaFactory.createFieldEntry().real(22, 3990, OmmReal.MagnitudeType.EXPONENT_NEG_2));
fieldList.add( EmaFactory.createFieldEntry().real(25, 3994, OmmReal.MagnitudeType.EXPONENT_NEG_2));
fieldList.add( EmaFactory.createFieldEntry().real(30, 9,  OmmReal.MagnitudeType.EXPONENT_0));
fieldList.add( EmaFactory.createFieldEntry().real(31, 19, OmmReal.MagnitudeType.EXPONENT_0));

RefreshMsg rmsg = EmaFactory.createRefreshMsg().name("somename")
        .serviceId(42)
        .solicited(true)
        .state(OmmState.StreamState.OPEN, OmmState.DataState.OK, OmmState.StatusCode.NONE, "Refresh Completed")
        .payload(fieldList)
        .complete(true);

try{
    FieldList fl = rmsg.payload().fieldList();
} catch (Exception e){
    System.out.println("Exeption decoding: " + e.getMessage());
    e.printStackTrace();
    System.exit(-1);
}


It throws this exception:

Exeption decoding: Attempt to fieldList() while actual data type is NoData

Exception Type='OmmInvalidUsageException', Text='Attempt to fieldList() while actual data type is NoData', Error Code='-4048'

at com.thomsonreuters.ema.access.PayloadAttribSummaryImpl.ommIUExcept(PayloadAttribSummaryImpl.java:276)

......


Do you get the same result? Our understanding is that there is a fundamental "feature" of the trep api that makes it impossible to decode a payload in the same process in which is was created. Have you heard about that? Any way to get around it so we can unit test the code?

icon clock
10 |1500

Up to 2 attachments (including images) can be used with a maximum of 5.0 MiB each and 10.0 MiB total.

Upvotes
1 0 1 1

Thanks!

It is a 1300 lines file. You link to the method: "testRefreshMsg_Decode() ". I assume that means you think the answer is in that method? I am not quite able to find a place in that method where for example fieldlist is accessed. As it seems you know the answer is in that file, are you able to give more pointers/ code snippets that work in the context of the code I posted in my previous post?

icon clock
10 |1500

Up to 2 attachments (including images) can be used with a maximum of 5.0 MiB each and 10.0 MiB total.

Its more then 1300 lines because it depends on other classes in that namespace.

Anyways, line #108 is where field list is applied to refresh message and #194 is where payload data type is checked while decoding the said refresh message.

Upvotes
1 0 1 1

Thanks! I still don't see the field list contents being accessed. Take for example this line from my code example above:

  1. fieldList.add( EmaFactory.createFieldEntry().real(25, 3994, OmmReal.MagnitudeType.EXPONENT_NEG_2));


Is it possible to decode this from the RefreshMsg, in my try/catch block in the example I posted?



icon clock
10 |1500

Up to 2 attachments (including images) can be used with a maximum of 5.0 MiB each and 10.0 MiB total.

No. You cannot decode the EMA factory created Refresh message in the same application.
Click below to post an Idea Post Idea