From f93f1fe6e6dbc938add283e74e5e9a9a2698764f Mon Sep 17 00:00:00 2001 From: Jon Skeet Date: Fri, 12 Mar 2021 15:14:28 +0000 Subject: [PATCH] feat: Make the MQTT protocol bindings follow conventions Signed-off-by: Jon Skeet --- .../MqttClientExtensions.cs | 57 +++++++++++++++++-- .../Mqtt/MqttTest.cs | 2 +- 2 files changed, 54 insertions(+), 5 deletions(-) diff --git a/src/CloudNative.CloudEvents.Mqtt/MqttClientExtensions.cs b/src/CloudNative.CloudEvents.Mqtt/MqttClientExtensions.cs index 5a3ab43..cf9b143 100644 --- a/src/CloudNative.CloudEvents.Mqtt/MqttClientExtensions.cs +++ b/src/CloudNative.CloudEvents.Mqtt/MqttClientExtensions.cs @@ -3,20 +3,69 @@ // See LICENSE file in the project root for full license information. using MQTTnet; +using System; +using System.Collections.Generic; namespace CloudNative.CloudEvents.Mqtt { + /// + /// Extension methods to convert between CloudEvents and MQTT messages. + /// public static class MqttClientExtensions { + /// + /// Converts this MQTT message into a CloudEvent object. + /// + /// The MQTT message to convert. Must not be null. + /// The event formatter to use to parse the CloudEvent. Must not be null. + /// The extension attributes to use when parsing the CloudEvent. May be null. + /// A reference to a validated CloudEvent instance. public static CloudEvent ToCloudEvent(this MqttApplicationMessage message, - CloudEventFormatter eventFormatter, params CloudEventAttribute[] extensionAttributes) + CloudEventFormatter formatter, params CloudEventAttribute[] extensionAttributes) => + ToCloudEvent(message, formatter, (IEnumerable) extensionAttributes); + + /// + /// Converts this MQTT message into a CloudEvent object. + /// + /// The MQTT message to convert. Must not be null. + /// The event formatter to use to parse the CloudEvent. Must not be null. + /// The extension attributes to use when parsing the CloudEvent. May be null. + /// A reference to a validated CloudEvent instance. + public static CloudEvent ToCloudEvent(this MqttApplicationMessage message, + CloudEventFormatter formatter, IEnumerable extensionAttributes) { + message = message ?? throw new ArgumentNullException(nameof(message)); + formatter = formatter ?? throw new ArgumentNullException(nameof(formatter)); + // TODO: Determine if there's a sensible content type we should apply. - return eventFormatter.DecodeStructuredModeMessage(message.Payload, contentType: null, extensionAttributes); + return formatter.DecodeStructuredModeMessage(message.Payload, contentType: null, extensionAttributes); } // TODO: Update to a newer version of MQTTNet and support both binary and structured mode? - public static MqttApplicationMessage ToMqttApplicationMessage(this CloudEvent cloudEvent, CloudEventFormatter formatter, string topic) => - new MqttApplicationMessage { Topic = topic, Payload = formatter.EncodeStructuredModeMessage(cloudEvent, out _)}; + /// + /// Converts a CloudEvent to . + /// + /// The CloudEvent to convert. Must not be null, and must be a valid CloudEvent. + /// Content mode. Currently only structured mode is supported. + /// The formatter to use within the conversion. Must not be null. + /// The MQTT topic for the message. May be null. + public static MqttApplicationMessage ToMqttApplicationMessage(this CloudEvent cloudEvent, ContentMode contentMode, CloudEventFormatter formatter, string topic) + { + cloudEvent = cloudEvent ?? throw new ArgumentNullException(nameof(cloudEvent)); + cloudEvent.ValidateForConversion(nameof(cloudEvent)); + formatter = formatter ?? throw new ArgumentNullException(nameof(formatter)); + + switch (contentMode) + { + case ContentMode.Structured: + return new MqttApplicationMessage + { + Topic = topic, + Payload = formatter.EncodeStructuredModeMessage(cloudEvent, out _) + }; + default: + throw new ArgumentOutOfRangeException(nameof(contentMode), $"Unsupported content mode: {contentMode}"); + } + } } } \ No newline at end of file diff --git a/test/CloudNative.CloudEvents.UnitTests/Mqtt/MqttTest.cs b/test/CloudNative.CloudEvents.UnitTests/Mqtt/MqttTest.cs index 36a7434..7c45760 100644 --- a/test/CloudNative.CloudEvents.UnitTests/Mqtt/MqttTest.cs +++ b/test/CloudNative.CloudEvents.UnitTests/Mqtt/MqttTest.cs @@ -63,7 +63,7 @@ namespace CloudNative.CloudEvents.Mqtt.UnitTests tcs.SetResult(args.ApplicationMessage.ToCloudEvent(jsonEventFormatter)); var result = await client.SubscribeAsync("abc"); - await client.PublishAsync(cloudEvent.ToMqttApplicationMessage(new JsonEventFormatter(), topic: "abc")); + await client.PublishAsync(cloudEvent.ToMqttApplicationMessage(ContentMode.Structured, new JsonEventFormatter(), topic: "abc")); var receivedCloudEvent = await tcs.Task; Assert.Equal(CloudEventsSpecVersion.Default, receivedCloudEvent.SpecVersion);