public async Task Subscriber_ProcessTheMessageTheSecondTime_MessageMustBeRemovedFromTheRabbitMq() { //prepare IConfiguration configuration = ConfigurationHelper.ProvideConfiguration(); var exchangeName = "Subscriber_ProcessTheMessageTheSecondTime_MessageMustBeRemovedFromTheRabbitMq.exchangename"; configuration["rabbitmq:exchangename"] = exchangeName; configuration["rabbitmq:waitexchangename"] = exchangeName.Replace("exchangename", "waitexchangename"); configuration["rabbitmq:retryfactor"] = 100.ToString(); var maxretrycount = 2; IContainer container = ConfigurationHelper.ConfigureContainer(configuration); //create Subscriber var bookingCreatedSubscriberFactory = container.Resolve <ISubscriberFactory>(); ISubscriber typedSubscriber = await bookingCreatedSubscriberFactory .CreateSubscriberAsync("Subscriber_ProcessTheMessageTheSecondTime_MessageMustBeRemovedFromTheRabbitMq" + ".typedbookingcreatedconsumer", new List <string> { "*.entity.create.booking" }, maxretrycount); BookingTypedConsumer typedConsumer = new BookingTypedConsumer(1); typedSubscriber.Subscribe(SubscriptionBuilder.Create().AddDefaultSubscription(() => typedConsumer).Build()); //create Publisher var publisher = container.Resolve <IPublisher>(); string routingKey = "changetracker.entity.create.booking"; //act BookingCreated bookingCreated = new BookingCreated() { BookingName = string.Concat("Microsoft Sale", Guid.NewGuid().ToString()) }; var bookingCreatedIntegrationEvent = new IntegrationEvent <BookingCreated>() { Content = bookingCreated, EventType = "bookingcreated" }; await publisher.PublishEventAsync(bookingCreatedIntegrationEvent, routingKey); await Task.Delay(500); //check typedConsumer.ProcessedIntegrationEvent.ShouldBeEquivalentTo(bookingCreatedIntegrationEvent); typedConsumer.CountOfAttempts.Should().Be(2); container.Dispose(); }
public async Task Publisher_PublishDirectEventAsync_MessageMustBeSerializedAndCorrectlyRoutedToSpecificSubscriber() { //prepare IConfiguration configuration = ConfigurationHelper.ProvideConfiguration(); var exchangeName = "Publisher_PublishDirectEventAsync_MessageMustBeSerializedAndCorrectlyRoutedToSpecificSubscriber.exchangename"; configuration["rabbitmq:exchangename"] = exchangeName; configuration["rabbitmq:waitexchangename"] = exchangeName.Replace("exchangename", "waitexchangename"); var maxretrycount = 2; IContainer container = ConfigurationHelper.ConfigureContainer(configuration); //create Subscriber var bookingCreatedSubscriberFactory = container.Resolve <ISubscriberFactory>(); string subscriberName = "Publisher_PublishDirectEventAsync_MessageMustBeSerializedAndCorrectlyRoutedToSpecificSubscriber.typedbookingcreatedconsumer"; ISubscriber typedSubscriber = await bookingCreatedSubscriberFactory .CreateSubscriberAsync(subscriberName, (List <string>) null, maxretrycount); BookingTypedConsumer typedConsumer = new BookingTypedConsumer(0); typedSubscriber.Subscribe(SubscriptionBuilder.Create().AddDefaultSubscription(() => typedConsumer).Build()); //create Publisher var publisher = container.Resolve <IPublisher>(); //act BookingCreated bookingCreated = new BookingCreated() { BookingName = string.Concat("Microsoft Sale", Guid.NewGuid().ToString()) }; var bookingCreatedIntegrationEvent = new IntegrationEvent <BookingCreated>() { Content = bookingCreated, EventType = "bookingcreated" }; await publisher.PublishDirectEventAsync(bookingCreatedIntegrationEvent, subscriberName); await Task.Delay(200); //check typedConsumer.ProcessedIntegrationEvent.ShouldBeEquivalentTo(bookingCreatedIntegrationEvent); typedConsumer.CountOfAttempts.Should().Be(1); container.Dispose(); }
public async Task Publisher_Publish_MessageMustBeSerializedAndCorrectlyRouted() { //prepare IConfiguration configuration = ConfigurationHelper.ProvideConfiguration(); var exchangeName = "Publisher_Publish_MessageMustBeSerializedAndCorrectlyRouted.exchangename"; configuration["rabbitmq:exchangename"] = exchangeName; IContainer container = ConfigurationHelper.ConfigureContainer(configuration); var publisher = container.Resolve <IPublisher>(); string routingKey = "changetracker.entity.create.booking"; var bus = container.Resolve <IAdvancedBus>(); IExchange exchange = bus.ExchangeDeclare(exchangeName, ExchangeType.Topic); var queue = bus.QueueDeclare("Publisher_Publish_MessageMustBeSentAndCorrectlyRouted.subscriberqueue"); var binding = bus.Bind(exchange, queue, "changetracker.entity.create.booking"); //act BookingCreated bookingCreated = new BookingCreated() { BookingName = string.Concat("Microsoft Sale", Guid.NewGuid().ToString()) }; var bookingCreatedIntegrationEvent = new IntegrationEvent <BookingCreated>() { Content = bookingCreated, EventType = "bookingcreated" }; await publisher.PublishEventAsync(bookingCreatedIntegrationEvent, routingKey); await Task.Delay(300); //check IBasicGetResult result = bus.Get(queue); var message = Encoding.UTF8.GetString(result.Body); IntegrationEvent <BookingCreated> eventToCheck = JsonConvert.DeserializeObject <IntegrationEvent <BookingCreated> >(message); eventToCheck.ShouldBeEquivalentTo(bookingCreatedIntegrationEvent); container.Dispose(); }
public async Task Subscriber_NetworkDisconnected_CallbackExecuted() { //prepare IConfiguration configuration = InitializeConfiguration(); const int subscriberNum = 5; var disconnectedEventFired = new bool[subscriberNum]; const int maxRetryCount = 1; const int maxPrefetchCount = 1; using (IContainer container = ConfigurationHelper.ConfigureContainer(configuration)) { //create Subscriber var testEntitySubscriberFactory = container.Resolve <ISubscriberFactory>(); for (int i = 0; i < subscriberNum; i++) { var index = i; ISubscriber subscriber = await testEntitySubscriberFactory .CreateSubscriberAsync($"Publiser_TemporaryQueue.testSubscriber_{Guid.NewGuid()}", () => { disconnectedEventFired[index] = true; }, new List <string> { "*.entity.create.testEntity", }, maxRetryCount, maxPrefetchCount); // create Subscriber subscriber.Subscribe(SubscriptionBuilder.Create() .AddSubscription("testEntityCreated", () => (IConsumer <string>)null) .Build()); } var managementClient = InitializeManagementClient(configuration); await CloseRabbitConnection(managementClient); await Task.Delay(100); disconnectedEventFired.ShouldAllBeEquivalentTo(true); } }
public async Task Subscriber_SeveralNetworkDisconnected_CallbackDelegateRunOnce() { //prepare IConfiguration configuration = InitializeConfiguration(); const int maxRetryCount = 1; const int maxPrefetchCount = 1; using (IContainer container = ConfigurationHelper.ConfigureContainer(configuration)) { //create Subscriber var testEntitySubscriberFactory = container.Resolve <ISubscriberFactory>(); var subscriberName = $"Publiser_TemporaryQueue.testSubscriber_{Guid.NewGuid()}"; var numberOfRuns = 0; ISubscriber subscriber = await testEntitySubscriberFactory .CreateSubscriberAsync(subscriberName, () => { numberOfRuns++; }, new List <string> { "*.entity.create.testEntity", }, maxRetryCount, maxPrefetchCount); // create Subscriber subscriber.Subscribe(SubscriptionBuilder.Create() .AddSubscription("testEntityCreated", () => (IConsumer <string>)null) .Build()); var managementClient = InitializeManagementClient(configuration); const int disconnectedNum = 5; for (int i = 0; i < disconnectedNum; i++) { await CloseRabbitConnection(managementClient); await Task.Delay(500); } numberOfRuns.Should().Be(1); } }
public async Task Subscriber_NetworkDisconnected_TemporaryQueueIsDeleted() { //prepare IConfiguration configuration = InitializeConfiguration(); const int maxRetryCount = 1; const int maxPrefetchCount = 1; using (IContainer container = ConfigurationHelper.ConfigureContainer(configuration)) { //create Subscriber var testEntitySubscriberFactory = container.Resolve <ISubscriberFactory>(); var subscriberName = $"Publiser_TemporaryQueue.testSubscriber_{Guid.NewGuid()}"; ISubscriber subscriber = await testEntitySubscriberFactory .CreateSubscriberAsync(subscriberName, () => { }, new List <string> { "*.entity.create.testEntity", }, maxRetryCount, maxPrefetchCount); // create Subscriber subscriber.Subscribe(SubscriptionBuilder.Create() .AddSubscription("testEntityCreated", () => (IConsumer <string>)null) .Build()); var managementClient = InitializeManagementClient(configuration); await CloseRabbitConnection(managementClient); await Task.Delay(100); var queuExists = await CheckQueueExists(managementClient, subscriberName); queuExists.Should().BeFalse(); } }
public void QueueInfoProvider_GetQueueInfo_UnknownQueueExceptionShouldBeThrown() { //prepare IConfiguration configuration = ConfigurationHelper.ProvideConfiguration(); var exchangeName = "QueueInfoProvider_GetQueueInfo_UnknownQueueExceptionShouldBeThrown.exchangename"; configuration["rabbitmq:exchangename"] = exchangeName; configuration["rabbitmq:waitexchangename"] = exchangeName.Replace("exchangename", "waitexchangename"); IContainer container = ConfigurationHelper.ConfigureContainer(configuration); var queueInfoProvider = container.Resolve <IQueueInfoProvider>(); //act Action f = () => { queueInfoProvider.GetQueueInfo( "uknownsubscriber"); }; //check f.ShouldThrow <Exception>(); }
public async Task Subscriber_MalformedMessage_MessageMustBeMovedToGlobalDeadLetterQueue(string caseName, string messageBody) { var testName = $"{nameof(Subscriber_MalformedMessage_MessageMustBeMovedToGlobalDeadLetterQueue)}_{caseName}"; //prepare IConfiguration configuration = ConfigurationHelper.ProvideConfiguration(); var exchangeName = $"{testName}.exchangename"; configuration["rabbitmq:exchangename"] = exchangeName; configuration["rabbitmq:waitexchangename"] = exchangeName.Replace("exchangename", "waitexchangename"); var maxretrycount = 2; IContainer container = ConfigurationHelper.ConfigureContainer(configuration); //create Subscriber var bookingCreatedSubscriberFactory = container.Resolve <ISubscriberFactory>(); ISubscriber typedSubscriber = await bookingCreatedSubscriberFactory .CreateSubscriberAsync(testName + ".stubconsumer", new List <string> { "*.entity.create.booking" }, maxretrycount); var consumer = new StubConsumer(); typedSubscriber.Subscribe(SubscriptionBuilder.Create().AddDefaultSubscription(() => consumer).Build()); //create Bus var bus = container.Resolve <IAdvancedBus>(); string routingKey = "changetracker.entity.create.booking"; //act var body = Encoding.UTF8.GetBytes(messageBody); var properties = new MessageProperties { DeliveryMode = 2//persistent }; await bus.PublishAsync(await bus.ExchangeDeclareAsync(exchangeName, ExchangeType.Topic), routingKey, false, properties, body); await Task.Delay(3000); //check var deadleterqueue = bus.QueueDeclare($"{exchangeName}.defaultTombQueue"); IBasicGetResult result = bus.Get(deadleterqueue); var message = Encoding.UTF8.GetString(result.Body); JObject errorEvent = JObject.Parse(message); errorEvent["RoutingKey"].Value <string>().Should().Be("changetracker.entity.create.booking"); errorEvent["Exchange"] .Value <string>().Should().Be(exchangeName); errorEvent["Queue"] .Value <string>().Should().Be($"{exchangeName}.{testName}.stubconsumer"); //check bindings var managementClient = new ManagementClient(configuration["rabbitmqmanagement:hostUrl"], configuration["rabbitmqmanagement:username"], configuration["rabbitmqmanagement:password"], configuration.GetValue <int>("rabbitmqmanagement:portNumber")); var virtualHostName = new ConnectionStringParser().Parse(configuration["rabbitmq:connectionstring"]).VirtualHost; var virtualhost = await managementClient.GetVhostAsync(virtualHostName); var deadleterq = await managementClient.GetQueueAsync(deadleterqueue.Name, virtualhost); var deadleterqbindings = (await managementClient.GetBindingsForQueueAsync(deadleterq)).ToList(); deadleterqbindings.Should().HaveCount(2);//one is default deadleterqbindings.Where(x => x.Source == $"{exchangeName}_error" && x.RoutingKey == routingKey).Should().HaveCount(1); container.Dispose(); }
public async Task Subscriber_DiscardException_MessageMustBeMovedToGlobalDeadLetterQueue() { //prepare IConfiguration configuration = ConfigurationHelper.ProvideConfiguration(); var exchangeName = "Subscriber_DiscardException_MessageMustBeMovedToGlobalDeadLetterQueue.exchangename"; configuration["rabbitmq:exchangename"] = exchangeName; configuration["rabbitmq:waitexchangename"] = exchangeName.Replace("exchangename", "waitexchangename"); var maxretrycount = 2; IContainer container = ConfigurationHelper.ConfigureContainer(configuration); //create Subscriber var bookingCreatedSubscriberFactory = container.Resolve <ISubscriberFactory>(); ISubscriber typedSubscriber = await bookingCreatedSubscriberFactory .CreateSubscriberAsync("Subscriber_DiscardException_MessageMustBeMovedToGlobalDeadLetterQueue" + ".typedbookingcreatedconsumer", new List <string> { "*.entity.create.booking" }, maxretrycount); DiscardConsumer discardConsumer = new DiscardConsumer(); typedSubscriber.Subscribe(SubscriptionBuilder.Create().AddDefaultSubscription(() => discardConsumer).Build()); //create Publisher var publisher = container.Resolve <IPublisher>(); string routingKey = "changetracker.entity.create.booking"; //act BookingCreated bookingCreated = new BookingCreated() { BookingName = string.Concat("Microsoft Sale", Guid.NewGuid().ToString()) }; var bookingCreatedIntegrationEvent = new IntegrationEvent <BookingCreated>() { Content = bookingCreated, EventType = "bookingcreated", CorrelationId = Guid.NewGuid() }; await publisher.PublishEventAsync(bookingCreatedIntegrationEvent, routingKey); await Task.Delay(3000); //check var bus = container.Resolve <IAdvancedBus>(); var deadleterqueue = bus.QueueDeclare($"{exchangeName}.defaultTombQueue"); IBasicGetResult result = bus.Get(deadleterqueue); var message = Encoding.UTF8.GetString(result.Body); JObject errorEvent = JObject.Parse(message); errorEvent["RoutingKey"].Value <string>().Should().Be("changetracker.entity.create.booking"); errorEvent["Exchange"] .Value <string>().Should().Be("Subscriber_DiscardException_MessageMustBeMovedToGlobalDeadLetterQueue.exchangename"); errorEvent["Queue"] .Value <string>().Should().Be($"{exchangeName}.Subscriber_DiscardException_MessageMustBeMovedToGlobalDeadLetterQueue.typedbookingcreatedconsumer"); //check bindings var managementClient = new ManagementClient(configuration["rabbitmqmanagement:hostUrl"], configuration["rabbitmqmanagement:username"], configuration["rabbitmqmanagement:password"], configuration.GetValue <int>("rabbitmqmanagement:portNumber")); var virtualHostName = new ConnectionStringParser().Parse(configuration["rabbitmq:connectionstring"]).VirtualHost; var virtualhost = await managementClient.GetVhostAsync(virtualHostName); var deadleterq = await managementClient.GetQueueAsync(deadleterqueue.Name, virtualhost); var deadleterqbindings = (await managementClient.GetBindingsForQueueAsync(deadleterq)).ToList(); deadleterqbindings.Should().HaveCount(2);//one is default deadleterqbindings.Where(x => x.Source == $"{exchangeName}_error" && x.RoutingKey == routingKey).Should().HaveCount(1); container.Dispose(); }
public async Task Subscriber_ExceededCountOfAttempts_MessageMustBeMovedToSpecificDeadLetterQueue() { //prepare IConfiguration configuration = ConfigurationHelper.ProvideConfiguration(); var exchangeName = "Subscriber_ExceededCountOfAttempts_MessageMustBeMovedToDeadLetterQueue.exchangename"; configuration["rabbitmq:exchangename"] = exchangeName; configuration["rabbitmq:waitexchangename"] = exchangeName.Replace("exchangename", "waitexchangename"); configuration["rabbitmq:retryfactor"] = 100.ToString(); var maxretrycount = 2; IContainer container = ConfigurationHelper.ConfigureContainer(configuration); //create Subscriber var bookingCreatedSubscriberFactory = container.Resolve <ISubscriberFactory>(); ISubscriber typedSubscriber = await bookingCreatedSubscriberFactory .CreateSubscriberAsync("Subscriber_ExceededCountOfAttempts_MessageMustBeMovedToDeadLetterQueue" + ".typedbookingcreatedconsumer", new List <string> { "*.entity.create.booking" }, maxretrycount); BookingTypedConsumer typedConsumer = new BookingTypedConsumer(3); IntegrationEvent <BookingCreated> actualDeadLetterCallbackIntegrationEvent = null; Exception actualDeadLetterCallbackException = null; typedSubscriber.Subscribe(SubscriptionBuilder.Create().AddDefaultSubscription(() => typedConsumer, (integrationEvent, exception) => { actualDeadLetterCallbackIntegrationEvent = integrationEvent; actualDeadLetterCallbackException = exception; return(Task.CompletedTask); }).Build()); //create Publisher var publisher = container.Resolve <IPublisher>(); string routingKey = "changetracker.entity.create.booking"; //act BookingCreated bookingCreated = new BookingCreated() { BookingName = string.Concat("Microsoft Sale", Guid.NewGuid().ToString()) }; var bookingCreatedIntegrationEvent = new IntegrationEvent <BookingCreated>() { Content = bookingCreated, EventType = "bookingcreated", CorrelationId = Guid.NewGuid() }; await publisher.PublishEventAsync(bookingCreatedIntegrationEvent, routingKey); //wait 1 second await Task.Delay(1000); //check var bus = container.Resolve <IAdvancedBus>(); var deadleterqueue = bus.QueueDeclare($"{exchangeName}.deadletter" + ".Subscriber_ExceededCountOfAttempts_MessageMustBeMovedToDeadLetterQueue." + "typedbookingcreatedconsumer"); IBasicGetResult result = bus.Get(deadleterqueue); var message = Encoding.UTF8.GetString(result.Body); var actualDeadLetterQueueIntergrationEvent = JsonConvert. DeserializeObject <IntegrationEvent <DeadLetterEventDescriptor <BookingCreated> > >(message); result.Info.RoutingKey.Should().Be("deadletter" + ".Subscriber_ExceededCountOfAttempts_MessageMustBeMovedToDeadLetterQueue" + ".typedbookingcreatedconsumer"); actualDeadLetterQueueIntergrationEvent.Content.Original .ShouldBeEquivalentTo(bookingCreatedIntegrationEvent); actualDeadLetterQueueIntergrationEvent.CorrelationId .ShouldBeEquivalentTo(bookingCreatedIntegrationEvent.CorrelationId); actualDeadLetterQueueIntergrationEvent.EventType.Should() .BeEquivalentTo(string.Concat("deadletter.", bookingCreatedIntegrationEvent.EventType)); actualDeadLetterCallbackException.Message.Should().Be("ExceptionHasBeenThrown"); actualDeadLetterCallbackException.Should().BeOfType <Exception>(); actualDeadLetterCallbackIntegrationEvent.ShouldBeEquivalentTo(bookingCreatedIntegrationEvent); typedConsumer.ProcessedIntegrationEvent.Should().BeNull(); typedConsumer.CountOfAttempts.Should().Be(3); container.Dispose(); }
public async Task Subscriber_NetworkDisconnectedNewSubscriberCreated_EventReceived() { //prepare IConfiguration configuration = InitializeConfiguration(); const int maxRetryCount = 1; const int maxPrefetchCount = 1; using (IContainer container = ConfigurationHelper.ConfigureContainer(configuration)) { //create Subscriber var testEntitySubscriberFactory = container.Resolve <ISubscriberFactory>(); var subscriberName = $"Publiser_TemporaryQueue.testSubscriber_{Guid.NewGuid()}"; TaskKeeper recreatingTask = new TaskKeeper(); ISubscriber subscriber = await testEntitySubscriberFactory .CreateSubscriberAsync(subscriberName, () => { recreatingTask.Task = RecreateSubscriber(); }, new List <string> { "*.entity.create.testEntity", }, maxRetryCount, maxPrefetchCount); // create Subscriber subscriber.Subscribe(SubscriptionBuilder.Create() .AddSubscription("testEntityCreated", () => (IConsumer <string>)null) .Build()); var managementClient = InitializeManagementClient(configuration); await CloseRabbitConnection(managementClient); while (recreatingTask.Task == null) { await Task.Delay(100); } await recreatingTask.Task; async Task RecreateSubscriber() { try { var subscriberNewName = $"Publiser_TemporaryQueue.testSubscriber_{Guid.NewGuid()}"; subscriber = await testEntitySubscriberFactory .CreateSubscriberAsync(subscriberNewName, true, new List <string> { "*.entity.create.testEntity", }, maxRetryCount, maxPrefetchCount); // create Subscriber var testConsumer = new TestEventConsumer(); subscriber.Subscribe(SubscriptionBuilder.Create() .AddSubscription("testEntityCreated", () => testConsumer) .Build()); var publisher = container.Resolve <IPublisher>(); var testEvent = new IntegrationEvent <string> { EventId = Guid.NewGuid(), CorrelationId = Guid.NewGuid(), EventCreationDate = DateTime.UtcNow, EventType = "testEntityCreated", Version = "0.1", Content = Guid.NewGuid().ToString() }; var routingKey = "test.entity.create.testEntity"; await publisher.PublishEventAsync(testEvent, routingKey); await Task.Delay(3000); // we successfully received event after disconnect testConsumer.ConsumedEvents.Should().BeGreaterOrEqualTo(1); } catch (Exception e) { Assert.True(false, $"{e.Message}"); } } } }
public async Task Subscribe_DeadLetterIsSibscribedThenDisposed_DeadLetterMessagesAreDeliveredCorrectlyToSecondSubscriber() { //prepare IConfiguration configuration = ConfigurationHelper.ProvideConfiguration(); var exchangeName = "Subscribe_DeadLetterIsSibscribedThenUnsibcribed_DeadLetterMessagesAreDeliveredCorrectly.exchangename"; configuration["rabbitmq:exchangename"] = exchangeName; configuration["rabbitmq:waitexchangename"] = exchangeName.Replace("exchangename", "waitexchangename"); IContainer container = ConfigurationHelper.ConfigureContainer(configuration); //Let's create AccountBookingTypedConsumer Subscriber var maxretrycount = 0; var accountcreatedbindingkey = "*.entity.create.account"; var accountCreatedSubscriberFactory = container.Resolve <ISubscriberFactory>(); var accountTypedConsumerSubscriberName = "Subscribe_DeadLetterIsSibscribedThenUnsibcribed_DeadLetterMessagesAreDeliveredCorrectly"; ISubscriber typedSubscriber = await accountCreatedSubscriberFactory .CreateSubscriberAsync(accountTypedConsumerSubscriberName , new List <string> { accountcreatedbindingkey }, maxretrycount); var accountCreatedEventType = "accountcreated"; AccountBookingTypedConsumer typedConsumer = new AccountBookingTypedConsumer(10, 0); typedSubscriber.Subscribe(SubscriptionBuilder.Create() .AddSubscription <AccountCreated>(accountCreatedEventType, () => typedConsumer).Build()); //Let's create AccountTypedConsumer for dead letter queue Subscriber var deadLetterSubscriberFactory = container.Resolve <IDeadLetterSubscriberFactory>(); DeadLetterConsumer deadLetterConsumer = new DeadLetterConsumer(0, 0); ISubscriber deadLetterSubscriber = await deadLetterSubscriberFactory.CreateSubscriberAsync(accountTypedConsumerSubscriberName, 1); deadLetterSubscriber.Subscribe(SubscriptionBuilder.Create() .AddDefaultSubscription <DeadLetterEventDescriptor <AccountCreated> >(() => deadLetterConsumer).Build()); //create Publisher var publisher = container.Resolve <IPublisher>(); string accountcreatedroutingKey = "changetracker.entity.create.account"; //act AccountCreated accountCreated = new AccountCreated() { AccountLevel = 10 }; var accountCreatedIntegrationEvent = new IntegrationEvent <AccountCreated>() { Content = accountCreated, EventType = accountCreatedEventType, CorrelationId = Guid.NewGuid() }; await publisher.PublishEventAsync(accountCreatedIntegrationEvent, accountcreatedroutingKey); //The event must be sent to the deadletter queue. await Task.Delay(1000); //Let's check that dead letter consumer processed the message with Type = AccountCreated on the first try. IntegrationEvent <DeadLetterEventDescriptor <AccountCreated> > deadLetterAccountCreatedMessage = deadLetterConsumer.ProcessedAccountCreatedIntegrationEvents.First(); deadLetterConsumer.ProcessedAccountCreatedIntegrationEvents.Count().Should().Be(1); deadLetterAccountCreatedMessage.CorrelationId.Should().Be(accountCreatedIntegrationEvent.CorrelationId); deadLetterAccountCreatedMessage.Content.Original.ShouldBeEquivalentTo(accountCreatedIntegrationEvent); deadLetterConsumer.CountOfAttemptsForAccountCreated.Should().Be(1); //Let's dispose deadLetterSubscriber.Dispose(); //Let's publish the new message that must be sent to the dead letter queue AccountCreated uptickAccountCreated = new AccountCreated() { AccountLevel = 20 }; var uptickAccountCreatedIntegrationEvent = new IntegrationEvent <AccountCreated>() { Content = uptickAccountCreated, EventType = accountCreatedEventType, CorrelationId = Guid.NewGuid() }; await publisher.PublishEventAsync(uptickAccountCreatedIntegrationEvent, accountcreatedroutingKey); //Let's create the new Dead Letter queue Subscriber DeadLetterConsumer secondDeadLetterConsumer = new DeadLetterConsumer(0, 0); ISubscriber secondDeadLetterSubscriber = await deadLetterSubscriberFactory.CreateSubscriberAsync(accountTypedConsumerSubscriberName, 1); secondDeadLetterSubscriber.Subscribe(SubscriptionBuilder.Create() .AddDefaultSubscription <DeadLetterEventDescriptor <AccountCreated> >(() => secondDeadLetterConsumer).Build()); await Task.Delay(1000); //check that the second dead letter qeuee message was sent to the new second consumer. The first should not have recieved new message. deadLetterConsumer.ProcessedAccountCreatedIntegrationEvents.Count().Should().Be(1); deadLetterAccountCreatedMessage.CorrelationId.Should().Be(accountCreatedIntegrationEvent.CorrelationId); deadLetterAccountCreatedMessage.Content.Original.ShouldBeEquivalentTo(accountCreatedIntegrationEvent); deadLetterConsumer.CountOfAttemptsForAccountCreated.Should().Be(1); IntegrationEvent <DeadLetterEventDescriptor <AccountCreated> > uptickAccountDeadLetterAccountCreatedMessage = secondDeadLetterConsumer.ProcessedAccountCreatedIntegrationEvents.First(); secondDeadLetterConsumer.ProcessedAccountCreatedIntegrationEvents.Count().Should().Be(1); uptickAccountDeadLetterAccountCreatedMessage.CorrelationId.Should().Be(uptickAccountCreatedIntegrationEvent.CorrelationId); uptickAccountDeadLetterAccountCreatedMessage.Content.Original.ShouldBeEquivalentTo(uptickAccountCreatedIntegrationEvent); secondDeadLetterConsumer.CountOfAttemptsForAccountCreated.Should().Be(1); }
public async Task Subscribe_DeadLetterMessageIsSentToDeadLetter_DeadLetterIsReadBySubscriber() { //prepare IConfiguration configuration = ConfigurationHelper.ProvideConfiguration(); var exchangeName = "Subscribe_DeadLetterMessageIsSentToDeadLetter_DeadLetterIsReadBySubscriber.exchangename"; configuration["rabbitmq:exchangename"] = exchangeName; configuration["rabbitmq:waitexchangename"] = exchangeName.Replace("exchangename", "waitexchangename"); IContainer container = ConfigurationHelper.ConfigureContainer(configuration); //Let's create AccountBookingTypedConsumer Subscriber var maxretrycount = 0; var accountcreatedbindingkey = "*.entity.create.account"; var bookingcreatedbindingkey = "*.entity.create.booking"; var accountBookingCreatedSubscriberFactory = container.Resolve <ISubscriberFactory>(); var accountBookingTypedConsumerSubscriberName = "Subscribe_DeadLetterMessagesAreSentToDeadLetter_DeadLettersAreReadByAppropriateConsumers"; ISubscriber typedSubscriber = await accountBookingCreatedSubscriberFactory .CreateSubscriberAsync(accountBookingTypedConsumerSubscriberName , new List <string> { accountcreatedbindingkey, bookingcreatedbindingkey }, maxretrycount); var accountCreatedEventType = "accountcreated"; var bookingCreatedEventType = "bookingcreated"; AccountBookingTypedConsumer typedConsumer = new AccountBookingTypedConsumer(10, 10); typedSubscriber.Subscribe(SubscriptionBuilder.Create() .AddSubscription <AccountCreated>(accountCreatedEventType, () => typedConsumer) .AddDefaultSubscription <BookingCreated>(() => typedConsumer).Build()); //Let's create AccountBookingTypedConsumer dead letter queue Subscriber var deadLetterSubscriberFactory = container.Resolve <IDeadLetterSubscriberFactory>(); DeadLetterConsumer deadLetterConsumer = new DeadLetterConsumer(0, 0); ISubscriber deadLetterSubscriber = await deadLetterSubscriberFactory.CreateSubscriberAsync(accountBookingTypedConsumerSubscriberName, 1); deadLetterSubscriber.Subscribe(SubscriptionBuilder.Create() .AddSubscription <DeadLetterEventDescriptor <BookingCreated> >(bookingCreatedEventType, () => deadLetterConsumer) .AddDefaultSubscription <DeadLetterEventDescriptor <AccountCreated> >(() => deadLetterConsumer).Build()); //create Publisher var publisher = container.Resolve <IPublisher>(); string accountcreatedroutingKey = "changetracker.entity.create.account"; string bookingcreatedroutingKey = "changetracker.entity.create.booking"; //act AccountCreated accountCreated = new AccountCreated() { AccountLevel = 10 }; var accountCreatedIntegrationEvent = new IntegrationEvent <AccountCreated>() { Content = accountCreated, EventType = accountCreatedEventType, CorrelationId = Guid.NewGuid() }; await publisher.PublishEventAsync(accountCreatedIntegrationEvent, accountcreatedroutingKey); BookingCreated bookingCreated = new BookingCreated() { BookingName = "bookingName" }; var bookingCreatedIntegrationEvent = new IntegrationEvent <BookingCreated>() { Content = bookingCreated, EventType = bookingCreatedEventType, CorrelationId = Guid.NewGuid() }; await publisher.PublishEventAsync(bookingCreatedIntegrationEvent, bookingcreatedroutingKey); //The event must be sent to the deadletter queue. await Task.Delay(500); //Let's check that dead letter consumer got the message. IntegrationEvent <DeadLetterEventDescriptor <AccountCreated> > deadLetterAccountCreatedMessage = deadLetterConsumer.ProcessedAccountCreatedIntegrationEvents.First(); deadLetterConsumer.ProcessedAccountCreatedIntegrationEvents.Count().Should().Be(1); deadLetterAccountCreatedMessage.CorrelationId.Should().Be(accountCreatedIntegrationEvent.CorrelationId); deadLetterAccountCreatedMessage.Content.Original.ShouldBeEquivalentTo(accountCreatedIntegrationEvent); IntegrationEvent <DeadLetterEventDescriptor <BookingCreated> > deadLetterBookingCreatedMessage = deadLetterConsumer.ProcessedBookingCreatedIntegrationEvents.First(); deadLetterConsumer.ProcessedBookingCreatedIntegrationEvents.Count().Should().Be(1); deadLetterBookingCreatedMessage.CorrelationId.Should().Be(bookingCreatedIntegrationEvent.CorrelationId); deadLetterBookingCreatedMessage.Content.Original.ShouldBeEquivalentTo(bookingCreatedIntegrationEvent); }
public async Task QueueInfoProvider_GetQueueInfo_CorrectCountOfReadyMessagesMustBeReturned() { //prepare IConfiguration configuration = ConfigurationHelper.ProvideConfiguration(); var exchangeName = "QueueInfoProvider_GetQueueInfo_CorrectCountOfReadyMessagesMustBeReturned.exchangename"; configuration["rabbitmq:exchangename"] = exchangeName; configuration["rabbitmq:waitexchangename"] = exchangeName.Replace("exchangename", "waitexchangename"); var maxretrycount = 2; IContainer container = ConfigurationHelper.ConfigureContainer(configuration); //create Subscriber var bookingCreatedSubscriberFactory = container.Resolve <ISubscriberFactory>(); ISubscriber fastSubscriber = await bookingCreatedSubscriberFactory .CreateSubscriberAsync("QueueInfoProvider_GetQueueInfo_CorrectCountOfReadyMessagesMustBeReturned" + ".fast", new List <string> { "*.entity.create.booking", }, maxretrycount, 5); ISubscriber slowSubscriber = await bookingCreatedSubscriberFactory .CreateSubscriberAsync("QueueInfoProvider_GetQueueInfo_CorrectCountOfReadyMessagesMustBeReturned" + ".slow", new List <string> { "*.entity.create.booking", }, maxretrycount, 1); //create Publisher var publisher = container.Resolve <IPublisher>(); string bookingRoutingKey = "changetracker.entity.create.booking"; //act BookingCreated bookingCreated = new BookingCreated() { BookingName = string.Concat("Microsoft Sale", Guid.NewGuid().ToString()) }; var bookingCreatedIntegrationEvent = new IntegrationEvent <BookingCreated>() { Content = bookingCreated, EventType = "bookingcreated" }; for (int i = 1; i <= 8; i++) { await publisher.PublishEventAsync(bookingCreatedIntegrationEvent, bookingRoutingKey); } //wait 1 second await Task.Delay(1000); //ckeck the GetQueueInfo method first call var queueInfoProvider = container.Resolve <IQueueInfoProvider>(); var fastSubscriberQueueSnapshotInfo = queueInfoProvider.GetQueueInfo( "QueueInfoProvider_GetQueueInfo_CorrectCountOfReadyMessagesMustBeReturned.fast"); fastSubscriberQueueSnapshotInfo.CountOfMessages.Should().Be(8); var slowSubscriberQueueSnapshotInfo = queueInfoProvider.GetQueueInfo( "QueueInfoProvider_GetQueueInfo_CorrectCountOfReadyMessagesMustBeReturned.slow"); slowSubscriberQueueSnapshotInfo.CountOfMessages.Should().Be(8); //Let's create Subscriber var fastBookingTypedSubscriberConsumer = new BookingTypedParallellismCounterConsumer(500); var slowBookingTypedSubscriberConsumer = new BookingTypedParallellismCounterConsumer(500); fastSubscriber.Subscribe(SubscriptionBuilder.Create() .AddSubscription("bookingcreated", () => fastBookingTypedSubscriberConsumer) .Build()); slowSubscriber.Subscribe(SubscriptionBuilder.Create() .AddSubscription("bookingcreated", () => slowBookingTypedSubscriberConsumer) .Build()); //wait 10 seconds await Task.Delay(10000); //check //ckeck the GetQueueInfo method second call fastSubscriberQueueSnapshotInfo = queueInfoProvider.GetQueueInfo( "QueueInfoProvider_GetQueueInfo_CorrectCountOfReadyMessagesMustBeReturned.fast"); fastSubscriberQueueSnapshotInfo.CountOfMessages.Should().Be(0); slowSubscriberQueueSnapshotInfo = queueInfoProvider.GetQueueInfo( "QueueInfoProvider_GetQueueInfo_CorrectCountOfReadyMessagesMustBeReturned.slow"); slowSubscriberQueueSnapshotInfo.CountOfMessages.Should().Be(0); container.Dispose(); }
public async Task Subscriber_ProcessThe2MessageTheFirstTimeWith2DifferentRoutingKeys_MessagesMustBeRemovedFromTheRabbitMq() { //prepare IConfiguration configuration = ConfigurationHelper.ProvideConfiguration(); var exchangeName = "Subscriber_ProcessTheMessageTheFirstTime_MessageMustBeRemovedFromTheRabbitMq.exchangename"; configuration["rabbitmq:exchangename"] = exchangeName; configuration["rabbitmq:waitexchangename"] = exchangeName.Replace("exchangename", "waitexchangename"); var maxretrycount = 2; IContainer container = ConfigurationHelper.ConfigureContainer(configuration); //create Subscriber var bookingCreatedSubscriberFactory = container.Resolve <ISubscriberFactory>(); ISubscriber typedSubscriber = await bookingCreatedSubscriberFactory .CreateSubscriberAsync("Subscriber_ProcessTheMessageTheFirstTime_MessageMustBeRemovedFromTheRabbitMq" + ".typedbookingcreatedconsumer", new List <string> { "*.entity.create.booking", "*.entity.create.account" }, maxretrycount); BookingTypedConsumer bookingTypedConsumer = new BookingTypedConsumer(0); AccountTypedConsumer accountTypedConsumer = new AccountTypedConsumer(0); typedSubscriber.Subscribe(SubscriptionBuilder.Create() .AddSubscription("bookingcreated", () => bookingTypedConsumer) .AddSubscription("accountcreated", () => accountTypedConsumer).Build()); //create Publisher var publisher = container.Resolve <IPublisher>(); string bookingRoutingKey = "changetracker.entity.create.booking"; string accountRoutingKey = "changetracker.entity.create.account"; //act BookingCreated bookingCreated = new BookingCreated() { BookingName = string.Concat("Microsoft Sale", Guid.NewGuid().ToString()) }; AccountCreated accountCreated = new AccountCreated() { AccountLevel = 100 }; var bookingCreatedIntegrationEvent = new IntegrationEvent <BookingCreated>() { Content = bookingCreated, EventType = "bookingcreated" }; var accountCreatedIntegrationEvent = new IntegrationEvent <AccountCreated>() { Content = accountCreated, EventType = "accountcreated" }; await publisher.PublishEventAsync(bookingCreatedIntegrationEvent, bookingRoutingKey); await publisher.PublishEventAsync(accountCreatedIntegrationEvent, accountRoutingKey); await Task.Delay(200); //check bookingTypedConsumer.ProcessedIntegrationEvent.ShouldBeEquivalentTo(bookingCreatedIntegrationEvent); bookingTypedConsumer.CountOfAttempts.Should().Be(1); accountTypedConsumer.ProcessedIntegrationEvent.ShouldBeEquivalentTo(accountCreatedIntegrationEvent); accountTypedConsumer.CountOfAttempts.Should().Be(1); container.Dispose(); }
public async Task Subscriber_2DifferentSubscribersWithEqualPrefetchCount_SubscribersShouldProcessEventsInParallelWithEqualSpeed() { //prepare IConfiguration configuration = ConfigurationHelper.ProvideConfiguration(); var exchangeName = "Subscriber_2DifferentSubscribersWithEqualPrefetchCount_SubscribersShouldProcessEventsInParallelWithEqualSpeed.exchangename"; configuration["rabbitmq:exchangename"] = exchangeName; configuration["rabbitmq:waitexchangename"] = exchangeName.Replace("exchangename", "waitexchangename"); var maxretrycount = 2; IContainer container = ConfigurationHelper.ConfigureContainer(configuration); //create Subscriber var bookingCreatedSubscriberFactory = container.Resolve <ISubscriberFactory>(); ISubscriber fastSubscriber = await bookingCreatedSubscriberFactory .CreateSubscriberAsync("Subscriber_2DifferentSubscribersWithEqualPrefetchCount_SubscribersShouldProcessEventsInParallelWithEqualSpeed" + ".first", new List <string> { "*.entity.create.booking", }, maxretrycount, 1); ISubscriber slowSubscriber = await bookingCreatedSubscriberFactory .CreateSubscriberAsync("Subscriber_2DifferentSubscribersWithEqualPrefetchCount_SubscribersShouldProcessEventsInParallelWithEqualSpeed" + ".second", new List <string> { "*.entity.create.booking", }, maxretrycount, 1); var firstBookingTypedSubscriberConsumer = new BookingTypedParallellismCounterConsumer(3000); var secondBookingTypedSubscriberConsumer = new BookingTypedParallellismCounterConsumer(3000); fastSubscriber.Subscribe(SubscriptionBuilder.Create() .AddSubscription("bookingcreated", () => firstBookingTypedSubscriberConsumer) .Build()); slowSubscriber.Subscribe(SubscriptionBuilder.Create() .AddSubscription("bookingcreated", () => secondBookingTypedSubscriberConsumer) .Build()); //create Publisher var publisher = container.Resolve <IPublisher>(); string bookingRoutingKey = "changetracker.entity.create.booking"; //act BookingCreated bookingCreated = new BookingCreated() { BookingName = string.Concat("Microsoft Sale", Guid.NewGuid().ToString()) }; var bookingCreatedIntegrationEvent = new IntegrationEvent <BookingCreated>() { Content = bookingCreated, EventType = "bookingcreated" }; for (int i = 1; i <= 8; i++) { await publisher.PublishEventAsync(bookingCreatedIntegrationEvent, bookingRoutingKey); } //wait 30 seconds await Task.Delay(30000); //check firstBookingTypedSubscriberConsumer.MaxParrelelEvents.Should().Be(1); firstBookingTypedSubscriberConsumer.CountOfProcessedEvents.Should().Be(8); secondBookingTypedSubscriberConsumer.MaxParrelelEvents.Should().Be(1); secondBookingTypedSubscriberConsumer.CountOfProcessedEvents.Should().Be(8); container.Dispose(); }
public async Task Subscribe_DeadLetterMessageIsSentToDeadLetter_DeadLetterIsReadByDeadLetterReloaderAndSentToTheOriginalQueue() { //prepare IConfiguration configuration = ConfigurationHelper.ProvideConfiguration(); var exchangeName = "Subscribe_DeadLetterMessageIsSentToDeadLetter_DeadLetterIsReadByDeadLetterReloaderAndSentToTheOriginalQueue.exchangename"; configuration["rabbitmq:exchangename"] = exchangeName; configuration["rabbitmq:waitexchangename"] = exchangeName.Replace("exchangename", "waitexchangename"); IContainer container = ConfigurationHelper.ConfigureContainer(configuration); //Let's create AccountBookingTypedConsumer Subscriber var maxretrycount = 0; var accountcreatedbindingkey = "*.entity.create.account"; var bookingcreatedbindingkey = "*.entity.create.booking"; var accountBookingCreatedSubscriberFactory = container.Resolve <ISubscriberFactory>(); var accountBookingTypedConsumerSubscriberName = "Subscribe_DeadLetterMessageIsSentToDeadLetter_DeadLetterIsReadByDeadLetterReloaderAndSentToTheOriginalQueue"; ISubscriber typedSubscriber = await accountBookingCreatedSubscriberFactory .CreateSubscriberAsync(accountBookingTypedConsumerSubscriberName , new List <string> { accountcreatedbindingkey, bookingcreatedbindingkey }, maxretrycount); var accountCreatedEventType = "accountcreated"; var bookingCreatedEventType = "bookingcreated"; AccountBookingTypedConsumer typedConsumer = new AccountBookingTypedConsumer(1, 1); typedSubscriber.Subscribe(SubscriptionBuilder.Create() .AddSubscription <AccountCreated>(accountCreatedEventType, () => typedConsumer) .AddDefaultSubscription <BookingCreated>(() => typedConsumer).Build()); //create Publisher var publisher = container.Resolve <IPublisher>(); string accountcreatedroutingKey = "changetracker.entity.create.account"; string bookingcreatedroutingKey = "changetracker.entity.create.booking"; //Let's create AccountBookingTypedConsumer dead letter queue Subscriber and use DeadLetterReloader var deadLetterSubscriberFactory = container.Resolve <IDeadLetterSubscriberFactory>(); DeadLetterReloader <AccountCreated> deadLetterreloader = new DeadLetterReloader <AccountCreated>(publisher, accountBookingTypedConsumerSubscriberName); ISubscriber deadLetterSubscriber = await deadLetterSubscriberFactory.CreateSubscriberAsync(accountBookingTypedConsumerSubscriberName, 1); deadLetterSubscriber.Subscribe(SubscriptionBuilder.Create() .AddDefaultSubscription(() => deadLetterreloader).Build()); //act AccountCreated accountCreated = new AccountCreated() { AccountLevel = 10 }; var accountCreatedIntegrationEvent = new IntegrationEvent <AccountCreated>() { Content = accountCreated, EventType = accountCreatedEventType, CorrelationId = Guid.NewGuid() }; await publisher.PublishEventAsync(accountCreatedIntegrationEvent, accountcreatedroutingKey); //The event must be sent to the deadletter queue. await Task.Delay(2000); //Let's check that dead letter reloader processed the message with Type = AccountCreated and sent it to the original queue. //AccountBookingTypedConsumer should process the original message at the second attempt. IntegrationEvent <AccountCreated> accountCreatedMessage = typedConsumer.ProcessedAccountCreatedIntegrationEvent; accountCreatedMessage.CorrelationId.Should().Be(accountCreatedIntegrationEvent.CorrelationId); accountCreatedMessage.Content.ShouldBeEquivalentTo(accountCreatedIntegrationEvent.Content); typedConsumer.CountOfAttemptsForAccountCreated.Should().Be(2); typedConsumer.CountOfAttemptsForBookingCreated.Should().Be(0); }
public async Task Tracker_3DifferentSubscribers_OnlyAppropriateMessagesMustBeReceived() { //prepare IConfiguration configuration = ConfigurationHelper.ProvideConfiguration(); var exchangeName = "Tracker_3DifferentSubscribers_OnlyAppropriateMessagesMustBeReceived.exchangename"; configuration["rabbitmq:exchangename"] = exchangeName; configuration["rabbitmq:waitexchangename"] = exchangeName.Replace("exchangename", "waitexchangename"); IContainer container = ConfigurationHelper.ConfigureContainer(configuration); //Let's create Tracker to follow activitygenerator and emailsignature subscribers var maxretrycount = 0; string trackerName = "servicecontroller"; string activityGeneratorName = "activitygenerator"; string emailSignatureName = "emailsignature"; string taggerName = "tagger"; var trackerFactory = container.Resolve <ITrackerFactory>(); var serviceController = await trackerFactory.CreateTrackerAsync(trackerName, false, new List <string>() { activityGeneratorName, emailSignatureName }, 0, 1); //Let's create Subscribers. We want to follow some of them (activitygenerator and emailsignature) //emailsignature and tagger subscribe to the same routing key var subscriberFactory = container.Resolve <ISubscriberFactory>(); string activitygeneratorroutingkey = "exchangecollector.create.email"; string emailsignatureroutingkey = "changetracker.table.create.activity"; string taggeroutingkey = "changetracker.table.create.activity"; ISubscriber activityGeneratorSubscriber = await subscriberFactory .CreateSubscriberAsync(activityGeneratorName, new List <string> { activitygeneratorroutingkey, }, maxretrycount, 20, true); ISubscriber emailSignatureSubscriber = await subscriberFactory .CreateSubscriberAsync(emailSignatureName, new List <string> { emailsignatureroutingkey, }, maxretrycount, 20, false); //oops! we forgot to specify that we want follow this subscriber ISubscriber taggerSubscriber = await subscriberFactory .CreateSubscriberAsync(taggerName, new List <string> { taggeroutingkey, }, maxretrycount, 20, true); //Let's specify Consumers string emailCreatedEventType = "email.created"; string activityCreatedEventType = "activity.create"; var activityGeneratorConsumer = new ActivityGeneratorConsumer(); activityGeneratorSubscriber.Subscribe( SubscriptionBuilder .Create() .AddSubscription(emailCreatedEventType, () => activityGeneratorConsumer) .Build()); var emailSignatureConsumer = new EmailSignatureConsumer(); emailSignatureSubscriber.Subscribe( SubscriptionBuilder .Create() .AddSubscription(activityCreatedEventType, () => emailSignatureConsumer) .Build()); var taggerConsumer = new TaggerConsumer(); taggerSubscriber.Subscribe( SubscriptionBuilder .Create() .AddSubscription(activityCreatedEventType, () => taggerConsumer) .Build()); //Let's process events sent to the tracking queue var trackerConsumer = new TrackerConsumer(); serviceController.Subscribe( SubscriptionBuilder .Create() .AddSubscription <string>(emailCreatedEventType, () => trackerConsumer) .AddSubscription <string>(activityCreatedEventType, () => trackerConsumer) .Build(), SubscriptionBuilder .Create() .AddSubscription <DeadLetterEventDescriptor <JObject> >(emailCreatedEventType, () => trackerConsumer) .AddSubscription <DeadLetterEventDescriptor <JObject> >(activityCreatedEventType, () => trackerConsumer) .Build()); //Let's create Publisher var publisher = container.Resolve <IPublisher>(); //Let's create and publish EmailCreated events. All of them must be catched by ActivityGenerator. The result of processing must be catched by tracker. var emailCreatedIntegrationEvent1 = new IntegrationEvent <EmailCreated>() { CorrelationId = Guid.NewGuid(), Content = new EmailCreated { Email = "*****@*****.**" }, EventType = emailCreatedEventType }; var emailCreatedIntegrationEvent2 = new IntegrationEvent <EmailCreated>() { CorrelationId = Guid.NewGuid(), Content = new EmailCreated { Email = "" }, EventType = emailCreatedEventType }; var emailCreatedIntegrationEvent3 = new IntegrationEvent <EmailCreated>() { CorrelationId = Guid.NewGuid(), Content = new EmailCreated { Email = "*****@*****.**" }, EventType = emailCreatedEventType }; await publisher.PublishEventAsync(emailCreatedIntegrationEvent1, activitygeneratorroutingkey); await publisher.PublishEventAsync(emailCreatedIntegrationEvent2, activitygeneratorroutingkey); await publisher.PublishEventAsync(emailCreatedIntegrationEvent3, activitygeneratorroutingkey); //Let's create and publish ActivityCreated events. All of them must be catched by EmailSignature and Tagger as they have the same binding key. //The result of processing should be catched by tracker. EmailSignature forgot to specify that after consuming //the explicit acknowledge message must be sent. The Tagger has not been specified as the subscriber whose message //processing results the Tracker is interested in. var activityCreatedIntegrationEvent1 = new IntegrationEvent <ActivityCreated>() { CorrelationId = Guid.NewGuid(), Content = new ActivityCreated() { Id = Guid.NewGuid().ToString() }, EventType = activityCreatedEventType }; var activityCreatedIntegrationEvent2 = new IntegrationEvent <ActivityCreated>() { CorrelationId = Guid.NewGuid(), Content = new ActivityCreated() { Id = Guid.NewGuid().ToString() }, EventType = activityCreatedEventType }; await publisher.PublishEventAsync(activityCreatedIntegrationEvent1, emailsignatureroutingkey); await publisher.PublishEventAsync(activityCreatedIntegrationEvent2, emailsignatureroutingkey); //wait 10 seconds await Task.Delay(10000); //check var actualFailedresult = new List <IntegrationEvent <DeadLetterEventDescriptor <JObject> > >(); var actualSuccessulresult = new List <IntegrationEvent <string> >(); foreach (var processedIntegrationEvent in trackerConsumer.FailedProcessedIntegrationEvents) { actualFailedresult.Add(processedIntegrationEvent); } foreach (var processedIntegrationEvent in trackerConsumer.SuccessfullyProcessedIntegrationEvents) { actualSuccessulresult.Add(processedIntegrationEvent); } actualFailedresult.Count.Should().Be(1); actualFailedresult[0].CorrelationId.Should().Be(emailCreatedIntegrationEvent2.CorrelationId); actualSuccessulresult.Count.Should().Be(2); actualSuccessulresult.Select(se => se.CorrelationId) .ShouldBeEquivalentTo(new List <Guid?> { emailCreatedIntegrationEvent1.CorrelationId, emailCreatedIntegrationEvent3.CorrelationId }); }
public async Task Aggregator_Consume40EventsWith5BucketSize_8BucketsMustBeCreated() { //prepare IConfiguration configuration = ConfigurationHelper.ProvideConfiguration(); var exchangeName = "Aggregator_Consume40EventsWith5BucketSize_8BucketsMustBeCreated.exchangename"; configuration["rabbitmq:exchangename"] = exchangeName; configuration["rabbitmq:waitexchangename"] = exchangeName.Replace("exchangename", "waitexchangename"); var maxretrycount = 2; IContainer container = ConfigurationHelper.ConfigureContainer(configuration); //create Subscriber var bookingactivityCreatedSubscriberFactory = container.Resolve <ISubscriberFactory>(); ISubscriber aggregatorSubscriber = await bookingactivityCreatedSubscriberFactory .CreateSubscriberAsync("Aggregator_Consume40EventsWith5BucketSize_8BucketsMustBeCreated" + ".bookingactivitycreatedclusterizator", new List <string> { "*.entity.create.bookingactivity", }, maxretrycount, 20); var activityBatchSubscriberFactory = container.Resolve <ISubscriberFactory>(); ISubscriber activityBatchSubscriber = await activityBatchSubscriberFactory .CreateSubscriberAsync("Aggregator_Consume40EventsWith5BucketSize_8BucketsMustBeCreated" + ".activityclusterizator", new List <string> { "*.activitytagging", }, maxretrycount, 1); //create Publisher var publisher = container.Resolve <IPublisher>(); string bookingactivityRoutingKey = "changetracker.entity.create.bookingactivity"; string activitytaggingRoutingKey = "activityclusterizator.activitytagging"; //create aggregator var bookingActivitiesChangeTrackerEventAggregator = new Aggregator <BookingActivity, Guid>( intergrationevent => Task.FromResult(intergrationevent.Content.ActivityId), 5, activitiesIds => { var activitytaggingintergrationevnt = new IntegrationEvent <ActivityTags> { EventId = Guid.NewGuid(), CorrelationId = Guid.NewGuid(), EventCreationDate = DateTime.UtcNow, EventType = "activitytagging", Version = "0.1", Content = new ActivityTags() { ActivityIds = activitiesIds.ToList() } }; return(publisher.PublishEventAsync(activitytaggingintergrationevnt, activitytaggingRoutingKey)); }, TimeSpan.Zero); aggregatorSubscriber.Subscribe(SubscriptionBuilder.Create() .AddSubscription("bookingactivityCreated", () => bookingActivitiesChangeTrackerEventAggregator) .Build()); var activityBatchProcessor = new ActivityTagsConsumer(); activityBatchSubscriber.Subscribe(SubscriptionBuilder.Create() .AddSubscription("activitytagging", () => activityBatchProcessor) .Build()); List <IntegrationEvent <BookingActivity> > originalBookingActivityCreatedEvents = new List <IntegrationEvent <BookingActivity> >(); for (int i = 1; i <= 40; i++) { originalBookingActivityCreatedEvents.Add(new IntegrationEvent <BookingActivity> { EventId = Guid.NewGuid(), CorrelationId = Guid.NewGuid(), EventCreationDate = DateTime.UtcNow, EventType = "bookingactivityCreated", Version = "0.1", Content = new BookingActivity() { ActivityId = Guid.NewGuid(), BookingId = Guid.NewGuid() } }); } //act foreach (var bookingActivityCreatedEvent in originalBookingActivityCreatedEvents) { await publisher.PublishEventAsync(bookingActivityCreatedEvent, bookingactivityRoutingKey); } //wait 10 seconds await Task.Delay(10000); //check List <Guid> expectedresult = new List <Guid>(); foreach (var processedIntegrationEvent in activityBatchProcessor.ProcessedIntegrationEvents) { processedIntegrationEvent.Content.ActivityIds.Count().Should().Be(5); expectedresult.AddRange(processedIntegrationEvent.Content.ActivityIds); } expectedresult.ShouldBeEquivalentTo(originalBookingActivityCreatedEvents.Select(ob => ob.Content.ActivityId)); container.Dispose(); }