public async Task Should_not_leak_state_when_request_canceled() { var dictionary = new ConcurrentDictionary <string, RequestResponseStateLookup.State>(); var requestResponseStateLookup = new RequestResponseStateLookup(dictionary); var tcs = new TaskCompletionSource <object>(); var adapter = new TaskCompletionSourceAdapter <object>(tcs); var tokenSource = new CancellationTokenSource(); var outgoingPhysicalMessageContext = new TestableOutgoingPhysicalMessageContext(); outgoingPhysicalMessageContext.Extensions.Set(new RequestResponseStateLookup.State { CancellationToken = tokenSource.Token, TaskCompletionSource = adapter }); var behavior = new UpdateRequestResponseCorrelationTableBehavior(requestResponseStateLookup); await behavior.Invoke(outgoingPhysicalMessageContext, () => { tokenSource.Cancel(); return(Task.FromResult(0)); }); Assert.ThrowsAsync <TaskCanceledException>(async() => { await tcs.Task; }); Assert.IsEmpty(dictionary); }
public static RequestResponseStateLookup.State? TryRemoveResponseStateBasedOnCorrelationId(this IIncomingContext context, IncomingMessage message, RequestResponseStateLookup lookup) { var correlationId = context.GetCorrelationId(); if (correlationId == null) { return null; } string version; var checkMessageIntent = true; if (message.Headers.TryGetValue(Headers.NServiceBusVersion, out version)) { Version parsedVersion; if (Version.TryParse(version, out parsedVersion)) { if (parsedVersion < minimumVersionThatSupportMessageIntent_Reply) { checkMessageIntent = false; } } } var messageIntentEnum = message.GetMesssageIntent(); if (checkMessageIntent && messageIntentEnum != MessageIntentEnum.Reply) { return null; } RequestResponseStateLookup.State state; return lookup.TryRemove(correlationId, out state) ? (RequestResponseStateLookup.State?) state : null; }
public async Task Should_not_leak_state_when_request_canceled() { var dictionary = new ConcurrentDictionary<string, RequestResponseStateLookup.State>(); var requestResponseStateLookup = new RequestResponseStateLookup(dictionary); var tcs = new TaskCompletionSource<object>(); var adapter = new TaskCompletionSourceAdapter(tcs); var tokenSource = new CancellationTokenSource(); var outgoingPhysicalMessageContext = new TestableOutgoingPhysicalMessageContext(); outgoingPhysicalMessageContext.Extensions.Set(new RequestResponseStateLookup.State { CancellationToken = tokenSource.Token, TaskCompletionSource = adapter }); var behavior = new UpdateRequestResponseCorrelationTableBehavior(requestResponseStateLookup); await behavior.Invoke(outgoingPhysicalMessageContext, () => { tokenSource.Cancel(); return Task.FromResult(0); }); Assert.ThrowsAsync<TaskCanceledException>(async () => { await tcs.Task; }); Assert.IsEmpty(dictionary); }
public void Below_v4_3_0_should_return_value_for_all_intents(string nsbVersion, MessageIntentEnum intent) { var correlationId = new Guid().ToString(); var lookup = new RequestResponseStateLookup(); lookup.RegisterState(correlationId, new RequestResponseStateLookup.State()); var message = new IncomingMessageFromLegacyEndpoint(nsbVersion, intent); var incomingContext = new TestableIncomingLogicalMessageContext(); incomingContext.MessageHeaders.Add(Headers.CorrelationId, correlationId); var result = incomingContext.TryRemoveResponseStateBasedOnCorrelationId(message, lookup); Assert.IsTrue(result.HasValue); }
protected override void Setup(FeatureConfigurationContext context) { if (!context.Settings.HasSetting("EndpointInstanceDiscriminator")) { throw new Exception("In order to use the callbacks feature you need to specify an endpoint instance ID via EndpointConfiguration.MakeInstanceUniquelyAddressable(string discriminator)"); } var lookup = new RequestResponseStateLookup(); context.Pipeline.Register("RequestResponseInvocationForControlMessagesBehavior", new RequestResponseInvocationForControlMessagesBehavior(lookup), "Invokes the callback of a synchronous request/response for control messages"); context.Pipeline.Register("RequestResponseInvocationForMessagesBehavior", new RequestResponseInvocationForMessagesBehavior(lookup), "Invokes the callback of a synchronous request/response"); context.Pipeline.Register(new UpdateRequestResponseCorrelationTableBehavior.Registration(lookup)); }
protected override void Setup(FeatureConfigurationContext context) { if (!context.Settings.HasSetting("EndpointInstanceDiscriminator")) { throw new Exception("In order to use the callbacks feature you need to specify an endpoint instance ID via EndpointConfiguration.MakeInstanceUniquelyAddressable(string discriminator)"); } var lookup = new RequestResponseStateLookup(); context.Pipeline.Register("RequestResponseInvocationForControlMessagesBehavior", new RequestResponseInvocationForControlMessagesBehavior(lookup), "Invokes the callback of a synchronous request/response for control messages"); context.Pipeline.Register("RequestResponseInvocationForMessagesBehavior", new RequestResponseInvocationForMessagesBehavior(lookup), "Invokes the callback of a synchronous request/response"); context.Pipeline.Register(new UpdateRequestResponseCorrelationTableBehavior.Registration(lookup)); context.Pipeline.Register("SetCallbackResponseReturnCodeBehavior", new SetCallbackResponseReturnCodeBehavior(), "Promotes the callback response return code to a header in order to be backwards compatible with v5 and below"); context.Pipeline.Register<SkipBestPracticesForReplyIntEnumBehavior.Registration>(); }
public void Below_v5_0_0_should_return_value_for_all_intents(string nsbVersion, MessageIntentEnum intent) { var correlationId = new Guid().ToString(); var lookup = new RequestResponseStateLookup(); lookup.RegisterState(correlationId, new RequestResponseStateLookup.State()); var message = new IncomingMessageFromLegacyEndpoint(nsbVersion, intent); var incomingContext = new TestableIncomingLogicalMessageContext(); incomingContext.MessageHeaders.Add(Headers.CorrelationId, correlationId); var result = incomingContext.TryRemoveResponseStateBasedOnCorrelationId(message, lookup); Assert.IsTrue(result.HasValue); }