From 450ba23e962843f967c60cf9f29aae8a389a1673 Mon Sep 17 00:00:00 2001 From: Jon Skeet Date: Fri, 12 Mar 2021 14:27:36 +0000 Subject: [PATCH] feat: Make the AMQP protocol bindings follow conventions Signed-off-by: Jon Skeet --- .../AmqpClientExtensions.cs | 54 +++++++++++++++---- 1 file changed, 45 insertions(+), 9 deletions(-) diff --git a/src/CloudNative.CloudEvents.Amqp/AmqpClientExtensions.cs b/src/CloudNative.CloudEvents.Amqp/AmqpClientExtensions.cs index a5818ca..6c595de 100644 --- a/src/CloudNative.CloudEvents.Amqp/AmqpClientExtensions.cs +++ b/src/CloudNative.CloudEvents.Amqp/AmqpClientExtensions.cs @@ -6,11 +6,15 @@ using Amqp; using Amqp.Framing; using Amqp.Types; using System; +using System.Collections.Generic; using System.IO; using System.Net.Mime; namespace CloudNative.CloudEvents.Amqp { + /// + /// Extension methods to convert between CloudEvents and AMQP messages. + /// public static class AmqpClientExtensions { internal const string AmqpHeaderPrefix = "cloudEvents:"; @@ -21,10 +25,34 @@ namespace CloudNative.CloudEvents.Amqp HasCloudEventsContentType(message, out _) || message.ApplicationProperties.Map.ContainsKey(SpecVersionAmqpHeader); - public static CloudEvent ToCloudEvent(this Message message, + /// + /// Converts this AMQP message into a CloudEvent object. + /// + /// The AMQP 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 Message message, CloudEventFormatter formatter, - params CloudEventAttribute[] extensionAttributes) + params CloudEventAttribute[] extensionAttributes) => + ToCloudEvent(message, formatter, (IEnumerable) extensionAttributes); + + /// + /// Converts this AMQP message into a CloudEvent object. + /// + /// The AMQP 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 Message message, + CloudEventFormatter formatter, + IEnumerable extensionAttributes) { + message = message ?? throw new ArgumentNullException(nameof(message)); + formatter = formatter ?? throw new ArgumentNullException(nameof(formatter)); + if (HasCloudEventsContentType(message, out var contentType)) { return formatter.DecodeStructuredModeMessage(new MemoryStream((byte[]) message.Body), new ContentType(contentType), extensionAttributes); @@ -32,15 +60,13 @@ namespace CloudNative.CloudEvents.Amqp else { var propertyMap = message.ApplicationProperties.Map; - if (!propertyMap.TryGetValue(SpecVersionAmqpHeader, out var versionId) || !(versionId is string versionIdText)) + if (!propertyMap.TryGetValue(SpecVersionAmqpHeader, out var versionId)) { throw new ArgumentException("Request is not a CloudEvent"); } - var version = CloudEventsSpecVersion.FromVersionId(versionIdText); - if (version is null) - { - throw new ArgumentException($"Unsupported CloudEvents spec version '{versionIdText}'"); - } + + var version = CloudEventsSpecVersion.FromVersionId(versionId as string) + ?? throw new ArgumentException($"Unknown CloudEvents spec version '{versionId}'", nameof(message)); var cloudEvent = new CloudEvent(version, extensionAttributes) { @@ -96,7 +122,7 @@ namespace CloudNative.CloudEvents.Amqp throw new ArgumentException("Binary mode data in AMQP message must be in the application data section"); } - return cloudEvent; + return cloudEvent.ValidateForConversion(nameof(message)); } } @@ -107,8 +133,18 @@ namespace CloudNative.CloudEvents.Amqp return contentType?.StartsWith(CloudEvent.MediaType) == true; } + /// + /// Converts a CloudEvent to . + /// + /// The CloudEvent to convert. Must not be null, and must be a valid CloudEvent. + /// Content mode. Structured or binary. + /// The formatter to use within the conversion. Must not be null. public static Message ToAmqpMessage(this CloudEvent cloudEvent, ContentMode contentMode, CloudEventFormatter formatter) { + cloudEvent = cloudEvent ?? throw new ArgumentNullException(nameof(cloudEvent)); + cloudEvent.ValidateForConversion(nameof(cloudEvent)); + formatter = formatter ?? throw new ArgumentNullException(nameof(formatter)); + var applicationProperties = MapHeaders(cloudEvent); RestrictedDescribed bodySection; Properties properties;