Azure / iotedge

The IoT Edge OSS project
MIT License
1.45k stars 457 forks source link

EdgeHub fails to parse valid D2C creation time UTC string #7294

Open stefanb2 opened 1 month ago

stefanb2 commented 1 month ago

Expected Behavior

I follow the System Properties of D2C IoT messages table and add a creation time property to event messages. Those messages will be routed

Message creation & sending:

// e.g. "2024-05-23T07:50:52.598Z"
const now = new Date().toISOString();
const message = new Message(JSON.stringify(data));

message.properties.add('iothub-creation-time-utc', now);

client.sendOutputEvent(output, message);

This works fine when module uses MQTT protocol to connect to edgeHub:

import { Mqtt } from 'azure-iot-device-mqtt'
import { ModuleClient } from 'azure-iot-device'

client = await ModuleClient.fromEnvironment(Mqtt)

Current Behavior

When I switch the module from MQTT to AMQP protocol (NOTE: no other changes to the code!):

import { Amqp } from 'azure-iot-device-amqp'
import { ModuleClient } from 'azure-iot-device'

client = await ModuleClient.fromEnvironment(Amqp)

then messages are no longer routed from the Azure IoT Edge device to the Azure IoT Hub.

Instead you can now see an exception in edgeHub log, f.ex.

System.FormatException: String '2024-05-23T07:50:52.598Z' was not recognized as a valid DateTime.

The traceback points to this line in the edgeHub source code in DeviceClientMessageConverter.cs:

if (inputMessage.SystemProperties.TryGetNonEmptyValue(SystemProperties.CreationTime, out string creationTime))
{
  message.CreationTimeUtc = DateTime.ParseExact(creationTime, "o", CultureInfo.InvariantCulture);
}

The "o" format in the above line only seems to accept YYYY-MM-DDTHH:MM:SS.1234567Z as valid. I confirmed this by applying the following workaround to my code:

message.properties.add('iothub-creation-time-utc', now.replace(/Z$/, '0000Z'));

With the workaround in place the errors disappeared from the log and messages were routed again from the Azure IoT Edge device to the Azure IoT Hub.

Steps to Reproduce

  1. create an Azure IoT Edge device
  2. create a custom module with AMQP as protocol
  3. see the code snippets in the above description for the message creation
  4. deploy custom module to Azure IoT Edge device
  5. monitor events from the Azure IoT Edge device on the Azure IoT Hub

Context (Environment)

Device Information

Runtime Versions

Additional Information

What is the intention behind the strict DateTime.ParseExact(..., "o", ...) ("The round-trip ("O", "o") format specifier" according to .NET documentation)? It should accept any valid UTC ISO-8601 string.