3

I have a iot-hub that receives both JSON and non-json (hex) messages. These all go to my Java function app to decode. Based on the device-id I'm calling a different decoder.

I'm trying to get the actual iothub-connection-device-id of the message I'm receiving.

public class TranslateEndpoint {
    /**
     * This function will be invoked when an event is received from Event Hub.
     */
    @FunctionName("TranslateEndpoint")
    public void run(
        @EventHubTrigger(name = "message", eventHubName = "NAME-DeviceIntegration", connection = "HostName=HOST;SharedAccessKeyName=NAME;SharedAccessKey=KEY=", consumerGroup = "$Default", cardinality = Cardinality.ONE) EventData message,
        final ExecutionContext context
    ) {
        context.getLogger().info("Java Event Hub trigger function executed.");
        context.getLogger().info("Length:" + message.toString());
        TranslateController temp = new TranslateController();

        // Build up a list with all the data

        context.getLogger().info(message.getSystemProperties().getPublisher());
        context.getLogger().info(message.getSystemProperties().getPartitionKey());
        context.getLogger().info(message.getSystemProperties().get("iothub-connection-device-id").toString());
    }

The code above is inspired by some C# code I found. Unfortunately I get an error Stack: java.lang.RuntimeException: Unable to invoke no-args constructor for interface com.microsoft.azure.eventhubs.EventData. Registering an InstanceCreator with Gson for this type may fix this problem.

Before I used a String and only got my actual payload. What is the proper way of receiving system properties of my message?

54m
  • 719
  • 2
  • 7
  • 18

1 Answers1

1

At least in Java, metadata properties have to be pulled in through additional, annotated parameters, in this case:

//The system properties, including the event data
@BindingName("SystemProperties") Map<String, Object> systemProperties

The device ID can then be retrieved from that parameter:

String deviceId = (String) systemProperties.get("iothub-connection-device-id");

The message parameter annotated with @EventHubTrigger should be a string or maybe a byte array. A POJO (or EventData for that matter) cannot be mapped in this case, as the backing data only contains the event payload/value.

So, the function should look like this:

public class TranslateEndpoint {
    /**
     * This function will be invoked when an event is received from Event Hub.
     */
    @FunctionName("TranslateEndpoint")
    public void run(
            @BindingName("SystemProperties") Map<String, Object> systemProperties,
            @EventHubTrigger(name = "message", eventHubName = "NAME-DeviceIntegration", connection = "HostName=HOST;SharedAccessKeyName=NAME;SharedAccessKey=KEY=", consumerGroup = "$Default", cardinality = Cardinality.ONE) String message,
            final ExecutionContext context
    ) {
        String deviceId = (String) systemProperties.get("iothub-connection-device-id");
        //decode/parse message string
        //...
    }
}

Documentation:

I can't help but say that the documentation could be less cumbersome, just like the APIs in all supported languages could be more consistent. I might still be missing something.

Sam
  • 7,778
  • 1
  • 23
  • 49