diff --git a/shared.csproj b/shared.csproj index a1b76554..2e66e880 100644 --- a/shared.csproj +++ b/shared.csproj @@ -1,7 +1,7 @@ - 0.7.1 + 0.7.2 9 enable CS8600;CS8602;CS8625;CS8618;CS8604;CS8601 diff --git a/src/Motor.Extensions.Hosting.RabbitMQ/BasicPropertiesExtensions.cs b/src/Motor.Extensions.Hosting.RabbitMQ/BasicPropertiesExtensions.cs index a26d3a98..73e9473b 100644 --- a/src/Motor.Extensions.Hosting.RabbitMQ/BasicPropertiesExtensions.cs +++ b/src/Motor.Extensions.Hosting.RabbitMQ/BasicPropertiesExtensions.cs @@ -84,10 +84,18 @@ public static MotorCloudEvent ExtractCloudEvent(this IBasicProperties se return cloudEvent; } - var hasVersion = attributes.TryGetValue(MotorVersionExtension.MotorVersionAttribute.Name, out var versionObject); - var version = hasVersion && versionObject is byte[] versionBytes - ? new Version(Encoding.UTF8.GetString(versionBytes)) - : null; + var hasVersion = + attributes.TryGetValue(MotorVersionExtension.MotorVersionAttribute.Name, out var versionObject); + Version? version = null; + if (hasVersion && versionObject is byte[] versionBytes) + { + var versionString = Encoding.UTF8.GetString(versionBytes); + // If the version is enclosed in double quotes, that means it has passed an old Motor.NET version as an + // unknown header. Therefore, the version number should not be trusted and instead, the version is set + // to null. + version = versionString.StartsWith("\"") || versionString.EndsWith("\"") ? null : new Version( + Encoding.UTF8.GetString(versionBytes)); + } foreach (var (key, value) in attributes) { diff --git a/test/Motor.Extensions.Hosting.RabbitMQ_IntegrationTest/BasicPropertiesExtensionsTest.cs b/test/Motor.Extensions.Hosting.RabbitMQ_IntegrationTest/BasicPropertiesExtensionsTest.cs index fe973ccb..7e5bd2c4 100644 --- a/test/Motor.Extensions.Hosting.RabbitMQ_IntegrationTest/BasicPropertiesExtensionsTest.cs +++ b/test/Motor.Extensions.Hosting.RabbitMQ_IntegrationTest/BasicPropertiesExtensionsTest.cs @@ -194,6 +194,45 @@ public void UpdateAndExtractCloudEvent_V0_6_0Header_ExtensionsAddedToCloudEvent( } } + [Fact] + public void UpdateAndExtractCloudEvent_V0_6_0HeaderWithIncorrectVersionField_ExtensionsAddedToCloudEvent() + { + var channel = _fixture.Connection.CreateModel(); + var basicProperties = channel.CreateBasicProperties(); + var publisherOptions = new RabbitMQPublisherOptions(); + var content = new byte[] { 1, 2, 3 }; + var inputCloudEvent = MotorCloudEvent.CreateTestCloudEvent(content); + var mockedApplicationNameService = Mock.Of(); + + basicProperties.Update(inputCloudEvent, publisherOptions); + // manipulate basic properties to simulate outdated version + basicProperties.Headers[ + $"{BasicPropertiesExtensions.CloudEventPrefix}{MotorVersionExtension.MotorVersionAttribute.Name}"] = + Encoding.UTF8.GetBytes("\"0.7.1.0\""); + basicProperties.ContentEncoding = null; + basicProperties.Headers.Add( + $"{BasicPropertiesExtensions.CloudEventPrefix}{CloudEventsSpecVersion.V1_0.DataContentTypeAttribute.Name}", + Encoding.UTF8.GetBytes($"{basicProperties.ContentType}")); + foreach (var (key, value) in basicProperties.Headers) + { + if (value is byte[] byteValue) + { + basicProperties.Headers[key] = EscapeWithQuotes(byteValue); + } + } + + var outputCloudEvent = basicProperties.ExtractCloudEvent(mockedApplicationNameService, + new ReadOnlyMemory(content)); + + // expecting all required attributes plus the (incorrect) version attribute + Assert.Equal(MotorCloudEventInfo.RequiredAttributes(Version.Parse("0.6.0.0")).Count() + 1, + outputCloudEvent.GetPopulatedAttributes().Count()); + foreach (var requiredAttribute in MotorCloudEventInfo.RequiredAttributes(Version.Parse("0.6.0.0"))) + { + Assert.Equal(inputCloudEvent[requiredAttribute], outputCloudEvent[requiredAttribute]); + } + } + private static Version CurrentMotorVersion => typeof(BasicPropertiesExtensionsTest).Assembly.GetName().Version; private static byte[] EscapeWithQuotes(byte[] value)