public async Task ConsumeAsync_DeadLetterMesssageIsProvided_OriginalMessageIsSentToSubscriberQueue() { //prepare var publisherMock = new Mock <IPublisher>(); string subscriberQueueName = "subscriber"; IntegrationEvent <DeadLetterEventDescriptor <JObject> > deadLetterIntegrationEvent = JsonConvert.DeserializeObject <IntegrationEvent <DeadLetterEventDescriptor <JObject> > >(_serializedMessage); IntegrationEvent <JObject> originalMessage = null; publisherMock.Setup(x => x.PublishDirectEventAsync( It.IsAny <IntegrationEvent <JObject> >(), subscriberQueueName, true)) .Returns <IntegrationEvent <JObject>, string, bool>( (integrationEvent, subscriberName, persistant) => { originalMessage = integrationEvent; return(Task.CompletedTask); }); var deadLetterReloader = new DeadLetterReloader <JObject>(publisherMock.Object, subscriberQueueName); //act await deadLetterReloader.ConsumeAsync(deadLetterIntegrationEvent); //check originalMessage.ShouldBeEquivalentTo(deadLetterIntegrationEvent.Content.Original); }
public async void NotifyAboutDeadLetterAsync_NotNullDeadLetterCallbackFuncIsProvided_CallbackIsInvoked() { //prepare IntegrationEvent <BookingCreated> expectedFirstIntegrationEvent = null; Exception expectedFirstException = null; IntegrationEvent <BookingCreated> expectedSecondIntegrationEvent = null; Exception expectedSecondException = null; int count = 0; Func <IntegrationEvent <BookingCreated>, Exception, Task> deadLetterCallbackFunc = (bookingCreatedEvent, exception) => { if (count == 0) { expectedFirstIntegrationEvent = bookingCreatedEvent; expectedFirstException = exception; count = count + 1; } else { expectedSecondIntegrationEvent = bookingCreatedEvent; expectedSecondException = exception; } return(Task.CompletedTask); }; ISubscription subscription = new Subscription <BookingCreated>(null, deadLetterCallbackFunc); IntegrationEvent <BookingCreated> shouldRaiseArgumentNullExceptionIntegrationEvent = new IntegrationEvent <BookingCreated>(new BookingCreated { BookingName = "Coca Cola" }, "bookingcreatedeventtype"); IntegrationEvent <BookingCreated> shouldRaiseInvalidOperationExceptionIntegrationEvent = new IntegrationEvent <BookingCreated>(new BookingCreated { BookingName = "Apple" }, "bookingcreatedeventtype"); string serializedShouldRaiseArgumentNullExceptionIntegrationEvent = JsonConvert.SerializeObject(shouldRaiseArgumentNullExceptionIntegrationEvent); string serializedShouldRaiseInvalidOperationExceptionIntegrationEvent = JsonConvert.SerializeObject(shouldRaiseInvalidOperationExceptionIntegrationEvent); ArgumentNullException argumentNullException = new ArgumentNullException("ArgumentNullException"); InvalidOperationException invalidOperationException = new InvalidOperationException("InvalidOperationException"); //act await subscription.NotifyAboutDeadLetterAsync(serializedShouldRaiseArgumentNullExceptionIntegrationEvent, argumentNullException); await subscription.NotifyAboutDeadLetterAsync(serializedShouldRaiseInvalidOperationExceptionIntegrationEvent, invalidOperationException); //check expectedFirstException.Should().Be(argumentNullException); expectedSecondException.Should().Be(invalidOperationException); expectedFirstIntegrationEvent.ShouldBeEquivalentTo(shouldRaiseArgumentNullExceptionIntegrationEvent); expectedSecondIntegrationEvent.ShouldBeEquivalentTo(shouldRaiseInvalidOperationExceptionIntegrationEvent); }
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_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(); }