question

Upvotes
Accepted
23 5 11 13

How to Serialize OMMItemEvent into String ?

How to Serialize OMMItemEvent into String ?

Client's developer had try to use ObjectMapper to serialize , but get error.

treprfarfa-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.

What programming language?

Upvotes
Accepted
1.9k 6 9 16

Hello @jessie.lin,

I believe that you are trying to parse OMMItemEvent to JSON String using ObjectMapper (from Jackson library).

In my opinion, this Jackson library was created to facilitate mapping between Plain Old Java Object (POJO) and JSON.

However, the main point is that RFA Java’s OMMItemEvent and associated properties’ structures are not POJOs. Nevertheless, the implementation of OMM’s complex type (e.g. FieldList, Vector, Map) in RFA Java is more specific and quite different from Java’s com.util.Collections package. So, I don’t think that the Jackson library is able to properly cover these proprietary data types from Thomson Reuters either.

Here this is the result when I used the following snippet code to convert OMMItemEvent to JSON String:

Snippet Code – in processEvent() method

OMMItemEvent ie = (OMMItemEvent)event;
String jsonInString = null;
try {
    jsonInString = mapper.writeValueAsString(ie);
} catch (JsonProcessingException e) {
    e.printStackTrace();
}
System.out.println(jsonInString);

As the result, an error occurred from a reference in an Event object.

com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class com.reuters.rfa.internal.common.Stack and no properties discovered to create BeanSerializer (to avoid exception, disable
  SerializationFeature.FAIL_ON_EMPTY_BEANS) (through reference chain:
  com.reuters.rfa.internal.session.omm.OMMItemEventMsg["callStack"]->com.reuters.rfa.internal.common.CallStack["_stack"])
  at com.fasterxml.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:77)
  at com.fasterxml.jackson.databind.SerializerProvider.reportBadDefinition(SerializerProvider.java:1188)
  at com.fasterxml.jackson.databind.DatabindContext.reportBadDefinition(DatabindContext.java:260)
  at com.fasterxml.jackson.databind.ser.impl.UnknownSerializer.failForEmpty(UnknownSerializer.java:69)
  at com.fasterxml.jackson.databind.ser.impl.UnknownSerializer.serialize(UnknownSerializer.java:32)
  at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:727)
  at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:717)
  at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:155)
  at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:727)
  at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:717)
  at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:155)
  at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider._serialize(DefaultSerializerProvider.java:481)
  at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:320)
  at com.fasterxml.jackson.databind.ObjectMapper._configAndWriteValue(ObjectMapper.java:3826)
  at com.fasterxml.jackson.databind.ObjectMapper.writeValueAsString(ObjectMapper.java:3140)
  at com.reuters.rfa.example.omm.cons.ItemManager.processEvent(ItemManager.java:182)
  at com.reuters.rfa.internal.common.ResponseMessage.dispatchToClient(Unknown
  Source)
  at com.reuters.rfa.internal.common.ResponseMessage.dispatch(Unknown Source)
  at com.reuters.rfa.internal.common.EventQueueImpl.localDispatch(Unknown Source)
  at com.reuters.rfa.internal.common.EventQueueImpl.dispatch(Unknown Source)
  at com.reuters.rfa.example.omm.cons.StarterConsumer.run(StarterConsumer.java:219)
  at com.reuters.rfa.example.omm.cons.StarterConsumer.main(StarterConsumer.java:335)

Then, I tried to fix ‘No serializer’ error by disabling SerializationFeature.FAIL_ON_EMPTY_BEANS and null object:

OMMItemEvent ie = (OMMItemEvent)event;
ObjectMapper mapper = new ObjectMapper();
mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
mapper.setSerializationInclusion(Include.NON_NULL);
String jsonInString = null;
try {
    jsonInString = mapper.writeValueAsString(ie);
} catch (JsonProcessingException e) {
    e.printStackTrace();
}
System.out.println(jsonInString);

Still, there was an error from NullPointerException.

com.fasterxml.jackson.databind.JsonMappingException: (was
  java.lang.NullPointerException) (through reference chain:
  com.reuters.rfa.internal.session.omm.OMMItemEventMsg["msg"]->com.reuters.rfa.internal.rwf.RwfMsgOverride["pool"]->com.reuters.rfa.internal.rwf.RwfPool["carrierMessage"])
  at com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:391)
  at com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:351)
  at com.fasterxml.jackson.databind.ser.std.StdSerializer.wrapAndThrow(StdSerializer.java:316)
  at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:725)
  at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:155)
  at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:727)
  at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:717)
  at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:155)
  at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:727)
  at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:717)
  at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:155)
  at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider._serialize(DefaultSerializerProvider.java:481)
  at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:320)
  at com.fasterxml.jackson.databind.ObjectMapper._configAndWriteValue(ObjectMapper.java:3826)
  at com.fasterxml.jackson.databind.ObjectMapper.writeValueAsString(ObjectMapper.java:3140)
  at com.reuters.rfa.example.omm.cons.ItemManager.processEvent(ItemManager.java:182)
  at com.reuters.rfa.internal.common.ResponseMessage.dispatchToClient(Unknown
  Source)
  at com.reuters.rfa.internal.common.ResponseMessage.dispatch(Unknown Source)
  at com.reuters.rfa.internal.common.EventQueueImpl.localDispatch(Unknown Source)
  at com.reuters.rfa.internal.common.EventQueueImpl.dispatch(Unknown Source)
  at com.reuters.rfa.example.omm.cons.StarterConsumer.run(StarterConsumer.java:219)
  at com.reuters.rfa.example.omm.cons.StarterConsumer.main(StarterConsumer.java:335)
Caused by: java.lang.NullPointerException
  at com.reuters.rfa.internal.rwf.RwfPool.getCarrierMessage(Unknown Source)
  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
  at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
  at java.lang.reflect.Method.invoke(Method.java:497)
  at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:687)
  at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:717)
  ...
  18 more

Note that RFA Java’s Event object also provides methods such as getClosure(), getInterestSpec(), getEventQueue(), and etc., which are non-information and should not be generated as JSON anyway.

At this rate, if you still want to convert RFA Java’s Event and associated structures to JSON String via this Jackson library, I suggest you create your own wrapper POJO classes for keeping necessary information that you want it to be in JSON result, and then you convert your POJOs to JSON instead.

Otherwise, if you just want a plain String format output (non-JSON), you may consider to modify/customize a com.reuters.rfa.example.utility.GenericOMMParser class. Here this is the output example just in case you might be interested in it:

MESSAGE
    Msg Type: MsgType.UPDATE_RESP
    Msg Model Type: MARKET_PRICE  
    Indication Flags: DO_NOT_CONFLATE  
    Hint Flags: HAS_ATTRIB_INFO | HAS_RESP_TYPE_NUM | HAS_SEQ_NUM  
    SeqNum: 22782  
    RespTypeNum: 0 (UNSPECIFIED)  
    AttribInfo  
        ServiceName: API_ELEKTRON_EPD_RSSL  
        ServiceId: 2115  
        Name: JPY=  
        NameType: 1 (RIC)  
    Payload: 13 bytes  
        FIELD_LIST  
            FIELD_ENTRY 114/BID_NET_CH: -0.28
            FIELD_ENTRY 372/IRGPRC: -0.25

Hope this helps!

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
4.4k 10 6 9

Hi @jessie.lin

OMMItemEvent in RFA C++ and .NET does not support serialization.

Why the client want to serialize OMMItemEvent into String?

If you want to keep it for later use, then they can just clone the event.

Or if they want to access the raw encoded buffer in message level and save it to disk or database, then they can just call getEncodedBuffer() from Msg object to get the raw buffer and then save the raw buffer.

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.

Sorry forget to mention, client is using RFA Java.

Upvotes
1.5k 3 5 7

(assuming this an RFA Java question)

What is "ObjectMapper" ? The only ObjectMapper I know is the one from Jackson library. Nothing to do with RFA API.

If you really want to do this then I guess you can use

event.getMsg().getBytes()

and then Base64 encode that.

But the fundamental question is: What is it you're trying to achieve?

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
23 5 11 13

Hi sirs

Thank you for the answers. The reason to make serialize, is client want to save the real time source data into messages, and then process those data with Multiple threads asynchronously, in order to get better performance and no lost of real time data.

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.9k 6 9 16

@jessie.lin, instead of saving data into messages, you can also use OMMPool.acquireCopy() to copy an OMMMsg from OMMItemEvent into the memory (or the application's queue). Then, the application can use another thread to process copied objects later as an alternative.

You can find the detail of OMMPool.acquireCopy() from Developer Guide:

The OMM Item Event (and the encapsulated message) is only valid during the Client callback. If the application wishes to retain the message or data beyond the scope of the callback, it must make a copy of the message or data. Application can use the RFA-managed memory to save the message or data using the OMMPool or acquireCopy() method.

Hope this helps.

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
23 5 11 13

Thank you, Client is satisfy with the answers.

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.

Click below to post an Idea Post Idea