From ee1d7df8bf8dbc3569d2f43460156adb04c7bd84 Mon Sep 17 00:00:00 2001 From: JoshLove-msft <54595583+JoshLove-msft@users.noreply.github.com> Date: Mon, 16 Oct 2023 14:39:13 -0700 Subject: [PATCH 1/5] Use bytes to represent AMQP property map --- .../Shared/AmqpAnnotatedMessageConverter.cs | 18 +- .../src/Grpc/Proto/SettlementExtensions.cs | 15 -- .../src/Grpc/Proto/settlement.proto | 25 +-- .../src/Grpc/SettlementService.cs | 43 +++-- ...Azure.WebJobs.Extensions.ServiceBus.csproj | 3 + .../tests/Grpc/ServiceBusGrpcEndToEndTests.cs | 47 ++---- .../Grpc/ServiceBusGrpcEndToEndTestsBase.cs | 60 +++++++ .../ServiceBusGrpcSessionEndToEndTests.cs | 38 +---- .../tests/Grpc/SettlementPropertiesTests.cs | 158 +++++++++--------- .../tests/WebJobsServiceBusTestBase.cs | 6 - 10 files changed, 211 insertions(+), 202 deletions(-) create mode 100644 sdk/servicebus/Microsoft.Azure.WebJobs.Extensions.ServiceBus/tests/Grpc/ServiceBusGrpcEndToEndTestsBase.cs diff --git a/sdk/core/Azure.Core.Amqp/src/Shared/AmqpAnnotatedMessageConverter.cs b/sdk/core/Azure.Core.Amqp/src/Shared/AmqpAnnotatedMessageConverter.cs index 3b4a340a5428..22c97fdc90fb 100644 --- a/sdk/core/Azure.Core.Amqp/src/Shared/AmqpAnnotatedMessageConverter.cs +++ b/sdk/core/Azure.Core.Amqp/src/Shared/AmqpAnnotatedMessageConverter.cs @@ -329,7 +329,7 @@ public static AmqpAnnotatedMessage FromAmqpMessage(AmqpMessage source) if (source.Properties.CorrelationId != null) { - message.Properties.CorrelationId = new AmqpMessageId(source.Properties.CorrelationId.ToString()); + message.Properties.CorrelationId = new AmqpMessageId(source.Properties.CorrelationId.ToString()!); } if (source.Properties.CreationTime.HasValue) @@ -349,12 +349,12 @@ public static AmqpAnnotatedMessage FromAmqpMessage(AmqpMessage source) if (source.Properties.MessageId != null) { - message.Properties.MessageId = new AmqpMessageId(source.Properties.MessageId.ToString()); + message.Properties.MessageId = new AmqpMessageId(source.Properties.MessageId.ToString()!); } if (source.Properties.ReplyTo != null) { - message.Properties.ReplyTo = new AmqpAddress(source.Properties.ReplyTo.ToString()); + message.Properties.ReplyTo = new AmqpAddress(source.Properties.ReplyTo.ToString()!); } if (!string.IsNullOrEmpty(source.Properties.ReplyToGroupId)) @@ -369,10 +369,10 @@ public static AmqpAnnotatedMessage FromAmqpMessage(AmqpMessage source) if (source.Properties.To != null) { - message.Properties.To = new AmqpAddress(source.Properties.To.ToString()); + message.Properties.To = new AmqpAddress(source.Properties.To.ToString()!); } - if (source.Properties.UserId != null) + if (source.Properties.UserId != default) { message.Properties.UserId = source.Properties.UserId; } @@ -579,7 +579,7 @@ private static bool TryGetValueBody(AmqpMessage source, out AmqpMessageBody? val /// /// true if an AMQP property value was able to be created; otherwise, false. /// - private static bool TryCreateAmqpPropertyValueFromNetProperty( + public static bool TryCreateAmqpPropertyValueFromNetProperty( object? propertyValue, out object? amqpPropertyValue, bool allowBodyTypes = false) @@ -659,7 +659,7 @@ private static bool TryCreateAmqpPropertyValueFromNetProperty( /// /// true if a message property value was able to be created; otherwise, false. /// - private static bool TryCreateNetPropertyFromAmqpProperty( + public static bool TryCreateNetPropertyFromAmqpProperty( object? amqpPropertyValue, out object? convertedPropertyValue, bool allowBodyTypes = false) @@ -715,13 +715,13 @@ private static bool TryCreateNetPropertyFromAmqpProperty( convertedPropertyValue = listOrArray; break; - case ArraySegment segment when segment.Count == segment.Array.Length: + case ArraySegment segment when segment.Count == segment.Array!.Length: convertedPropertyValue = segment.Array; break; case ArraySegment segment: var buffer = new byte[segment.Count]; - Buffer.BlockCopy(segment.Array, segment.Offset, buffer, 0, segment.Count); + Buffer.BlockCopy(segment.Array!, segment.Offset, buffer, 0, segment.Count); convertedPropertyValue = buffer; break; diff --git a/sdk/servicebus/Microsoft.Azure.WebJobs.Extensions.ServiceBus/src/Grpc/Proto/SettlementExtensions.cs b/sdk/servicebus/Microsoft.Azure.WebJobs.Extensions.ServiceBus/src/Grpc/Proto/SettlementExtensions.cs index b3118786d773..092525713613 100644 --- a/sdk/servicebus/Microsoft.Azure.WebJobs.Extensions.ServiceBus/src/Grpc/Proto/SettlementExtensions.cs +++ b/sdk/servicebus/Microsoft.Azure.WebJobs.Extensions.ServiceBus/src/Grpc/Proto/SettlementExtensions.cs @@ -8,21 +8,6 @@ namespace Microsoft.Azure.WebJobs.Extensions.ServiceBus.Grpc { internal static class SettlementExtensions { - internal static object GetPropertyValue(this SettlementProperties properties) - { - return properties.ValuesCase switch - { - SettlementProperties.ValuesOneofCase.LongValue => properties.LongValue, - SettlementProperties.ValuesOneofCase.UlongValue => properties.UlongValue, - SettlementProperties.ValuesOneofCase.DoubleValue => properties.DoubleValue, - SettlementProperties.ValuesOneofCase.FloatValue => properties.FloatValue, - SettlementProperties.ValuesOneofCase.IntValue => properties.IntValue, - SettlementProperties.ValuesOneofCase.UintValue => properties.UintValue, - SettlementProperties.ValuesOneofCase.BoolValue => properties.BoolValue, - SettlementProperties.ValuesOneofCase.StringValue => properties.StringValue, - _ => null - }; - } } } #endif \ No newline at end of file diff --git a/sdk/servicebus/Microsoft.Azure.WebJobs.Extensions.ServiceBus/src/Grpc/Proto/settlement.proto b/sdk/servicebus/Microsoft.Azure.WebJobs.Extensions.ServiceBus/src/Grpc/Proto/settlement.proto index 9c6c45d0be96..fdca72531b00 100644 --- a/sdk/servicebus/Microsoft.Azure.WebJobs.Extensions.ServiceBus/src/Grpc/Proto/settlement.proto +++ b/sdk/servicebus/Microsoft.Azure.WebJobs.Extensions.ServiceBus/src/Grpc/Proto/settlement.proto @@ -29,13 +29,13 @@ message CompleteRequest { // The abandon message request containing the locktoken and properties to modify. message AbandonRequest { string locktoken = 1; - map propertiesToModify = 2; + bytes propertiesToModify = 2; } // The deadletter message request containing the locktoken and properties to modify along with the reason/description. message DeadletterRequest { string locktoken = 1; - map propertiesToModify = 2; + bytes propertiesToModify = 2; string deadletterReason = 3; string deadletterErrorDescription = 4; } @@ -43,24 +43,5 @@ message DeadletterRequest { // The defer message request containing the locktoken and properties to modify. message DeferRequest { string locktoken = 1; - map propertiesToModify = 2; -} - -// The settlement property can be of any type listed below, which -// corresponds to the types specified in -// https://learn.microsoft.com/en-us/dotnet/api/azure.messaging.servicebus.servicebusmessage.applicationproperties?view=azure-dotnet#remarks -// Note: this list doesn't match 1:1 with the supported Service Bus types, so compatible types are used in some cases - e.g. -// short uses int, TimeSpan uses string, etc. The full list of transforms can be found in the isolated worker extension source code. -message SettlementProperties { - oneof values { - string stringValue = 1; - int32 intValue = 2; - uint32 uintValue = 3; - int64 longValue = 4; - uint64 ulongValue = 5; - bool boolValue = 6; - float floatValue = 7; - double doubleValue = 8; - google.protobuf.Timestamp timestampValue = 9; - } + bytes propertiesToModify = 2; } diff --git a/sdk/servicebus/Microsoft.Azure.WebJobs.Extensions.ServiceBus/src/Grpc/SettlementService.cs b/sdk/servicebus/Microsoft.Azure.WebJobs.Extensions.ServiceBus/src/Grpc/SettlementService.cs index 832272828267..d8d490cbb90a 100644 --- a/sdk/servicebus/Microsoft.Azure.WebJobs.Extensions.ServiceBus/src/Grpc/SettlementService.cs +++ b/sdk/servicebus/Microsoft.Azure.WebJobs.Extensions.ServiceBus/src/Grpc/SettlementService.cs @@ -2,11 +2,14 @@ // Licensed under the MIT License. #if NET6_0_OR_GREATER -using System; -using System.Linq; +using System.Collections.Generic; using System.Threading.Tasks; +using Azure.Core.Amqp.Shared; +using Google.Protobuf; using Google.Protobuf.WellKnownTypes; using Grpc.Core; +using Microsoft.Azure.Amqp; +using Microsoft.Azure.Amqp.Encoding; using Microsoft.Azure.ServiceBus.Grpc; using Microsoft.Azure.WebJobs.ServiceBus; @@ -44,9 +47,7 @@ public override async Task Abandon(AbandonRequest request, ServerCallCont { await tuple.Actions.AbandonMessageAsync( tuple.Message, - request.PropertiesToModify.ToDictionary( - pair => pair.Key, - pair => pair.Value.GetPropertyValue()), + DeserializeAmqpMap(request.PropertiesToModify), context.CancellationToken).ConfigureAwait(false); return new Empty(); } @@ -59,9 +60,7 @@ public override async Task Defer(DeferRequest request, ServerCallContext { await tuple.Actions.DeferMessageAsync( tuple.Message, - request.PropertiesToModify.ToDictionary( - pair => pair.Key, - pair => pair.Value.GetPropertyValue()), + DeserializeAmqpMap(request.PropertiesToModify), context.CancellationToken).ConfigureAwait(false); return new Empty(); } @@ -74,9 +73,7 @@ public override async Task Deadletter(DeadletterRequest request, ServerCa { await tuple.Actions.DeadLetterMessageAsync( tuple.Message, - request.PropertiesToModify.ToDictionary( - pair => pair.Key, - pair => pair.Value.GetPropertyValue()), + DeserializeAmqpMap(request.PropertiesToModify), request.DeadletterReason, request.DeadletterErrorDescription, context.CancellationToken).ConfigureAwait(false); @@ -84,6 +81,30 @@ await tuple.Actions.DeadLetterMessageAsync( } throw new RpcException (new Status(StatusCode.FailedPrecondition, $"LockToken {request.Locktoken} not found.")); } + + private static Dictionary DeserializeAmqpMap(ByteString mapBytes) + { + if (mapBytes == null || mapBytes == ByteString.Empty) + { + return null; + } + + var bytes = mapBytes.ToByteArray(); + using ByteBuffer buffer = new ByteBuffer(bytes.Length, false); + AmqpBitConverter.WriteBytes(buffer, bytes, 0, bytes.Length); + var map = AmqpCodec.DecodeMap(buffer); + var dict = new Dictionary(map.Count); + foreach (var pair in map) + { + // This matches the behavior when constructing a ServiceBusReceivedMessage in the SDK. + if (AmqpAnnotatedMessageConverter.TryCreateNetPropertyFromAmqpProperty(pair.Value, out object value)) + { + dict[pair.Key.ToString()] = value; + } + } + + return dict; + } } } #endif \ No newline at end of file diff --git a/sdk/servicebus/Microsoft.Azure.WebJobs.Extensions.ServiceBus/src/Microsoft.Azure.WebJobs.Extensions.ServiceBus.csproj b/sdk/servicebus/Microsoft.Azure.WebJobs.Extensions.ServiceBus/src/Microsoft.Azure.WebJobs.Extensions.ServiceBus.csproj index 77ac3d72bb2b..ba0898e39f32 100644 --- a/sdk/servicebus/Microsoft.Azure.WebJobs.Extensions.ServiceBus/src/Microsoft.Azure.WebJobs.Extensions.ServiceBus.csproj +++ b/sdk/servicebus/Microsoft.Azure.WebJobs.Extensions.ServiceBus/src/Microsoft.Azure.WebJobs.Extensions.ServiceBus.csproj @@ -34,6 +34,7 @@ + @@ -47,5 +48,7 @@ + + diff --git a/sdk/servicebus/Microsoft.Azure.WebJobs.Extensions.ServiceBus/tests/Grpc/ServiceBusGrpcEndToEndTests.cs b/sdk/servicebus/Microsoft.Azure.WebJobs.Extensions.ServiceBus/tests/Grpc/ServiceBusGrpcEndToEndTests.cs index 725e8948ebc4..3b0b48e597d0 100644 --- a/sdk/servicebus/Microsoft.Azure.WebJobs.Extensions.ServiceBus/tests/Grpc/ServiceBusGrpcEndToEndTests.cs +++ b/sdk/servicebus/Microsoft.Azure.WebJobs.Extensions.ServiceBus/tests/Grpc/ServiceBusGrpcEndToEndTests.cs @@ -2,12 +2,17 @@ // Licensed under the MIT License. #if NET6_0_OR_GREATER using System; +using System.Collections; +using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; using Azure.Messaging.ServiceBus; using Azure.Messaging.ServiceBus.Tests; +using Google.Protobuf; using Grpc.Core; +using Microsoft.Azure.Amqp; +using Microsoft.Azure.Amqp.Encoding; using Microsoft.Azure.ServiceBus.Grpc; using Microsoft.Azure.WebJobs.Extensions.ServiceBus.Grpc; using Microsoft.Azure.WebJobs.ServiceBus; @@ -16,7 +21,7 @@ namespace Microsoft.Azure.WebJobs.Host.EndToEndTests { - public class ServiceBusGrpcEndToEndTests : WebJobsServiceBusTestBase + public class ServiceBusGrpcEndToEndTests : ServiceBusGrpcEndToEndTestsBase { public ServiceBusGrpcEndToEndTests() : base(isSession: false) { @@ -242,7 +247,7 @@ await SettlementService.Deadletter( Locktoken = message.LockToken, DeadletterErrorDescription = "description", DeadletterReason = "reason", - PropertiesToModify = {{ "key", new SettlementProperties { IntValue = 42} }} + PropertiesToModify = EncodeDictionary(new Dictionary{{ "key", 42}}) }, new MockServerCallContext()); @@ -266,13 +271,17 @@ public static async Task BindToMessage( var message = messages.Single(); Assert.AreEqual("foobar", message.Body.ToString()); + var dict = new Dictionary { { "key", 42 } }; + var map = new AmqpMap(dict); + var buffer = new ByteBuffer(200, true); + AmqpCodec.EncodeMap(map, buffer); await SettlementService.Deadletter( new DeadletterRequest() { Locktoken = message.LockToken, DeadletterErrorDescription = "description", DeadletterReason = "reason", - PropertiesToModify = { { "key", new SettlementProperties { IntValue = 42 } } } + PropertiesToModify = ByteString.CopyFrom(buffer.Buffer) }, new MockServerCallContext()); @@ -298,7 +307,7 @@ await SettlementService.Defer( new DeferRequest { Locktoken = message.LockToken, - PropertiesToModify = {{ "key", new SettlementProperties { BoolValue = true} }} + PropertiesToModify = EncodeDictionary(new Dictionary{{ "key", true}}) }, new MockServerCallContext()); var deferredMessage = (await receiveActions.ReceiveDeferredMessagesAsync( @@ -322,7 +331,7 @@ await SettlementService.Defer( new DeferRequest { Locktoken = message.LockToken, - PropertiesToModify = {{ "key", new SettlementProperties { BoolValue = true} }} + PropertiesToModify = EncodeDictionary(new Dictionary{{ "key", true}}) }, new MockServerCallContext()); var deferredMessage = (await receiveActions.ReceiveDeferredMessagesAsync( @@ -344,7 +353,7 @@ await SettlementService.Abandon( new AbandonRequest { Locktoken = message.LockToken, - PropertiesToModify = {{ "key", new SettlementProperties { StringValue = "value"} }} + PropertiesToModify = EncodeDictionary(new Dictionary{{ "key", "value"}}) }, new MockServerCallContext()); _waitHandle1.Set(); @@ -364,36 +373,12 @@ await SettlementService.Abandon( new AbandonRequest { Locktoken = message.LockToken, - PropertiesToModify = {{ "key", new SettlementProperties { StringValue = "value"} }} + PropertiesToModify = EncodeDictionary(new Dictionary{{ "key", "value"}}) }, new MockServerCallContext()); _waitHandle1.Set(); } } - - internal class MockServerCallContext : ServerCallContext - { - protected override Task WriteResponseHeadersAsyncCore(Metadata responseHeaders) - { - throw new NotImplementedException(); - } - - protected override ContextPropagationToken CreatePropagationTokenCore(ContextPropagationOptions options) - { - throw new NotImplementedException(); - } - - protected override string MethodCore { get; } - protected override string HostCore { get; } - protected override string PeerCore { get; } - protected override DateTime DeadlineCore { get; } - protected override Metadata RequestHeadersCore { get; } - protected override CancellationToken CancellationTokenCore { get; } = CancellationToken.None; - protected override Metadata ResponseTrailersCore { get; } - protected override Status StatusCore { get; set; } - protected override WriteOptions WriteOptionsCore { get; set; } - protected override AuthContext AuthContextCore { get; } - } } } #endif \ No newline at end of file diff --git a/sdk/servicebus/Microsoft.Azure.WebJobs.Extensions.ServiceBus/tests/Grpc/ServiceBusGrpcEndToEndTestsBase.cs b/sdk/servicebus/Microsoft.Azure.WebJobs.Extensions.ServiceBus/tests/Grpc/ServiceBusGrpcEndToEndTestsBase.cs new file mode 100644 index 000000000000..f82cb38e2bb2 --- /dev/null +++ b/sdk/servicebus/Microsoft.Azure.WebJobs.Extensions.ServiceBus/tests/Grpc/ServiceBusGrpcEndToEndTestsBase.cs @@ -0,0 +1,60 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +#if NET6_0_OR_GREATER +using System; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; +using Azure.Core.Amqp.Shared; +using Google.Protobuf; +using Grpc.Core; +using Microsoft.Azure.Amqp; +using Microsoft.Azure.Amqp.Encoding; + +namespace Microsoft.Azure.WebJobs.Host.EndToEndTests +{ + public class ServiceBusGrpcEndToEndTestsBase : WebJobsServiceBusTestBase + { + public ServiceBusGrpcEndToEndTestsBase(bool isSession) : base(isSession) + { + } + + public static ByteString EncodeDictionary(IDictionary dictionary) + { + var map = new AmqpMap(); + foreach (KeyValuePair kvp in dictionary) + { + AmqpAnnotatedMessageConverter.TryCreateAmqpPropertyValueFromNetProperty(kvp.Value, out var amqpValue); + map.Add(new MapKey(kvp.Key), amqpValue); + } + using ByteBuffer buffer = new ByteBuffer(256, true); + AmqpCodec.EncodeMap(map, buffer); + return ByteString.CopyFrom(buffer.Buffer, 0, buffer.Length); + } + + internal class MockServerCallContext : ServerCallContext + { + protected override Task WriteResponseHeadersAsyncCore(Metadata responseHeaders) + { + throw new NotImplementedException(); + } + + protected override ContextPropagationToken CreatePropagationTokenCore(ContextPropagationOptions options) + { + throw new NotImplementedException(); + } + + protected override string MethodCore { get; } + protected override string HostCore { get; } + protected override string PeerCore { get; } + protected override DateTime DeadlineCore { get; } + protected override Metadata RequestHeadersCore { get; } + protected override CancellationToken CancellationTokenCore { get; } = CancellationToken.None; + protected override Metadata ResponseTrailersCore { get; } + protected override Status StatusCore { get; set; } + protected override WriteOptions WriteOptionsCore { get; set; } + protected override AuthContext AuthContextCore { get; } + } + } +} +#endif \ No newline at end of file diff --git a/sdk/servicebus/Microsoft.Azure.WebJobs.Extensions.ServiceBus/tests/Grpc/ServiceBusGrpcSessionEndToEndTests.cs b/sdk/servicebus/Microsoft.Azure.WebJobs.Extensions.ServiceBus/tests/Grpc/ServiceBusGrpcSessionEndToEndTests.cs index 7a39c9f1bb3c..e8acb12e4991 100644 --- a/sdk/servicebus/Microsoft.Azure.WebJobs.Extensions.ServiceBus/tests/Grpc/ServiceBusGrpcSessionEndToEndTests.cs +++ b/sdk/servicebus/Microsoft.Azure.WebJobs.Extensions.ServiceBus/tests/Grpc/ServiceBusGrpcSessionEndToEndTests.cs @@ -2,12 +2,16 @@ // Licensed under the MIT License. #if NET6_0_OR_GREATER using System; +using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; using Azure.Messaging.ServiceBus; using Azure.Messaging.ServiceBus.Tests; +using Google.Protobuf; using Grpc.Core; +using Microsoft.Azure.Amqp; +using Microsoft.Azure.Amqp.Encoding; using Microsoft.Azure.ServiceBus.Grpc; using Microsoft.Azure.WebJobs.Extensions.ServiceBus.Grpc; using Microsoft.Azure.WebJobs.ServiceBus; @@ -16,7 +20,7 @@ namespace Microsoft.Azure.WebJobs.Host.EndToEndTests { - public class ServiceBusGrpcSessionEndToEndTests : WebJobsServiceBusTestBase + public class ServiceBusGrpcSessionEndToEndTests : ServiceBusGrpcEndToEndTestsBase { public ServiceBusGrpcSessionEndToEndTests() : base(isSession: true) { @@ -128,7 +132,7 @@ public async Task BindToSessionMessageAndAbandon() var receiver = await client.AcceptNextSessionAsync(FirstQueueScope.QueueName); var abandonedMessage = (await receiver.ReceiveMessagesAsync(1)).Single(); Assert.AreEqual("foobar", abandonedMessage.Body.ToString()); - Assert.AreEqual("value", abandonedMessage.ApplicationProperties["key"]); + Assert.AreEqual(TimeSpan.FromSeconds(60), abandonedMessage.ApplicationProperties["key"]); Assert.IsEmpty(provider.ActionsCache); } @@ -170,7 +174,7 @@ await SettlementService.Deadletter( Locktoken = message.LockToken, DeadletterErrorDescription = "description", DeadletterReason = "reason", - PropertiesToModify = {{ "key", new SettlementProperties { IntValue = 42} }} + PropertiesToModify = EncodeDictionary(new Dictionary {{ "key", 42}}) }, new MockServerCallContext()); @@ -195,7 +199,7 @@ await SettlementService.Defer( new DeferRequest { Locktoken = message.LockToken, - PropertiesToModify = {{ "key", new SettlementProperties { BoolValue = true} }} + PropertiesToModify = EncodeDictionary(new Dictionary {{ "key", true}}) }, new MockServerCallContext()); var deferredMessage = (await receiveActions.ReceiveDeferredMessagesAsync( @@ -217,36 +221,12 @@ await SettlementService.Abandon( new AbandonRequest { Locktoken = message.LockToken, - PropertiesToModify = {{ "key", new SettlementProperties { StringValue = "value"} }} + PropertiesToModify = EncodeDictionary(new Dictionary {{ "key", TimeSpan.FromSeconds(60)}}) }, new MockServerCallContext()); _waitHandle1.Set(); } } - - internal class MockServerCallContext : ServerCallContext - { - protected override Task WriteResponseHeadersAsyncCore(Metadata responseHeaders) - { - throw new NotImplementedException(); - } - - protected override ContextPropagationToken CreatePropagationTokenCore(ContextPropagationOptions options) - { - throw new NotImplementedException(); - } - - protected override string MethodCore { get; } - protected override string HostCore { get; } - protected override string PeerCore { get; } - protected override DateTime DeadlineCore { get; } - protected override Metadata RequestHeadersCore { get; } - protected override CancellationToken CancellationTokenCore { get; } = CancellationToken.None; - protected override Metadata ResponseTrailersCore { get; } - protected override Status StatusCore { get; set; } - protected override WriteOptions WriteOptionsCore { get; set; } - protected override AuthContext AuthContextCore { get; } - } } } #endif \ No newline at end of file diff --git a/sdk/servicebus/Microsoft.Azure.WebJobs.Extensions.ServiceBus/tests/Grpc/SettlementPropertiesTests.cs b/sdk/servicebus/Microsoft.Azure.WebJobs.Extensions.ServiceBus/tests/Grpc/SettlementPropertiesTests.cs index 57a341556981..dd7e62afcc89 100644 --- a/sdk/servicebus/Microsoft.Azure.WebJobs.Extensions.ServiceBus/tests/Grpc/SettlementPropertiesTests.cs +++ b/sdk/servicebus/Microsoft.Azure.WebJobs.Extensions.ServiceBus/tests/Grpc/SettlementPropertiesTests.cs @@ -9,85 +9,85 @@ namespace Microsoft.Azure.WebJobs.ServiceBus.UnitTests.Grpc { public class SettlementPropertiesTests { - [Test] - public void CanGetStringValue() - { - var properties = new SettlementProperties - { - StringValue = "foo" - }; - Assert.AreEqual("foo", properties.GetPropertyValue()); - } - - [Test] - public void CanGetIntValue() - { - var properties = new SettlementProperties - { - IntValue = 42 - }; - Assert.AreEqual(42, properties.GetPropertyValue()); - } - - [Test] - public void CanGetUintValue() - { - var properties = new SettlementProperties - { - UintValue = 42 - }; - Assert.AreEqual(42, properties.GetPropertyValue()); - } - - [Test] - public void CanGetLongValue() - { - var properties = new SettlementProperties - { - LongValue = 42 - }; - Assert.AreEqual(42, properties.GetPropertyValue()); - } - - [Test] - public void CanGetUlongValue() - { - var properties = new SettlementProperties - { - UlongValue = 42 - }; - Assert.AreEqual(42, properties.GetPropertyValue()); - } - - [Test] - public void CanGetFloatValue() - { - var properties = new SettlementProperties - { - FloatValue = 42.0f - }; - Assert.AreEqual(42.0, properties.GetPropertyValue()); - } - - [Test] - public void CanGetDoubleValue() - { - var properties = new SettlementProperties - { - DoubleValue = 42.0 - }; - Assert.AreEqual(42.0, properties.GetPropertyValue()); - } - - [Test] - public void CanGetBoolValue() - { - var properties = new SettlementProperties - { - BoolValue = true - }; - Assert.IsTrue((bool)properties.GetPropertyValue()); - } + // [Test] + // public void CanGetStringValue() + // { + // var properties = new SettlementProperties + // { + // StringValue = "foo" + // }; + // Assert.AreEqual("foo", properties.GetPropertyValue()); + // } + // + // [Test] + // public void CanGetIntValue() + // { + // var properties = new SettlementProperties + // { + // IntValue = 42 + // }; + // Assert.AreEqual(42, properties.GetPropertyValue()); + // } + // + // [Test] + // public void CanGetUintValue() + // { + // var properties = new SettlementProperties + // { + // UintValue = 42 + // }; + // Assert.AreEqual(42, properties.GetPropertyValue()); + // } + // + // [Test] + // public void CanGetLongValue() + // { + // var properties = new SettlementProperties + // { + // LongValue = 42 + // }; + // Assert.AreEqual(42, properties.GetPropertyValue()); + // } + // + // [Test] + // public void CanGetUlongValue() + // { + // var properties = new SettlementProperties + // { + // UlongValue = 42 + // }; + // Assert.AreEqual(42, properties.GetPropertyValue()); + // } + // + // [Test] + // public void CanGetFloatValue() + // { + // var properties = new SettlementProperties + // { + // FloatValue = 42.0f + // }; + // Assert.AreEqual(42.0, properties.GetPropertyValue()); + // } + // + // [Test] + // public void CanGetDoubleValue() + // { + // var properties = new SettlementProperties + // { + // DoubleValue = 42.0 + // }; + // Assert.AreEqual(42.0, properties.GetPropertyValue()); + // } + // + // [Test] + // public void CanGetBoolValue() + // { + // var properties = new SettlementProperties + // { + // BoolValue = true + // }; + // Assert.IsTrue((bool)properties.GetPropertyValue()); + // } } } #endif \ No newline at end of file diff --git a/sdk/servicebus/Microsoft.Azure.WebJobs.Extensions.ServiceBus/tests/WebJobsServiceBusTestBase.cs b/sdk/servicebus/Microsoft.Azure.WebJobs.Extensions.ServiceBus/tests/WebJobsServiceBusTestBase.cs index 5353e6ef5cd1..9d5775e618fa 100644 --- a/sdk/servicebus/Microsoft.Azure.WebJobs.Extensions.ServiceBus/tests/WebJobsServiceBusTestBase.cs +++ b/sdk/servicebus/Microsoft.Azure.WebJobs.Extensions.ServiceBus/tests/WebJobsServiceBusTestBase.cs @@ -336,12 +336,6 @@ public async Task StopAsync(CancellationToken cancellationToken) QueueRuntimeProperties properties = await client.GetQueueRuntimePropertiesAsync(FirstQueueScope.QueueName, CancellationToken.None); Assert.AreEqual(ExpectedRemainingMessages, properties.ActiveMessageCount); - - var provider = _host.Services.GetService(); - Assert.AreEqual(0, provider.ClientCache.Count); - Assert.AreEqual(0, provider.MessageReceiverCache.Count); - Assert.AreEqual(0, provider.MessageSenderCache.Count); - Assert.AreEqual(0, provider.ActionsCache.Count); } private static bool IsError(LogMessage logMessage) From d0e82f8f117d62e43efd88826b07273d0cb0447c Mon Sep 17 00:00:00 2001 From: JoshLove-msft <54595583+JoshLove-msft@users.noreply.github.com> Date: Mon, 16 Oct 2023 14:47:30 -0700 Subject: [PATCH 2/5] Delete SettlementPropertiesTests.cs --- .../tests/Grpc/SettlementPropertiesTests.cs | 93 ------------------- 1 file changed, 93 deletions(-) delete mode 100644 sdk/servicebus/Microsoft.Azure.WebJobs.Extensions.ServiceBus/tests/Grpc/SettlementPropertiesTests.cs diff --git a/sdk/servicebus/Microsoft.Azure.WebJobs.Extensions.ServiceBus/tests/Grpc/SettlementPropertiesTests.cs b/sdk/servicebus/Microsoft.Azure.WebJobs.Extensions.ServiceBus/tests/Grpc/SettlementPropertiesTests.cs deleted file mode 100644 index dd7e62afcc89..000000000000 --- a/sdk/servicebus/Microsoft.Azure.WebJobs.Extensions.ServiceBus/tests/Grpc/SettlementPropertiesTests.cs +++ /dev/null @@ -1,93 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. -#if NET6_0_OR_GREATER -using Microsoft.Azure.ServiceBus.Grpc; -using Microsoft.Azure.WebJobs.Extensions.ServiceBus.Grpc; -using NUnit.Framework; - -namespace Microsoft.Azure.WebJobs.ServiceBus.UnitTests.Grpc -{ - public class SettlementPropertiesTests - { - // [Test] - // public void CanGetStringValue() - // { - // var properties = new SettlementProperties - // { - // StringValue = "foo" - // }; - // Assert.AreEqual("foo", properties.GetPropertyValue()); - // } - // - // [Test] - // public void CanGetIntValue() - // { - // var properties = new SettlementProperties - // { - // IntValue = 42 - // }; - // Assert.AreEqual(42, properties.GetPropertyValue()); - // } - // - // [Test] - // public void CanGetUintValue() - // { - // var properties = new SettlementProperties - // { - // UintValue = 42 - // }; - // Assert.AreEqual(42, properties.GetPropertyValue()); - // } - // - // [Test] - // public void CanGetLongValue() - // { - // var properties = new SettlementProperties - // { - // LongValue = 42 - // }; - // Assert.AreEqual(42, properties.GetPropertyValue()); - // } - // - // [Test] - // public void CanGetUlongValue() - // { - // var properties = new SettlementProperties - // { - // UlongValue = 42 - // }; - // Assert.AreEqual(42, properties.GetPropertyValue()); - // } - // - // [Test] - // public void CanGetFloatValue() - // { - // var properties = new SettlementProperties - // { - // FloatValue = 42.0f - // }; - // Assert.AreEqual(42.0, properties.GetPropertyValue()); - // } - // - // [Test] - // public void CanGetDoubleValue() - // { - // var properties = new SettlementProperties - // { - // DoubleValue = 42.0 - // }; - // Assert.AreEqual(42.0, properties.GetPropertyValue()); - // } - // - // [Test] - // public void CanGetBoolValue() - // { - // var properties = new SettlementProperties - // { - // BoolValue = true - // }; - // Assert.IsTrue((bool)properties.GetPropertyValue()); - // } - } -} -#endif \ No newline at end of file From 58d77e3ed639c120a35c2131973b4d9eebed1b94 Mon Sep 17 00:00:00 2001 From: JoshLove-msft <54595583+JoshLove-msft@users.noreply.github.com> Date: Tue, 17 Oct 2023 09:38:11 -0700 Subject: [PATCH 3/5] PR fb --- .../Shared/AmqpAnnotatedMessageConverter.cs | 272 +++++++++--------- .../ServiceBusGrpcSessionEndToEndTests.cs | 20 +- 2 files changed, 154 insertions(+), 138 deletions(-) diff --git a/sdk/core/Azure.Core.Amqp/src/Shared/AmqpAnnotatedMessageConverter.cs b/sdk/core/Azure.Core.Amqp/src/Shared/AmqpAnnotatedMessageConverter.cs index 22c97fdc90fb..bbfd10b59887 100644 --- a/sdk/core/Azure.Core.Amqp/src/Shared/AmqpAnnotatedMessageConverter.cs +++ b/sdk/core/Azure.Core.Amqp/src/Shared/AmqpAnnotatedMessageConverter.cs @@ -433,142 +433,6 @@ public static AmqpAnnotatedMessage FromAmqpMessage(AmqpMessage source) return message; } - /// - /// Translates the data body segments into the corresponding set of - /// instances. - /// - /// - /// The data body to translate. - /// - /// The set of instances that represents the . - /// - private static IEnumerable TranslateDataBody(IEnumerable> dataBody) - { - foreach (var bodySegment in dataBody) - { - if (!MemoryMarshal.TryGetArray(bodySegment, out ArraySegment dataSegment)) - { - dataSegment = new ArraySegment(bodySegment.ToArray()); - } - - yield return new Data - { - Value = dataSegment - }; - } - } - - /// - /// Translates the data body elements into the corresponding set of - /// instances. - /// - /// - /// The sequence body to translate. - /// - /// The set of instances that represents the in AMQP format. - /// - private static IEnumerable TranslateSequenceBody(IEnumerable> sequenceBody) - { - foreach (var item in sequenceBody) - { - yield return new AmqpSequence((IList)item); - } - } - - /// - /// Translates the data body into the corresponding set of - /// instance. - /// - /// - /// The sequence body to translate. - /// - /// The instance that represents the in AMQP format. - /// - private static AmqpValue TranslateValueBody(object valueBody) - { - if (TryCreateAmqpPropertyValueFromNetProperty(valueBody, out var amqpValue, allowBodyTypes: true)) - { - return new AmqpValue { Value = amqpValue }; - } - - throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, "{0} is not a supported value body type.", valueBody.GetType().Name)); - } - - /// - /// Attempts to read the data body of an . - /// - /// - /// The to read from. - /// The value of the data body, if read. - /// - /// true if the body was successfully read; otherwise, false. - /// - private static bool TryGetDataBody(AmqpMessage source, out AmqpMessageBody? dataBody) - { - if (((source.BodyType & SectionFlag.Data) == 0) || (source.DataBody == null)) - { - dataBody = null; - return false; - } - - dataBody = AmqpMessageBody.FromData(MessageBody.FromDataSegments(source.DataBody)); - return true; - } - - /// - /// Attempts to read the sequence body of an . - /// - /// - /// The to read from. - /// The value of the sequence body, if read. - /// - /// true if the body was successfully read; otherwise, false. - /// - private static bool TryGetSequenceBody(AmqpMessage source, out AmqpMessageBody? sequenceBody) - { - if ((source.BodyType & SectionFlag.AmqpSequence) == 0) - { - sequenceBody = null; - return false; - } - - var bodyContent = new List>(); - - foreach (var item in source.SequenceBody) - { - bodyContent.Add((IList)item.List); - } - - sequenceBody = AmqpMessageBody.FromSequence(bodyContent); - return true; - } - - /// - /// Attempts to read the sequence body of an . - /// - /// - /// The to read from. - /// The value body, if read. - /// - /// true if the body was successfully read; otherwise, false. - /// - private static bool TryGetValueBody(AmqpMessage source, out AmqpMessageBody? valueBody) - { - if (((source.BodyType & SectionFlag.AmqpValue) == 0) || (source.ValueBody?.Value == null)) - { - valueBody = null; - return false; - } - - if (TryCreateNetPropertyFromAmqpProperty(source.ValueBody.Value, out var translatedValue, allowBodyTypes: true)) - { - valueBody = AmqpMessageBody.FromValue(translatedValue!); - return true; - } - - throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, "{0} is not a supported value body type.", source.ValueBody.Value.GetType().Name)); - } - /// /// Attempts to create an AMQP property value for a given event property. /// @@ -750,6 +614,142 @@ public static bool TryCreateNetPropertyFromAmqpProperty( return (convertedPropertyValue != null); } + /// + /// Translates the data body segments into the corresponding set of + /// instances. + /// + /// + /// The data body to translate. + /// + /// The set of instances that represents the . + /// + private static IEnumerable TranslateDataBody(IEnumerable> dataBody) + { + foreach (var bodySegment in dataBody) + { + if (!MemoryMarshal.TryGetArray(bodySegment, out ArraySegment dataSegment)) + { + dataSegment = new ArraySegment(bodySegment.ToArray()); + } + + yield return new Data + { + Value = dataSegment + }; + } + } + + /// + /// Translates the data body elements into the corresponding set of + /// instances. + /// + /// + /// The sequence body to translate. + /// + /// The set of instances that represents the in AMQP format. + /// + private static IEnumerable TranslateSequenceBody(IEnumerable> sequenceBody) + { + foreach (var item in sequenceBody) + { + yield return new AmqpSequence((IList)item); + } + } + + /// + /// Translates the data body into the corresponding set of + /// instance. + /// + /// + /// The sequence body to translate. + /// + /// The instance that represents the in AMQP format. + /// + private static AmqpValue TranslateValueBody(object valueBody) + { + if (TryCreateAmqpPropertyValueFromNetProperty(valueBody, out var amqpValue, allowBodyTypes: true)) + { + return new AmqpValue { Value = amqpValue }; + } + + throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, "{0} is not a supported value body type.", valueBody.GetType().Name)); + } + + /// + /// Attempts to read the data body of an . + /// + /// + /// The to read from. + /// The value of the data body, if read. + /// + /// true if the body was successfully read; otherwise, false. + /// + private static bool TryGetDataBody(AmqpMessage source, out AmqpMessageBody? dataBody) + { + if (((source.BodyType & SectionFlag.Data) == 0) || (source.DataBody == null)) + { + dataBody = null; + return false; + } + + dataBody = AmqpMessageBody.FromData(MessageBody.FromDataSegments(source.DataBody)); + return true; + } + + /// + /// Attempts to read the sequence body of an . + /// + /// + /// The to read from. + /// The value of the sequence body, if read. + /// + /// true if the body was successfully read; otherwise, false. + /// + private static bool TryGetSequenceBody(AmqpMessage source, out AmqpMessageBody? sequenceBody) + { + if ((source.BodyType & SectionFlag.AmqpSequence) == 0) + { + sequenceBody = null; + return false; + } + + var bodyContent = new List>(); + + foreach (var item in source.SequenceBody) + { + bodyContent.Add((IList)item.List); + } + + sequenceBody = AmqpMessageBody.FromSequence(bodyContent); + return true; + } + + /// + /// Attempts to read the sequence body of an . + /// + /// + /// The to read from. + /// The value body, if read. + /// + /// true if the body was successfully read; otherwise, false. + /// + private static bool TryGetValueBody(AmqpMessage source, out AmqpMessageBody? valueBody) + { + if (((source.BodyType & SectionFlag.AmqpValue) == 0) || (source.ValueBody?.Value == null)) + { + valueBody = null; + return false; + } + + if (TryCreateNetPropertyFromAmqpProperty(source.ValueBody.Value, out var translatedValue, allowBodyTypes: true)) + { + valueBody = AmqpMessageBody.FromValue(translatedValue!); + return true; + } + + throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, "{0} is not a supported value body type.", source.ValueBody.Value.GetType().Name)); + } + private static void ThrowSerializationFailed(string propertyName, KeyValuePair pair) { throw new NotSupportedException( diff --git a/sdk/servicebus/Microsoft.Azure.WebJobs.Extensions.ServiceBus/tests/Grpc/ServiceBusGrpcSessionEndToEndTests.cs b/sdk/servicebus/Microsoft.Azure.WebJobs.Extensions.ServiceBus/tests/Grpc/ServiceBusGrpcSessionEndToEndTests.cs index e8acb12e4991..71476fdf6cb8 100644 --- a/sdk/servicebus/Microsoft.Azure.WebJobs.Extensions.ServiceBus/tests/Grpc/ServiceBusGrpcSessionEndToEndTests.cs +++ b/sdk/servicebus/Microsoft.Azure.WebJobs.Extensions.ServiceBus/tests/Grpc/ServiceBusGrpcSessionEndToEndTests.cs @@ -132,7 +132,11 @@ public async Task BindToSessionMessageAndAbandon() var receiver = await client.AcceptNextSessionAsync(FirstQueueScope.QueueName); var abandonedMessage = (await receiver.ReceiveMessagesAsync(1)).Single(); Assert.AreEqual("foobar", abandonedMessage.Body.ToString()); - Assert.AreEqual(TimeSpan.FromSeconds(60), abandonedMessage.ApplicationProperties["key"]); + Assert.AreEqual(TimeSpan.FromSeconds(60), abandonedMessage.ApplicationProperties["timespan"]); + Assert.AreEqual(ServiceBusBindToSessionMessageAndAbandon.Uri, abandonedMessage.ApplicationProperties["uri"]); + Assert.That(abandonedMessage.ApplicationProperties["datetime"], Is.EqualTo(ServiceBusBindToSessionMessageAndAbandon.DateTimeNow).Within(TimeSpan.FromMilliseconds(1))); + Assert.That(abandonedMessage.ApplicationProperties["datetimeoffset"], Is.EqualTo(ServiceBusBindToSessionMessageAndAbandon.DateTimeOffsetNow).Within(TimeSpan.FromMilliseconds(1))); + Assert.AreEqual(ServiceBusBindToSessionMessageAndAbandon.Guid, abandonedMessage.ApplicationProperties["guid"]); Assert.IsEmpty(provider.ActionsCache); } @@ -212,6 +216,11 @@ await SettlementService.Defer( public class ServiceBusBindToSessionMessageAndAbandon { + internal static DateTime DateTimeNow { get; } = DateTime.UtcNow; + internal static DateTimeOffset DateTimeOffsetNow { get; } = DateTimeOffset.UtcNow; + internal static Guid Guid { get; } = Guid.NewGuid(); + internal static Uri Uri { get; } = new Uri("http://nonExistingServiceBusWebsite.com"); + internal static SettlementService SettlementService { get; set; } public static async Task BindToMessage( [ServiceBusTrigger(FirstQueueNameKey, IsSessionsEnabled = true)] ServiceBusReceivedMessage message, ServiceBusReceiveActions receiveActions) @@ -221,7 +230,14 @@ await SettlementService.Abandon( new AbandonRequest { Locktoken = message.LockToken, - PropertiesToModify = EncodeDictionary(new Dictionary {{ "key", TimeSpan.FromSeconds(60)}}) + PropertiesToModify = EncodeDictionary(new Dictionary + { + { "timespan", TimeSpan.FromSeconds(60) }, + { "uri", Uri }, + { "datetime", DateTimeNow }, + { "datetimeoffset", DateTimeOffsetNow }, + { "guid", Guid }, + }) }, new MockServerCallContext()); _waitHandle1.Set(); From 26e48a4a3cc13c9f38121a8074f2362a4b4fa115 Mon Sep 17 00:00:00 2001 From: JoshLove-msft <54595583+JoshLove-msft@users.noreply.github.com> Date: Tue, 17 Oct 2023 09:42:04 -0700 Subject: [PATCH 4/5] Fix test and revert testbase change --- .../tests/Grpc/ServiceBusGrpcSessionEndToEndTests.cs | 5 +++-- .../tests/WebJobsServiceBusTestBase.cs | 6 ++++++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/sdk/servicebus/Microsoft.Azure.WebJobs.Extensions.ServiceBus/tests/Grpc/ServiceBusGrpcSessionEndToEndTests.cs b/sdk/servicebus/Microsoft.Azure.WebJobs.Extensions.ServiceBus/tests/Grpc/ServiceBusGrpcSessionEndToEndTests.cs index 71476fdf6cb8..3008f74fee79 100644 --- a/sdk/servicebus/Microsoft.Azure.WebJobs.Extensions.ServiceBus/tests/Grpc/ServiceBusGrpcSessionEndToEndTests.cs +++ b/sdk/servicebus/Microsoft.Azure.WebJobs.Extensions.ServiceBus/tests/Grpc/ServiceBusGrpcSessionEndToEndTests.cs @@ -132,7 +132,7 @@ public async Task BindToSessionMessageAndAbandon() var receiver = await client.AcceptNextSessionAsync(FirstQueueScope.QueueName); var abandonedMessage = (await receiver.ReceiveMessagesAsync(1)).Single(); Assert.AreEqual("foobar", abandonedMessage.Body.ToString()); - Assert.AreEqual(TimeSpan.FromSeconds(60), abandonedMessage.ApplicationProperties["timespan"]); + Assert.AreEqual(ServiceBusBindToSessionMessageAndAbandon.TimeSpan, abandonedMessage.ApplicationProperties["timespan"]); Assert.AreEqual(ServiceBusBindToSessionMessageAndAbandon.Uri, abandonedMessage.ApplicationProperties["uri"]); Assert.That(abandonedMessage.ApplicationProperties["datetime"], Is.EqualTo(ServiceBusBindToSessionMessageAndAbandon.DateTimeNow).Within(TimeSpan.FromMilliseconds(1))); Assert.That(abandonedMessage.ApplicationProperties["datetimeoffset"], Is.EqualTo(ServiceBusBindToSessionMessageAndAbandon.DateTimeOffsetNow).Within(TimeSpan.FromMilliseconds(1))); @@ -220,6 +220,7 @@ public class ServiceBusBindToSessionMessageAndAbandon internal static DateTimeOffset DateTimeOffsetNow { get; } = DateTimeOffset.UtcNow; internal static Guid Guid { get; } = Guid.NewGuid(); internal static Uri Uri { get; } = new Uri("http://nonExistingServiceBusWebsite.com"); + internal static TimeSpan TimeSpan { get; } = TimeSpan.FromSeconds(60); internal static SettlementService SettlementService { get; set; } public static async Task BindToMessage( @@ -232,7 +233,7 @@ await SettlementService.Abandon( Locktoken = message.LockToken, PropertiesToModify = EncodeDictionary(new Dictionary { - { "timespan", TimeSpan.FromSeconds(60) }, + { "timespan", TimeSpan }, { "uri", Uri }, { "datetime", DateTimeNow }, { "datetimeoffset", DateTimeOffsetNow }, diff --git a/sdk/servicebus/Microsoft.Azure.WebJobs.Extensions.ServiceBus/tests/WebJobsServiceBusTestBase.cs b/sdk/servicebus/Microsoft.Azure.WebJobs.Extensions.ServiceBus/tests/WebJobsServiceBusTestBase.cs index 9d5775e618fa..5353e6ef5cd1 100644 --- a/sdk/servicebus/Microsoft.Azure.WebJobs.Extensions.ServiceBus/tests/WebJobsServiceBusTestBase.cs +++ b/sdk/servicebus/Microsoft.Azure.WebJobs.Extensions.ServiceBus/tests/WebJobsServiceBusTestBase.cs @@ -336,6 +336,12 @@ public async Task StopAsync(CancellationToken cancellationToken) QueueRuntimeProperties properties = await client.GetQueueRuntimePropertiesAsync(FirstQueueScope.QueueName, CancellationToken.None); Assert.AreEqual(ExpectedRemainingMessages, properties.ActiveMessageCount); + + var provider = _host.Services.GetService(); + Assert.AreEqual(0, provider.ClientCache.Count); + Assert.AreEqual(0, provider.MessageReceiverCache.Count); + Assert.AreEqual(0, provider.MessageSenderCache.Count); + Assert.AreEqual(0, provider.ActionsCache.Count); } private static bool IsError(LogMessage logMessage) From 355353d224fae94b1c73feca2f4de923e5ad6e19 Mon Sep 17 00:00:00 2001 From: JoshLove-msft <54595583+JoshLove-msft@users.noreply.github.com> Date: Tue, 17 Oct 2023 10:56:34 -0700 Subject: [PATCH 5/5] remove unused import --- .../src/Grpc/Proto/settlement.proto | 1 - 1 file changed, 1 deletion(-) diff --git a/sdk/servicebus/Microsoft.Azure.WebJobs.Extensions.ServiceBus/src/Grpc/Proto/settlement.proto b/sdk/servicebus/Microsoft.Azure.WebJobs.Extensions.ServiceBus/src/Grpc/Proto/settlement.proto index fdca72531b00..9360a0d3ed7b 100644 --- a/sdk/servicebus/Microsoft.Azure.WebJobs.Extensions.ServiceBus/src/Grpc/Proto/settlement.proto +++ b/sdk/servicebus/Microsoft.Azure.WebJobs.Extensions.ServiceBus/src/Grpc/Proto/settlement.proto @@ -1,6 +1,5 @@ syntax = "proto3"; -import "google/protobuf/timestamp.proto"; import "google/protobuf/empty.proto"; // this namespace will be shared between isolated worker and WebJobs extension so make it somewhat generic