Skip to content

K Payload JSON Format

stefanomorson edited this page Apr 28, 2017 · 6 revisions

K-Payload JSON format

Eclipse Kura uses MQTT as message protocol. Within a message, the payload is encoded using Google Protobuf which guarantees efficiency and a strong type system [1]. However, since the Protobuf format is inconvenient to consume in some use cases, we would like to support also JSON as a possible encoding for a Kura message payload .

JSON encoded messages can greatly ease the integration with third party systems since JSON is largely adopted in the community. However, JSON is coarsely typed compared to what is needed by Kura and Kapua so the way the JSON encoding is structured makes difference.

In JavaScript (and JSON) the Number type can represent any numeric value, while in many communication protocols numeric types exist to describe different sizes and types of numeric values; this allows the runtime to handle numeric operations more efficiently.

This is the case also for distributed applications built upon Eclipse Kura and Kapua.

Due to these considerations we would like to support two JSON encodings:

  • "Typed" JSON encoding
  • "Simple" JSON encoding

The first, inspired by the binary JSON standard [3], can be used for every use case and will also be the only JSON encoding supported for Kura-Kapua communications.

The latter can be used by a Kura gateway to send messages to third-party solutions from a Kura gateway.

Typed JSON Encoding

The following is an example of how a JSON payload will be structured:

{
  "sentOn" : 1491298822,
  "position" : {
    "latitude" : 45.234,
    "longitude" : -7.3456,
    "altitude" : 1.0,
    "heading" : 5.4,
    "precision" : 0.1,
    "speed" : 23.5,
    "timestamp" : 1191292288,
    "satellites" : 3,
    "status" : 2
  },
  "metrics": {
    "code" : { "string" : "A23D44567Q" },
    "distance" : { "double" : 0.26456E+4 },
    "temperature" : { "float" : 27.5 },
    "count" : { "int32" : 12354 },
    "timestamp" : { "int64" : 23412334545 },
    "enable" : { "bool" : true },
    "rawBuffer" : { "bytes" : "cGlwcG8gcGx1dG8gcGFwZXJpbm8=" }
  },
  "body": "UGlwcG8sIHBsdXRvLCBwYXBlcmlubywgcXVpLCBxdW8gZSBxdWEu"
}

The strongly typed section of the message deals with the metrics. Each metric value needs to be annotated with a type qualifier. As a consequence the metric itself is represented as an object. The key-value pair inside carries the type and the value of the metric in a compact format thus containing the same information encoded in a protobuf payload.

Timestamps (like "sentOn") are expressed in milliseconds, byte arrays (like "rawBuffer" or "body") are encoded as base64 strings.

The equivalent representation in xml will be the following:

<message>
  <sentOn>1491298822</sentOn>
  <position>
    <latitude>45.234</latitude>
    <longitude>-7.3456</longitude>
    <altitude>1.0</altitude>
    <heading>5.4</heading>
    <precision>0.1</precision>
    <speed>23.5</precision>
    <timestamp>1191292288</timestamp>
    <satellites>3</satellites>
    <status>2</status>
  </position>
  <metrics>
    <code type="string">A23D44567Q</code>
    <distance type="double">0,26456E+4</distance>
    <temperature type="float">27.5</temperature>
    <count type="int32">12354</count>
    <timestamp type="int64">23412334545</timestamp>
    <enable type="bool">true</enable>
    <rawBuffer type="bytes">cGlwcG8gcGx1dG8gcGFwZXJpbm8=</rawBuffer>
  </metrics>
  <body>UGlwcG8sIHBsdXRvLCBwYXBlcmlubywgcXVpLCBxdW8gZSBxdWEu</body>
</message>

Simple JSON Encoding

In this version the information of the types is removed. Clients which receive these messages either has an a-priori knowledge of the data sent or can make a best-effort decoding.

The following is an example of how a JSON payload could be structured:

{
  "sentOn" : 1491298822,
  "position" : {
    "latitude" : 45.234,
    "longitude" : -7.3456,
    "altitude" : 1.0,
    "heading" : 5.4,
    "precision" : 0.1,
    "speed" : 23.5,
    "timestamp" : 1191292288,
    "satellites" : 3,
    "status" : 2
  },
  "metrics": {
    "code" : "A23D44567Q",
    "distance" : 0.26456E+4,
    "temperature" : 27.5,
    "count" : 12354,
    "timestamp" : 23412334545,
    "enable" : true,
    "rawBuffer" : "cGlwcG8gcGx1dG8gcGFwZXJpbm8="
  },
  "body": "UGlwcG8sIHBsdXRvLCBwYXBlcmlubywgcXVpLCBxdW8gZSBxdWEu"
}

Kura-Kapua Communication

Publish (Kura):

Always encode the payload (including lifecycle messages) accordingly to the "preferred" KuraPayload protobuf/JSON encoding (a configuration property of the Kura CloudService). Add a new metric to the Birth Certificate to indicate the preferred KuraPayload protobuf/JSON encoding

Publish (Kapua):

If the encoding used by the gateway is not known yet (from the Birth Certificate), encode the payload as a KuraPayload protobuf [1]. This is backward compatible with Kura releases not supporting the new JSON encoding. If the encoding used by the gateway is known encode the payload accordingly

Receive (Kura):

Try to decode the payload accordingly to the preferred Kura Payload protobuf/JSON encoding If it fails, try the other decoder (just in case...) If it fails, wrap the binary payload as the body of an Java Kura Payload [2] (just in case...)

Receive (Kapua):

If the encoding used by the gateway is not known (from the Birth Certificate), try to decode the MQTT payload as an Kura Payload protobuf [1] If the encoding used by the gateway is known, try to decode the MQTT payload accordingly If it fails try the other decoder (just in case...) If it fails wrap the binary payload as the body of an Java Kura Payload [2]

[1] https://github.com/eclipse/kura/blob/KURA_2.1.0_RELEASE/kura/org.eclipse.kura.core.cloud/src/main/protobuf/kurapayload.proto

[2] https://github.com/eclipse/kura/blob/KURA_2.1.0_RELEASE/kura/org.eclipse.kura.api/src/main/java/org/eclipse/kura/message/KuraPayload.java

[3] http://ubjson.org