1

I am writing pdxInstances to GemFire using the sequence: rabbitmq => springxd => gemfire.

If I put this JSON into rabbitmq {'ID':11,'value':5}, value appears as a byte value in GemFire. If I put {'ID':11,'value':500}, value appears as a word and if I put {'ID':11,'value':50000} it appears as an Integer.

A problem arises when I query data from GemFire and order them. For example, if I use a query such as select * from /my_region order by value it fails, saying it cannot compare a byte with a word (or byte with an integer).

Is there any way to declare the data type in JSON? Or any other method to get rid of this problem?

Matthew Murdoch
  • 30,874
  • 30
  • 96
  • 127
Altan Gokcek
  • 91
  • 2
  • 9

2 Answers2

3

To add a bit of insight into this problem... in reviewing GemFire/Geode source code, it would seem it is not possible to configure the desired value type and override GemFire/Geode's default behavior, which can be seen in JSONFormatter.setNumberField(..).

I will not explain how GemFire/Geode involves the JSONFormatter during a Region.put(key, value) operation as it is rather involved and beyond the scope of this discussion.

However, one could argue that the problem is not necessarily with the JSONFormatter class, since storing a numeric value in a byte is more efficient than storing the value in an integer, especially when the value would indeed fit into a byte. Therefore, the problem is really that the Comparator used in the Query processor should be able to compare numeric values in the same type family (byte, short, int, long), upcasting where appropriate.

If you feel so inclined, feel free to file a JIRA ticket in the Apache Geode JIRA repository at https://issues.apache.org/jira/browse/GEODE-72?jql=project%20%3D%20GEODE

Note, Apache Geode is the open source "core" of Pivotal GemFire now. See the Apache Geode website for more details.

Cheers!

John Blum
  • 7,381
  • 1
  • 20
  • 30
0

Your best bet would be to take care of this with a custom module or a groovy script. You can either write a custom module in Java to do the conversion and then upload the custom module into SpringXD, then you could reference your custom module like any other processor. Or you could write a script in Groovy and pass the incoming data through a transform processor.

http://docs.spring.io/spring-xd/docs/current/reference/html/#processors

The actual conversion probably won't be too tricky, but will vary depending on which method you use. The stream creation would look something like this when you're done.

  1. stream create --name myRabbitStream --definition "rabbit | my-custom-module | gemfire-json-server etc....."

  2. stream create --name myRabbitStream --definition "rabbit | transform --script=file:/transform.groovy | gemfire-json-server etc...."

It seems like you have your source and sink modules set up just fine, so all you need to do is get your processor module setup to do the conversion and you should be all set.

mross1080
  • 144
  • 1
  • 7