0
votes

I am writing a heartbeat function for devices. The following piece of code constructs the message envelope using Azure SDK for devices:

private Message constructHeartbeatEnvelope(final HeartbeatEvent heartbeat) throws JsonProcessingException {
    String jsonString = mapper.writeValueAsString(heartbeat);
    System.out.println(jsonString);
    final Message message = new Message(jsonString.getBytes(StandardCharsets.UTF_8));
    message.setProperty("type", "heartbeat");
    message.setContentTypeFinal("application/json");
    message.setExpiryTime(HEARTBEAT_INTERVAL);
    return message;
}

In the IoT Hub to which this device belongs, I have the following two routes for testing purposes:

+-----------------+----------------+--------------------------------------+------------+---------+
|      Name       |  Data Source   |            Routing Query             |  Endpoint  | Enabled |
+-----------------+----------------+--------------------------------------+------------+---------+
| heartbeat-route | DeviceMessages | $body.type.name = 'heartbeat/device' | events-dev | true    |
| events-dev-type | DeviceMessages | $type = 'heartbeat'                  | events-dev | true    |
+-----------------+----------------+--------------------------------------+------------+---------+

The body of the message looks like this:

{
    "created": 1568104629007,
    "type": {
        "name": "heartbeat/device",
        "version": "1.0"
    },
    "origin": "iothubdeviceid",
    "content": {
        // heartbeat metadata
    },
    "originId": "S1"
}

The fallback route is disabled.

The events-dev endpoint is an event hub which has a dedicated consumer group for these heartbeat events. Last in the chain is a function app which consumes from this event hub and only prints the body of what it receives for debug purposes.

However, when I view the metrics in my IoT Hub, it says zero messages are routed to an event hub and all of the messages sent are "orphaned".

Under Built-in endpoints I have also added an additional consumer group called heartbeats.

I have tried activating the fallback route and then using a modified sample from the Python SDK which only receives messages, I connected to the IoT Hub event hub and I can find the messages there, but I can't get routing to work at all. I also see that orphaned messages return to 0 in the metrics, and that messages routed to fallback goes up. I also do not get any messages on heartbeats consumer group when doing this approach, only on $Default.

What am I doing wrong here?

Solution:

Based on reply below, the following did the trick:

Remove $ for filtering on user-added property:

+-----------------+----------------+--------------------------------------+------------+---------+
|      Name       |  Data Source   |            Routing Query             |  Endpoint  | Enabled |
+-----------------+----------------+--------------------------------------+------------+---------+
| heartbeat-route | DeviceMessages | $body.type.name = 'heartbeat/device' | events-dev | true    |
| events-dev-type | DeviceMessages | type = 'heartbeat'                   | events-dev | true    |
+-----------------+----------------+--------------------------------------+------------+---------+

Set content encoding manually on the message envelope:

private Message constructHeartbeatEnvelope(final HeartbeatEvent heartbeat) throws JsonProcessingException {
    String jsonString = mapper.writeValueAsString(heartbeat);
    System.out.println(jsonString);
    final Message message = new Message(jsonString.getBytes(StandardCharsets.UTF_8));
    message.setProperty("type", "heartbeat");
    message.setContentTypeFinal("application/json");
    message.setContentEncoding("utf-8"); // <---- This line
    message.setExpiryTime(HEARTBEAT_INTERVAL);
    return message;
}

Body routing does not seem to be working despite the above fixes

1

1 Answers

1
votes

The following is a fix:

  1. type = 'heartbeat'
  2. set the message ContentEcoding for utf-8

See more details here.