protected async Task StartPump(Func <MessageContext, Task> onMessage, Func <ErrorContext, Task <ErrorHandleResult> > onError, TransportTransactionMode transactionMode, Action <string, Exception> onCriticalError = null) { InputQueueName = GetTestName() + transactionMode; ErrorQueueName = $"{InputQueueName}.error"; transportSettings.Set("NServiceBus.Routing.EndpointName", InputQueueName); var queueBindings = new QueueBindings(); queueBindings.BindReceiving(InputQueueName); queueBindings.BindSending(ErrorQueueName); transportSettings.Set(ErrorQueueSettings.SettingsKey, ErrorQueueName); transportSettings.Set <QueueBindings>(queueBindings); transportSettings.Set <EndpointInstances>(new EndpointInstances()); Configurer = CreateConfigurer(); var configuration = Configurer.Configure(transportSettings, transactionMode); TransportInfrastructure = configuration.TransportInfrastructure; IgnoreUnsupportedTransactionModes(transactionMode); IgnoreUnsupportedDeliveryConstraints(); ReceiveInfrastructure = TransportInfrastructure.ConfigureReceiveInfrastructure(); SendInfrastructure = TransportInfrastructure.ConfigureSendInfrastructure(); lazyDispatcher = new Lazy <IDispatchMessages>(() => SendInfrastructure.DispatcherFactory()); MessagePump = ReceiveInfrastructure.MessagePumpFactory(); var queueCreator = ReceiveInfrastructure.QueueCreatorFactory(); await queueCreator.CreateQueueIfNecessary(queueBindings, WindowsIdentity.GetCurrent().Name); var pushSettings = new PushSettings(InputQueueName, ErrorQueueName, configuration.PurgeInputQueueOnStartup, transactionMode); await MessagePump.Init( context => { if (context.Headers.ContainsKey(TestIdHeaderName) && context.Headers[TestIdHeaderName] == testId) { return(onMessage(context)); } return(Task.FromResult(0)); }, context => { if (context.Message.Headers.ContainsKey(TestIdHeaderName) && context.Message.Headers[TestIdHeaderName] == testId) { return(onError(context)); } return(Task.FromResult(ErrorHandleResult.Handled)); }, new FakeCriticalError(onCriticalError), pushSettings); MessagePump.Start(configuration.PushRuntimeSettings); }
public async Task Should_stop_pumping_messages_after_first_unsuccessful_receive() { var successfulReceives = 46; var queueSize = 1000; var parser = new QueueAddressTranslator("nservicebus", "dbo", null, null); var inputQueue = new FakeTableBasedQueue(parser.Parse("input").QualifiedTableName, queueSize, successfulReceives); var pump = new MessagePump( m => new ProcessWithNoTransaction(sqlConnectionFactory), qa => qa == "input" ? (TableBasedQueue)inputQueue : new TableBasedQueue(parser.Parse(qa).QualifiedTableName, qa), new QueuePurger(sqlConnectionFactory), new ExpiredMessagesPurger(_ => sqlConnectionFactory.OpenNewConnection(), TimeSpan.MaxValue, 0), new QueuePeeker(sqlConnectionFactory, new QueuePeekerOptions()), new SchemaInspector(_ => sqlConnectionFactory.OpenNewConnection()), TimeSpan.MaxValue); await pump.Init( _ => Task.FromResult(0), _ => Task.FromResult(ErrorHandleResult.Handled), new CriticalError(_ => Task.FromResult(0)), new PushSettings("input", "error", false, TransportTransactionMode.None)); pump.Start(new PushRuntimeSettings(1)); await WaitUntil(() => inputQueue.NumberOfPeeks > 1); await pump.Stop(); Assert.That(inputQueue.NumberOfReceives, Is.AtMost(successfulReceives + 2), "Pump should stop receives after first unsuccessful attempt."); }
public async Task Pushes_received_message_into_pipeline() { var cts = new CancellationTokenSource(TimeSpan.FromSeconds(60)); await TestUtility.Delete("sales"); var settings = new SettingsHolder(); settings.Set("NServiceBus.SharedQueue", "sales"); new DefaultConfigurationValues().Apply(settings); // setting up the environment var container = new TransportPartsContainer(); var topology = await SetupEndpointOrientedTopology(container, "sales"); // setup the operator var pump = new MessagePump(topology, container, settings); var completed = new AsyncManualResetEvent(false); //var error = new AsyncManualResetEvent(false); var received = false; Exception ex = null; // Dummy CriticalError var criticalError = new CriticalError(ctx => TaskEx.Completed); await pump.Init(context => { received = true; completed.Set(); return(TaskEx.Completed); }, null, criticalError, new PushSettings("sales", "error", false, TransportTransactionMode.ReceiveOnly)); // execute pump.Start(new PushRuntimeSettings(1)); // send message to queue var senderFactory = (MessageSenderCreator)container.Resolve(typeof(MessageSenderCreator)); var sender = await senderFactory.Create("sales", null, "namespaceName"); await sender.Send(new BrokeredMessage()); await completed.WaitAsync(cts.Token).IgnoreCancellation(); // Task.WhenAny(completed.WaitOne(), error.WaitOne()); // validate Assert.IsTrue(received); Assert.IsNull(ex); // cleanup await pump.Stop(); }
public void ShouldThrowIfConfiguredToReceiveFromRemoteQueue() { var messagePump = new MessagePump(mode => null); var pushSettings = new PushSettings("queue@remote", "error", false, TransportTransactionMode.None); var exception = Assert.Throws <Exception>(() => { messagePump.Init(context => null, context => null, null, pushSettings); }); Assert.That(exception.Message, Does.Contain($"MSMQ Dequeuing can only run against the local machine. Invalid inputQueue name '{pushSettings.InputQueue}'.")); }
public void ShouldThrowIfConfiguredToReceiveFromRemoteQueue() { var messagePump = new MessagePump(mode => null); var pushSettings = new PushSettings("queue@remote", "error", false, TransportTransactionMode.None); var exception = Assert.Throws<Exception>(() => { messagePump.Init(context => null, context => null, null, pushSettings); }); Assert.That(exception.Message, Does.Contain($"MSMQ Dequeuing can only run against the local machine. Invalid inputQueue name '{pushSettings.InputQueue}'.")); }
public void Should_throw() { var settings = SettingsHolderFactory.BuildWithSerializer(); settings.Set("NServiceBus.SharedQueue", "sales"); DefaultConfigurationValues.Apply(settings); var pump = new MessagePump(null, null, null, null, settings, "sales"); var criticalError = new CriticalError(ctx => TaskEx.Completed); const bool purgeOnStartup = true; Assert.ThrowsAsync <InvalidOperationException>(async() => await pump.Init(context => TaskEx.Completed, null, criticalError, new PushSettings("sales", "error", purgeOnStartup, TransportTransactionMode.SendsAtomicWithReceive))); }
public async Task Should_trigger_circuit_breaker() { var cts = new CancellationTokenSource(TimeSpan.FromSeconds(60)); var container = new TransportPartsContainer(); var fakeTopologyOperator = new FakeTopologyOperator(); container.Register <IOperateTopology>(() => fakeTopologyOperator); var settings = new SettingsHolder(); settings.Set("NServiceBus.SharedQueue", "sales"); new DefaultConfigurationValues().Apply(settings); container.Register <ReadOnlySettings>(() => settings); Exception exceptionReceivedByCircuitBreaker = null; var criticalErrorWasRaised = false; var tcs = new TaskCompletionSource <object>(); cts.Token.Register(() => tcs.TrySetCanceled()); // setup critical error action to capture exception thrown by message pump var criticalError = new FakeCriticalError(ctx => { criticalErrorWasRaised = true; exceptionReceivedByCircuitBreaker = ctx.Exception; tcs.TrySetResult(null); return(TaskEx.Completed); }); var pump = new MessagePump(new FakeTopology(), container, settings, TimeSpan.FromSeconds(1)); await pump.Init(context => TaskEx.Completed, null, criticalError, new PushSettings("sales", "error", false, TransportTransactionMode.ReceiveOnly)); pump.Start(new PushRuntimeSettings(1)); await fakeTopologyOperator.onIncomingMessage(new IncomingMessageDetails("id", new Dictionary <string, string>(), new byte[0]), new FakeReceiveContext()); var exceptionThrownByMessagePump = new Exception("kaboom"); await fakeTopologyOperator.onError(exceptionThrownByMessagePump); await tcs.Task; // let circuit breaker kick in // validate Assert.IsTrue(criticalErrorWasRaised, "Expected critical error to be raised, but it wasn't"); Assert.AreEqual(exceptionThrownByMessagePump, exceptionReceivedByCircuitBreaker, "Exception circuit breaker got should be the same as the one raised by message pump"); }
public void SetUp() { routingTopology = new ConventionalRoutingTopology(true); receivedMessages = new BlockingCollection <IncomingMessage>(); var settings = new SettingsHolder(); settings.Set("NServiceBus.Routing.EndpointName", "endpoint"); var connectionString = Environment.GetEnvironmentVariable("RabbitMQTransport.ConnectionString"); ConnectionConfiguration config; if (connectionString != null) { var parser = new ConnectionStringParser(settings); config = parser.Parse(connectionString); } else { config = new ConnectionConfiguration(settings); config.Host = "localhost"; } connectionFactory = new ConnectionFactory(config); channelProvider = new ChannelProvider(connectionFactory, routingTopology, true); messageDispatcher = new MessageDispatcher(channelProvider); var purger = new QueuePurger(connectionFactory); messagePump = new MessagePump(connectionFactory, new MessageConverter(), "Unit test", channelProvider, purger, TimeSpan.FromMinutes(2), 3, 0); MakeSureQueueAndExchangeExists(ReceiverQueue); subscriptionManager = new SubscriptionManager(connectionFactory, routingTopology, ReceiverQueue); messagePump.Init(messageContext => { receivedMessages.Add(new IncomingMessage(messageContext.MessageId, messageContext.Headers, messageContext.Body)); return(TaskEx.CompletedTask); }, ErrorContext => Task.FromResult(ErrorHandleResult.Handled), new CriticalError(_ => TaskEx.CompletedTask), new PushSettings(ReceiverQueue, "error", true, TransportTransactionMode.ReceiveOnly) ).GetAwaiter().GetResult(); messagePump.Start(new PushRuntimeSettings(MaximumConcurrency)); }
public void Should_throw() { var container = new TransportPartsContainer(); container.Register <TopologyOperator>(); var settings = new SettingsHolder(); settings.Set("NServiceBus.SharedQueue", "sales"); new DefaultConfigurationValues().Apply(settings); container.Register <ReadOnlySettings>(() => settings); var pump = new MessagePump(null, container, settings); var criticalError = new CriticalError(ctx => TaskEx.Completed); const bool purgeOnStartup = true; Assert.ThrowsAsync <InvalidOperationException> (async() => await pump.Init(context => TaskEx.Completed, null, criticalError, new PushSettings("sales", "error", purgeOnStartup, TransportTransactionMode.SendsAtomicWithReceive))); }
public async Task Should_stop_pumping_messages_after_first_unsuccessful_receive() { var successfulReceives = 46; var queueSize = 1000; var parser = new QueueAddressTranslator("nservicebus", "dbo", null, null); var inputQueue = new FakeTableBasedQueue(parser.Parse("input").QualifiedTableName, queueSize, successfulReceives); var connectionString = Environment.GetEnvironmentVariable("SqlServerTransportConnectionString"); if (string.IsNullOrEmpty(connectionString)) { connectionString = @"Data Source=.\SQLEXPRESS;Initial Catalog=nservicebus;Integrated Security=True"; } var sqlConnectionFactory = SqlConnectionFactory.Default(connectionString); var pump = new MessagePump( m => new ProcessWithNoTransaction(sqlConnectionFactory, null), qa => qa == "input" ? (TableBasedQueue)inputQueue : new TableBasedQueue(parser.Parse(qa).QualifiedTableName, qa, true), new QueuePurger(sqlConnectionFactory), new NoOpExpiredMessagesPurger(), new QueuePeeker(sqlConnectionFactory, new QueuePeekerOptions()), new QueuePeekerOptions(), new SchemaInspector(_ => sqlConnectionFactory.OpenNewConnection(), false), TimeSpan.MaxValue); await pump.Init( _ => Task.FromResult(0), _ => Task.FromResult(ErrorHandleResult.Handled), new CriticalError(_ => Task.FromResult(0)), new PushSettings("input", "error", false, TransportTransactionMode.None)); pump.Start(new PushRuntimeSettings(1)); await WaitUntil(() => inputQueue.NumberOfPeeks > 1); await pump.Stop(); Assert.That(inputQueue.NumberOfReceives, Is.AtMost(successfulReceives + 2), "Pump should stop receives after first unsuccessful attempt."); }
public void SetUp() { routingTopology = new ConventionalRoutingTopology(true); receivedMessages = new BlockingCollection <IncomingMessage>(); var connectionString = Environment.GetEnvironmentVariable("RabbitMQTransport_ConnectionString"); if (string.IsNullOrEmpty(connectionString)) { throw new Exception("The 'RabbitMQTransport_ConnectionString' environment variable is not set."); } var config = ConnectionConfiguration.Create(connectionString, ReceiverQueue); connectionFactory = new ConnectionFactory(ReceiverQueue, config, null, false, false); channelProvider = new ChannelProvider(connectionFactory, config.RetryDelay, routingTopology, true); channelProvider.CreateConnection(); messageDispatcher = new MessageDispatcher(channelProvider); var purger = new QueuePurger(connectionFactory); messagePump = new MessagePump(connectionFactory, new MessageConverter(), "Unit test", channelProvider, purger, TimeSpan.FromMinutes(2), 3, 0); routingTopology.Reset(connectionFactory, new[] { ReceiverQueue }.Concat(AdditionalReceiverQueues), new[] { ErrorQueue }); subscriptionManager = new SubscriptionManager(connectionFactory, routingTopology, ReceiverQueue); messagePump.Init(messageContext => { receivedMessages.Add(new IncomingMessage(messageContext.MessageId, messageContext.Headers, messageContext.Body)); return(TaskEx.CompletedTask); }, ErrorContext => Task.FromResult(ErrorHandleResult.Handled), new CriticalError(_ => TaskEx.CompletedTask), new PushSettings(ReceiverQueue, ErrorQueue, true, TransportTransactionMode.ReceiveOnly) ).GetAwaiter().GetResult(); messagePump.Start(new PushRuntimeSettings(MaximumConcurrency)); }
public void SetUp(params Type[] typesToSubscribeTo) { receivedMessages = new BlockingCollection <IncomingMessage>(); Environment.SetEnvironmentVariable("KafkaTransport.ConnectionString", "127.0.0.1:9092"); var connectionString = Environment.GetEnvironmentVariable("KafkaTransport.ConnectionString");//"127.0.0.1:9092" SettingsHolder settingsHolder = new SettingsHolder(); settingsHolder.Set("NServiceBus.Routing.EndpointName", endpointName); var kafkaTransport = new KafkaTransport(); var infra = kafkaTransport.Initialize(settingsHolder, connectionString); messageDispatcher = new MessageDispatcher(new Transports.Kafka.Connection.ProducerFactory(connectionString)); messagePump = new MessagePump(settingsHolder, connectionString); subscriptionManager = new SubscriptionManager(messagePump, null); foreach (var t in typesToSubscribeTo) { subscriptionManager.Subscribe(t, new ContextBag()); } messagePump.Init(messageContext => { receivedMessages.Add(new IncomingMessage(messageContext.MessageId, messageContext.Headers, messageContext.Body)); return(Task.FromResult(0)); }, ErrorContext => Task.FromResult(ErrorHandleResult.Handled), new CriticalError(_ => Task.FromResult(0)), new PushSettings(endpointName, ErrorQueue, true, TransportTransactionMode.ReceiveOnly) ).GetAwaiter().GetResult(); messagePump.Start(new PushRuntimeSettings(MaximumConcurrency)); }
protected async Task StartPump(Func <MessageContext, Task> onMessage, Func <ErrorContext, Task <ErrorHandleResult> > onError, TransportTransactionMode transactionMode, Action <string, Exception> onCriticalError = null) { InputQueueName = GetTestName() + transactionMode; ErrorQueueName = $"{InputQueueName}.error"; var endpointConfiguration = new EndpointConfiguration(InputQueueName); endpointConfiguration.SendFailedMessagesTo(ErrorQueueName); transportSettings = endpointConfiguration.GetSettings(); var queueBindings = transportSettings.Get <QueueBindings>(); queueBindings.BindReceiving(InputQueueName); queueBindings.BindSending(ErrorQueueName); Configurer = CreateConfigurer(); var configuration = Configurer.Configure(transportSettings, transactionMode); TransportInfrastructure = configuration.TransportInfrastructure; IgnoreUnsupportedTransactionModes(transactionMode); IgnoreUnsupportedDeliveryConstraints(); ReceiveInfrastructure = TransportInfrastructure.ConfigureReceiveInfrastructure(); var queueCreator = ReceiveInfrastructure.QueueCreatorFactory(); var userName = GetUserName(); await queueCreator.CreateQueueIfNecessary(queueBindings, userName); var result = await ReceiveInfrastructure.PreStartupCheck(); if (result.Succeeded == false) { throw new Exception($"Pre start-up check failed: {result.ErrorMessage}"); } await TransportInfrastructure.Start(); SendInfrastructure = TransportInfrastructure.ConfigureSendInfrastructure(); lazyDispatcher = new Lazy <IDispatchMessages>(() => SendInfrastructure.DispatcherFactory()); MessagePump = ReceiveInfrastructure.MessagePumpFactory(); await MessagePump.Init( context => { if (context.Headers.ContainsKey(TestIdHeaderName) && context.Headers[TestIdHeaderName] == testId) { return(onMessage(context)); } return(Task.FromResult(0)); }, context => { if (context.Message.Headers.ContainsKey(TestIdHeaderName) && context.Message.Headers[TestIdHeaderName] == testId) { return(onError(context)); } return(Task.FromResult(ErrorHandleResult.Handled)); }, new FakeCriticalError(onCriticalError), new PushSettings(InputQueueName, ErrorQueueName, configuration.PurgeInputQueueOnStartup, transactionMode)); result = await SendInfrastructure.PreStartupCheck(); if (result.Succeeded == false) { throw new Exception($"Pre start-up check failed: {result.ErrorMessage}"); } MessagePump.Start(configuration.PushRuntimeSettings); }