예제 #1
0
            public async Task Handle(BookingCreated notification, CancellationToken cancellationToken)
            {
                var booking = notification.Booking;

                var customer = await _context
                               .Customers
                               .Include(x => x.CustomerLocations)
                               .ThenInclude(x => x.Location)
                               .SingleAsync(x => x.CustomerId == booking.CustomerId);

                var shippingBooking = new ShipmentBooking()
                {
                    BookingId = booking.BookingId
                };

                var shipment = new Shipment()
                {
                    Type = ShipmentType.Delivery,
                };

                var customerLocation = customer.CustomerLocations
                                       .SingleOrDefault(x => x.Location.Type == LocationType.Delivery ||
                                                        x.Location.Type == LocationType.DeliveryPickUp);

                if (customerLocation != null)
                {
                    shipment.LocationId = customerLocation.Location.LocationId;
                }

                shipment.ShipmentBookings.Add(shippingBooking);

                await _context.Shipments.AddAsync(shipment);

                await _context.SaveChangesAsync(cancellationToken);
            }
        public async void HandleSuccessAsync(bool explicitAcknowledgments,
                                             bool storedeadletter)
        {
            //prepare
            MessageProperties messageProperties = new MessageProperties();

            BookingCreated bookingCreated = new BookingCreated {
                BookingName = "test"
            };
            string bookingCreatedEventType = "bookingCreatedEventType";
            IntegrationEvent <BookingCreated> integrationEvent = new IntegrationEvent <BookingCreated>(bookingCreated, bookingCreatedEventType);
            var message = JsonConvert.SerializeObject(integrationEvent);
            var body    = Encoding.UTF8.GetBytes(message);

            ExecutionHandlingStrategy executionHandlingStrategy = new ExecutionHandlingStrategy(_subscriberName, _easyNetQPublisher,
                                                                                                _maxRetry, _modelNamingConventionController.Object, explicitAcknowledgments, _publisher.Object, storedeadletter);

            _modelNamingConventionController.Setup(x => x.GetTrackingMessageEventType(bookingCreatedEventType))
            .Returns((string eventType) => string.Concat("ok.", eventType));

            _modelNamingConventionController.Setup(x => x.GetTrackingRoutingKey(_subscriberName))
            .Returns((string subscriberName) => string.Concat("ok.", subscriberName));

            //Tracking flow
            IntegrationEvent <string> actualTrackingMessage = null;
            string actualTrackingMessageRouting             = string.Empty;
            bool   actualPersistantMode = false;

            _publisher.Setup(x => x.PublishEventAsync(It.IsAny <IntegrationEvent <string> >(), It.IsAny <string>(), true))
            .Returns(Task.FromResult(true))
            .Callback <IntegrationEvent <string>, string, bool>(
                (trackingMessage, routing, persistantMode) =>
            {
                actualTrackingMessage        = trackingMessage;
                actualTrackingMessageRouting = routing;
                actualPersistantMode         = persistantMode;
            });

            //act
            await executionHandlingStrategy.HandleSuccessAsync(integrationEvent);

            //check
            if (explicitAcknowledgments == false)
            {
                //check, that No messages for tracking are sent.
                _publisher.Verify(v => v.PublishEventAsync(It.IsAny <IntegrationEvent <string> >(), It.IsAny <string>(), It.IsAny <bool>()), Times.Never);
            }
            else
            {
                _publisher.Verify(v => v.PublishEventAsync(It.IsAny <IntegrationEvent <string> >(), It.IsAny <string>(), It.IsAny <bool>()), Times.Once);

                actualTrackingMessageRouting.Should().Be(string.Concat("ok.", _subscriberName));
                actualPersistantMode.Should().BeTrue();
                actualTrackingMessage.EventType.Should()
                .Be(string.Concat("ok.", bookingCreatedEventType));
                actualTrackingMessage.CorrelationId.Should().Be(integrationEvent.CorrelationId);
                actualTrackingMessage.Content.Should().BeEmpty();
            }
        }
예제 #3
0
 public void Apply(BookingCreated dEvent)
 {
     this.Rooms             = dEvent.Rooms;
     this.BookingStatus     = dEvent.BookingStatus;
     this.NumberOfOccupents = dEvent.NumberOfOccupents;
     this.DaysBooked        = dEvent.DaysBooked;
     this.CheckInDate       = dEvent.CheckInDate;
     this.DayBooked         = dEvent.DayBooked;
 }
예제 #4
0
        public async Task <bool> CreateBooking(BookingCreateInput input)
        {
            var AggregateId    = new Guid();
            var bookingCreated = new BookingCreated
            {
                AggregateId = AggregateId,
                DateAdded   = DateTime.Now,
                Version     = 0,
                Data        = await BuildCreateBookingEventData()
            };
            await _eventStore.Push(bookingCreated);

            return(true);
        }
예제 #5
0
        //Hanlders , We are building the booking history here
        private IEnumerable <EventBase> Handle(BookingCreated e)
        {
            OrderHistory bookingCreated = new OrderHistory();

            bookingCreated.BookingOrderId = e.BookingId;
            bookingCreated.DateTime       = e.Date.ToString();
            bookingCreated.Origion        = e.Origin;
            bookingCreated.Destination    = e.Destination;
            bookingCreated.Description    = e.Description;
            bookingCreated.OrderState     = typeof(BookingCreated).ToString();

            orderHistory.Add(bookingCreated);

            return(new EventBase[] { e });
        }
예제 #6
0
        public static Booking Create(IEnumerable <long> roomIds, int numberOfOccupents, int daysBooked, DateTime checkInDate, string user)
        {
            var booking = new Booking();

            var bookingCreatedEvent = new BookingCreated(
                roomIds,
                BookingStatus.Booked,
                numberOfOccupents,
                daysBooked,
                checkInDate,
                DateTime.Now,
                user
                );

            booking.ApplyEvent(bookingCreatedEvent);

            return(booking);
        }
예제 #7
0
        public async Task Handle(BookingAddIntegrationEvent eventMsg)
        {
            List <EventBase> events = new List <EventBase>();

            if (eventMsg.Id != Guid.Empty)
            {
                try
                {
                    Track trackings = await _trackingContext.GetEventVersion(eventMsg.BookingId);

                    if (trackings == null)
                    {
                        trackings = new Track();
                    }

                    var messageType = _assemblyTypes
                                      .Where(t => t.Name.Contains("BookingCreated")).FirstOrDefault().
                                      Name.ToString();

                    BookingCreated bookingCreated = new
                                                    BookingCreated(eventMsg.BookingId, string.Empty, eventMsg.Id
                                                                   , messageType, eventMsg.CreationDate, eventMsg.Origin, eventMsg.Destination);


                    events.AddRange(trackings.BookingAdd(bookingCreated));
                    trackings.Version = trackings.OriginalVersion + 1;

                    await _trackingContext.SaveTrackingAsync(eventMsg.BookingId, trackings.OriginalVersion,
                                                             trackings.Version, events);
                }
                catch (Exception e)
                {
                    var ExceptionTelemetry = new ExceptionTelemetry(e);
                    ExceptionTelemetry.Properties.Add("BookingAddIntegrationEvent", eventMsg.BookingId);
                    ExceptionTelemetry.SeverityLevel = SeverityLevel.Critical;

                    telemetry.TrackException(ExceptionTelemetry);

                    throw;//Make sure event bus abaondon the message
                }
            }
        }
예제 #8
0
        public async Task UpdateBookingModelInCache(Message msg)
        {
            RedisCacheService rCache   = new RedisCacheService();
            List <EventBase>  events   = new List <EventBase>();
            Track             tracking = new Track();
            var bookingId = string.Empty;
            List <OrderHistory> trackingHistory = new List <OrderHistory>();

            try
            {
                if (msg.Label == "BookingAdd")
                {
                    BookingAddIntegrationEvent eventMsg = JsonConvert.DeserializeObject <BookingAddIntegrationEvent>(Encoding.UTF8.GetString(msg.Body));

                    string messageType = "BookingCreated";

                    BookingCreated bookingCreated = new
                                                    BookingCreated(eventMsg.BookingId, string.Empty, eventMsg.Id
                                                                   , messageType, eventMsg.CreationDate, eventMsg.Origin, eventMsg.Destination);

                    bookingId = eventMsg.BookingId;
                    tracking.BookingAdd(bookingCreated);
                }
                else if (msg.Label == "OrderPicked")
                {
                    OrderPickedIntegrationEvent eventMsg = JsonConvert.DeserializeObject <OrderPickedIntegrationEvent>(Encoding.UTF8.GetString(msg.Body));

                    string messageType = "OrderPicked";

                    OrderPicked orderPicked = new
                                              OrderPicked(eventMsg.BookingId, eventMsg.Description, eventMsg.Id
                                                          , messageType, eventMsg.CreationDate);

                    bookingId = eventMsg.BookingId;
                    tracking.OrderPicked(orderPicked);
                }

                else if (msg.Label == "OrderTransit")
                {
                    OrderTransitIntegrationEvent eventMsg = JsonConvert.DeserializeObject <OrderTransitIntegrationEvent>(Encoding.UTF8.GetString(msg.Body));

                    string messageType = "OrderInTransit";

                    OrderInTransit orderInTransit = new
                                                    OrderInTransit(eventMsg.BookingId, eventMsg.Description, eventMsg.Id
                                                                   , messageType, eventMsg.CreationDate);


                    bookingId = eventMsg.BookingId;
                    tracking.OrderInTransit(orderInTransit);
                }
                else if (msg.Label == "OrderDelivered")
                {
                    OrderDeliveredIntegrationEvent eventMsg = JsonConvert.DeserializeObject <OrderDeliveredIntegrationEvent>(Encoding.UTF8.GetString(msg.Body));

                    string messageType = "OrderDelivered";

                    OrderDelivered orderDelivered = new
                                                    OrderDelivered(eventMsg.BookingId, eventMsg.Description, eventMsg.Id
                                                                   , messageType, eventMsg.CreationDate, eventMsg.SignedBy);


                    bookingId = eventMsg.BookingId;
                    tracking.OrderDelivered(orderDelivered);
                }
                else if (msg.Label == "PaymentProcessed")
                {
                    PaymentProcessedIntegrationEvent eventMsg = JsonConvert.DeserializeObject <PaymentProcessedIntegrationEvent>(Encoding.UTF8.GetString(msg.Body));

                    string messageType = "PaymentProcessed";

                    string description = string.Empty;
                    if (eventMsg.PaymentStatus == PaymetStatus.Completed)
                    {
                        description = "Payment Done";
                    }
                    else if (eventMsg.PaymentStatus == PaymetStatus.Canceled)
                    {
                        description = "Payment Failed";
                    }
                    else if (eventMsg.PaymentStatus == PaymetStatus.Pending)
                    {
                        description = "Payment Pending";
                    }

                    PaymentProcessed eventPaymentProcessed = new
                                                             PaymentProcessed(eventMsg.BookingOrderId, description, eventMsg.Id, messageType, eventMsg.CreationDate);


                    bookingId = eventMsg.BookingOrderId;
                    tracking.PaymentProcessed(eventPaymentProcessed);
                }

                //If  Booking ID Exists
                if (!string.IsNullOrEmpty(bookingId))
                {
                    if (!string.IsNullOrEmpty(rCache.Get(bookingId)))
                    {
                        trackingHistory = JsonConvert.DeserializeObject <List <OrderHistory> >(rCache.Get(bookingId));
                    }

                    //Append new event to old events
                    trackingHistory.AddRange(tracking.orderHistory);

                    //Serialze the result
                    var result = JsonConvert.SerializeObject(trackingHistory);
                    await rCache.Remove(bookingId);

                    //Update the Cache
                    if (!string.IsNullOrEmpty(result))
                    {
                        await rCache.Save(bookingId, result);
                    }
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
예제 #9
0
 public IEnumerable <EventBase> BookingAdd(BookingCreated e)
 {
     return(HandleEvent(e));
 }
예제 #10
0
        public async void PublishDirectEventAsync_MessageMustBeSerializedAndCorrectlyRouted(bool persistant, byte deliveryMode)
        {
            //prepare

            var mockBus = new Mock <IAdvancedBus>();

            var mockExchange = new Mock <IExchange>();

            var mockModelNamingConventionController = new Mock <IModelNamingConventionController>();

            var subscriberName = "subscriber";
            var routingKey     = string.Concat("direct.", subscriberName);;

            IExchange         actualExchange   = null;
            string            actualRouting    = string.Empty;
            bool              actualMandatory  = true;
            MessageProperties actualProperties = null;

            byte[] actualMsg = null;

            mockModelNamingConventionController.Setup(x => x.GetDirectRoutingKey(subscriberName)).Returns(routingKey);

            mockBus.Setup(x => x.PublishAsync(mockExchange.Object, routingKey, false,
                                              It.IsAny <MessageProperties>(), It.IsAny <byte[]>()))
            .Returns((IExchange exchange, string routing, bool mandatory,
                      MessageProperties properties, byte[] msg) =>
                     { return(Task.FromResult(true)); })
            .Callback <IExchange, string, bool, MessageProperties, byte[]>(
                (exchange, routing, mandatory, properties, msg) =>
            {
                actualExchange   = exchange;
                actualRouting    = routing;
                actualMandatory  = mandatory;
                actualProperties = properties;
                actualMsg        = msg;
            });

            mockBus.Setup(x => x.ExchangeDeclareAsync("exchangename", ExchangeType.Topic,
                                                      false, true, false, false, null, false))
            .Returns((string exchangename, string exchanegType,
                      bool passive, bool durable, bool autoDelete, bool internalflag,
                      string alternateExchange, bool delayed) =>
                     { return(Task.FromResult(mockExchange.Object)); });

            //act
            EasyNetQPublisher easyNetQPublisher =
                new EasyNetQPublisher(mockBus.Object, "exchangename", mockModelNamingConventionController.Object);

            BookingCreated bookingCreated =
                new BookingCreated()
            {
                BookingName = string.Concat("Microsoft Sale",
                                            Guid.NewGuid().ToString())
            };

            var bookingCreatedIntegrationEvent = new IntegrationEvent <BookingCreated>()
            {
                Content   = bookingCreated,
                EventType = "bookingcreated"
            };
            await easyNetQPublisher.PublishDirectEventAsync(bookingCreatedIntegrationEvent,
                                                            subscriberName, persistant);



            //check
            actualExchange.Should().Be(mockExchange.Object);
            actualRouting.Should().Be(routingKey);
            actualMandatory.Should().Be(false);
            actualProperties.ShouldBeEquivalentTo(new MessageProperties()
            {
                DeliveryMode = deliveryMode
            });
            var messagejson  = JsonConvert.SerializeObject(bookingCreatedIntegrationEvent);
            var messagebytes = Encoding.UTF8.GetBytes(messagejson);

            actualMsg.ShouldBeEquivalentTo(messagebytes);
        }
예제 #11
0
        public async void Subscribe_DiscardEventException_WhenProcessed_ExceptionShouldBeThrown()
        {
            //prepare
            var content = new BookingCreated()
            {
                BookingName = _bookingName
            };
            IntegrationEvent <BookingCreated> integrationEvent =
                new IntegrationEvent <BookingCreated>
            {
                CorrelationId     = Guid.NewGuid(),
                EventCreationDate = DateTime.UtcNow,
                EventId           = Guid.NewGuid(),
                EventType         = _bookingEventType,
                Version           = _version,
                Content           = content
            };

            var messagebytes = SerializeEvent(integrationEvent);

            EventEmulator eventEmulator = null;

            _mockBus.Setup(x => x.Consume(_mockQueue.Object,
                                          It.IsAny <Func <byte[], MessageProperties, MessageReceivedInfo, Task> >(),
                                          It.IsAny <Action <IConsumerConfiguration> >()))
            .Returns((IQueue queue, Func <byte[],
                                          MessageProperties, MessageReceivedInfo, Task> func,
                      Action <IConsumerConfiguration> configure) =>
            {
                eventEmulator = new EventEmulator(func);
                return(_consumerDisposable.Object);
            });


            DiscardEventException discardEventException = new DiscardEventException();
            var mockSubscription = new Mock <ISubscription>();

            mockSubscription.Setup(x => x.InvokeAsync(Encoding.UTF8.GetString(messagebytes)))
            .Returns <string>(
                (serilizedmessage) =>
            {
                return(Task.FromException <DiscardEventException>(discardEventException));
            });


            Dictionary <string, ISubscription> subscriptions = new Dictionary <string, ISubscription> {
                { "bookingcreated", mockSubscription.Object }
            };

            _subsciptionSelector.Setup(x => x.Select(subscriptions, "bookingcreated"))
            .Returns((IDictionary <string, ISubscription> subs, string eventType) => mockSubscription.Object);

            MessageProperties       messageProperties             = new MessageProperties();
            MessageExecutionContext actualMessageExecutionContext = null;

            _errorHandlingStrategy.Setup(x => x.HandleErrorAsync(It.IsAny <MessageExecutionContext>()))
            .Returns <MessageExecutionContext>(
                (messageExecutionContext) =>
            {
                actualMessageExecutionContext = messageExecutionContext;
                return(Task.FromException <DiscardEventException>(messageExecutionContext.Exception));
            });

            _easyNetQSubscriber.Subscribe(subscriptions);

            //Act

            await eventEmulator.Execute(messagebytes, messageProperties, null);

            //check
            eventEmulator.RaisedException.GetType().Should().Be(typeof(DiscardEventException));

            _successHandlingStrategy.Verify(x => x.HandleSuccessAsync(It.IsAny <IntegrationEvent>()), Times.Never);
            _errorHandlingStrategy.Verify(x => x.HandleErrorAsync(It.IsAny <MessageExecutionContext>()), Times.Once);
            actualMessageExecutionContext.BodyBytes.ShouldBeEquivalentTo(messagebytes);
            actualMessageExecutionContext.Exception.Should().Be(eventEmulator.RaisedException);
            actualMessageExecutionContext.MessageProperties.Should().Be(messageProperties);
            actualMessageExecutionContext.IntergrationEventParsingResult.ShouldBeEquivalentTo(DefaultIntergrationEventParser.Parse(messagebytes));
            actualMessageExecutionContext.SerializedMessage.Should().Be(Encoding.UTF8.GetString(messagebytes));
            actualMessageExecutionContext.DeadLetterIntegrationEvent.Should().BeNull();
            actualMessageExecutionContext.Subscription.Should().Be(mockSubscription.Object);
        }
예제 #12
0
        public async void Subscribe_ChangeTheSubscriber_AppropriateConsumerShouldBeUsed()
        {
            //prepare
            var content = new BookingCreated()
            {
                BookingName = _bookingName
            };
            IntegrationEvent <BookingCreated> integrationEvent =
                new IntegrationEvent <BookingCreated>()
            {
                CorrelationId     = Guid.NewGuid(),
                EventCreationDate = DateTime.UtcNow,
                EventId           = Guid.NewGuid(),
                EventType         = _bookingEventType,
                Version           = _version,
                Content           = content
            };

            var messagebytes = SerializeEvent(integrationEvent);

            EventEmulator eventEmulator = null;

            _mockBus.Setup(x => x.Consume(_mockQueue.Object,
                                          It.IsAny <Func <byte[], MessageProperties, MessageReceivedInfo, Task> >(),
                                          It.IsAny <Action <IConsumerConfiguration> >()))
            .Returns((IQueue queue, Func <byte[],
                                          MessageProperties, MessageReceivedInfo, Task> func,
                      Action <IConsumerConfiguration> configure) =>
            {
                eventEmulator = new EventEmulator(func);
                return(_consumerDisposable.Object);
            });


            var mockSubscription = new Mock <ISubscription>();

            mockSubscription.Setup(x => x.InvokeAsync(Encoding.UTF8.GetString(messagebytes))).Returns(Task.FromResult(true));

            Dictionary <string, ISubscription> subscriptions = new Dictionary <string, ISubscription> {
                { "bookingcreated", mockSubscription.Object }
            };

            _subsciptionSelector.Setup(x => x.Select(subscriptions, "bookingcreated"))
            .Returns((IDictionary <string, ISubscription> subs, string eventType) => mockSubscription.Object);

            _easyNetQSubscriber.Subscribe(subscriptions);


            MessageProperties messageProperties = new MessageProperties();
            await eventEmulator.Execute(messagebytes, messageProperties, null);


            //Act
            _easyNetQSubscriber.UnSubscribe();

            var mockSubscription2 = new Mock <ISubscription>();

            mockSubscription2.Setup(x => x.InvokeAsync(Encoding.UTF8.GetString(messagebytes))).Returns(Task.FromResult(true));

            Dictionary <string, ISubscription> subscriptions2 = new Dictionary <string, ISubscription> {
                { "bookingcreated", mockSubscription2.Object }
            };

            _subsciptionSelector.Setup(x => x.Select(subscriptions2, "bookingcreated"))
            .Returns((IDictionary <string, ISubscription> subs, string eventType) => mockSubscription2.Object);

            _easyNetQSubscriber.Subscribe(subscriptions2);


            await eventEmulator.Execute(messagebytes, messageProperties, null);


            //check

            eventEmulator.RaisedException.Should().BeNull();

            mockSubscription.Verify(x => x.InvokeAsync(Encoding.UTF8.GetString(messagebytes)), Times.Once);
            mockSubscription2.Verify(x => x.InvokeAsync(Encoding.UTF8.GetString(messagebytes)), Times.Once);
        }
        public async void HandleErrorAsync_ExceptionThatShouldBeCatchedANDAttemptNumberN_MessageShouldBeSentToAppropriateRetryQueue(bool explicitAcknowledgments,
                                                                                                                                    int numberOfAttempt, bool storedeadletter)
        {
            //prepare
            MessageProperties messageProperties = new MessageProperties();

            if (numberOfAttempt != 0)
            {
                messageProperties.Headers = new Dictionary <string, object>();
                messageProperties.Headers["retrycount"] = numberOfAttempt;
            }


            BookingCreated bookingCreated = new BookingCreated {
                BookingName = "test"
            };
            string bookingCreatedEventType = "bookingCreatedEventType";
            IntegrationEvent <BookingCreated> integrationEvent = new IntegrationEvent <BookingCreated>(bookingCreated, bookingCreatedEventType);
            var       message   = JsonConvert.SerializeObject(integrationEvent);
            var       body      = Encoding.UTF8.GetBytes(message);
            Exception exception = new IOException("IOException");

            ExecutionHandlingStrategy executionHandlingStrategy = new ExecutionHandlingStrategy(_subscriberName, _easyNetQPublisher,
                                                                                                _maxRetry, _modelNamingConventionController.Object, explicitAcknowledgments, _publisher.Object, storedeadletter);

            string retryRoutingKey = string.Concat("retry.", numberOfAttempt + 1, ".", _subscriberName);

            _modelNamingConventionController.Setup(x => x.GetRetryRoutingKey(_subscriberName, numberOfAttempt + 1))
            .Returns((string subscribername, int retryindex) => retryRoutingKey);



            string            actualRouting    = string.Empty;
            MessageProperties actualProperties = null;

            byte[]    actualMsg      = null;
            IExchange actualExchange = null;

            _mockBus.Setup(x => x.ExchangeDeclareAsync(_exchangeName, ExchangeType.Topic,
                                                       false, true, false, false, null, false))
            .Returns((string exchangename, string exchanegType,
                      bool passive, bool durable, bool autoDelete, bool internalflag,
                      string alternateExchange, bool delayed) =>
                     { return(Task.FromResult(_mockExchange.Object)); });

            _mockBus.Setup(x => x.PublishAsync(It.IsAny <IExchange>(), It.IsAny <string>(), false, It.IsAny <MessageProperties>(), It.IsAny <byte[]>()))
            .Returns((IExchange exchange, string routing, bool mandatory,
                      MessageProperties properties, byte[] msg) =>
                     { return(Task.FromResult(true)); })
            .Callback <IExchange, string, bool, MessageProperties, byte[]>(
                (exchange, routing, mandatory, properties, msg) =>
            {
                actualExchange   = exchange;
                actualRouting    = routing;
                actualProperties = properties;
                actualMsg        = msg;
            });


            //act
            Mock <ISubscription>    mockedSubscription      = new Mock <ISubscription>();
            MessageExecutionContext messageExecutionContext =
                new MessageExecutionContext(body, messageProperties, null)
            {
                Exception         = exception,
                SerializedMessage = message,
                Subscription      = mockedSubscription.Object,
                IntergrationEventParsingResult = null,
                DeadLetterIntegrationEvent     = null
            };
            await executionHandlingStrategy.HandleErrorAsync(messageExecutionContext);


            //check
            actualRouting.Should().Be(retryRoutingKey);
            actualMsg.Should().BeEquivalentTo(body);
            (int.Parse(actualProperties.Headers["retrycount"].ToString())).Should().Be(numberOfAttempt + 1);
            actualExchange.Should().Be(_mockExchange.Object);

            _publisher.Verify(m => m.PublishEventAsync(It.IsAny <IntegrationEvent <string> >(), It.IsAny <string>(), It.IsAny <bool>()), Times.Never);
            mockedSubscription.Verify(s => s.NotifyAboutDeadLetterAsync(It.IsAny <string>(), It.IsAny <Exception>()), Times.Never);
            mockedSubscription.Verify(s => s.InvokeAsync(It.IsAny <string>()), Times.Never);
        }
        public async void HandleErrorAsync_ExceptionThatShouldBeCatchedANDLastAttempt_MessageShouldBeSentToAppropriateDeadLetterQueue(bool explicitAcknowledgments,
                                                                                                                                      bool storedeadletter)
        {
            //prepare
            MessageProperties messageProperties = new MessageProperties();

            messageProperties.Headers = new Dictionary <string, object>();
            messageProperties.Headers["retrycount"] = _maxRetry;

            BookingCreated bookingCreated = new BookingCreated {
                BookingName = "test"
            };
            string bookingCreatedEventType = "bookingCreatedEventType";
            IntegrationEvent <BookingCreated> integrationEvent = new IntegrationEvent <BookingCreated>(bookingCreated, bookingCreatedEventType);
            var       message   = JsonConvert.SerializeObject(integrationEvent);
            var       body      = Encoding.UTF8.GetBytes(message);
            Exception exception = new IOException("IOException");

            ExecutionHandlingStrategy executionHandlingStrategy = new ExecutionHandlingStrategy(_subscriberName, _easyNetQPublisher,
                                                                                                _maxRetry, _modelNamingConventionController.Object, explicitAcknowledgments, _publisher.Object, storedeadletter);

            _mockBus.Setup(x => x.ExchangeDeclareAsync(_exchangeName, ExchangeType.Topic,
                                                       false, true, false, false, null, false))
            .Returns((string exchangename, string exchanegType,
                      bool passive, bool durable, bool autoDelete, bool internalflag,
                      string alternateExchange, bool delayed) =>
                     { return(Task.FromResult(_mockExchange.Object)); });


            _modelNamingConventionController.Setup(x => x.GetDeadLetterQueueMessageEventType(bookingCreatedEventType))
            .Returns((string eventType) => string.Concat("deadletter.", eventType));

            _modelNamingConventionController.Setup(x => x.GetDeadLetterQueueRoutingKey(_subscriberName))
            .Returns((string subscriberName) => string.Concat("deadletter.", subscriberName));

            //Main flow
            string            actualRouting    = string.Empty;
            MessageProperties actualProperties = null;

            byte[]    actualMsg      = null;
            IExchange actualExchange = null;

            _mockBus.Setup(x => x.PublishAsync(It.IsAny <IExchange>(), It.IsAny <string>(), false, It.IsAny <MessageProperties>(), It.IsAny <byte[]>()))
            .Returns((IExchange exchange, string routing, bool mandatory,
                      MessageProperties properties, byte[] msg) =>
                     { return(Task.FromResult(true)); })
            .Callback <IExchange, string, bool, MessageProperties, byte[]>(
                (exchange, routing, mandatory, properties, msg) =>
            {
                actualExchange   = exchange;
                actualRouting    = routing;
                actualProperties = properties;
                actualMsg        = msg;
            });
            //END Main flow

            //Tracking flow
            IntegrationEvent <DeadLetterEventDescriptor <JObject> > actualTrackingMessage = null;
            string actualTrackingMessageRouting = string.Empty;
            bool   actualPersistantMode         = false;

            _publisher.Setup(x => x.PublishEventAsync(It.IsAny <IntegrationEvent <DeadLetterEventDescriptor <JObject> > >(), It.IsAny <string>(), true))
            .Returns(Task.FromResult(true))
            .Callback <IntegrationEvent <DeadLetterEventDescriptor <JObject> >, string, bool>(
                (trackingMessage, routing, persistantMode) =>
            {
                actualTrackingMessage        = trackingMessage;
                actualTrackingMessageRouting = routing;
                actualPersistantMode         = persistantMode;
            });

            //END Tracking flow


            //act
            Mock <ISubscription>    mockedSubscription      = new Mock <ISubscription>();
            MessageExecutionContext messageExecutionContext =
                new MessageExecutionContext(body, messageProperties, null)
            {
                Exception         = exception,
                SerializedMessage = message,
                Subscription      = mockedSubscription.Object,
                IntergrationEventParsingResult = null,
                DeadLetterIntegrationEvent     = null
            };

            await executionHandlingStrategy.HandleErrorAsync(messageExecutionContext);

            //check
            var expectedDeadLetterEventDescriptor =
                new DeadLetterEventDescriptor <JObject>
            {
                CountOfAttempts  = _maxRetry,
                LastAttemptError = exception.ToString(),
                Original         = JsonConvert.DeserializeObject <IntegrationEvent <JObject> >(message)
            };

            var expectedDeadletterqueueevent = new IntegrationEvent <DeadLetterEventDescriptor <JObject> >
            {
                CorrelationId = integrationEvent.CorrelationId,
                EventType     = string.Concat("deadletter.", bookingCreatedEventType),
                Content       = expectedDeadLetterEventDescriptor
            };

            //Check publishing dead letter message
            if (storedeadletter)
            {
                var actuaDeadLetterQueuelSerializedMessage = Encoding.UTF8.GetString(actualMsg);
                IntegrationEvent <DeadLetterEventDescriptor <JObject> > actualDeadLetterQueueIntegrationEvent =
                    JsonConvert.DeserializeObject <IntegrationEvent <DeadLetterEventDescriptor <JObject> > >(actuaDeadLetterQueuelSerializedMessage);


                actualDeadLetterQueueIntegrationEvent.CorrelationId.Should().Be(expectedDeadletterqueueevent.CorrelationId);
                actualDeadLetterQueueIntegrationEvent.Content.ShouldBeEquivalentTo(expectedDeadletterqueueevent.Content);
                actualDeadLetterQueueIntegrationEvent.EventType.Should()
                .Be(expectedDeadletterqueueevent.EventType);

                actualRouting.Should().Be(string.Concat("deadletter.", _subscriberName));
                actualExchange.Should().Be(_mockExchange.Object);
                actualProperties.DeliveryMode.Should().Be(2);//persistant delivery mode
            }
            else
            {
                _mockBus.Verify(v => v.PublishAsync(It.IsAny <IExchange>(), It.IsAny <string>(), false, It.IsAny <MessageProperties>(), It.IsAny <byte[]>()), Times.Never);
            }

            //Check Subsciption notification
            mockedSubscription.Verify(s => s.NotifyAboutDeadLetterAsync(messageExecutionContext.SerializedMessage, messageExecutionContext.Exception), Times.Once);
            mockedSubscription.Verify(s => s.InvokeAsync(It.IsAny <string>()), Times.Never);

            //Check Tracking flow
            if (explicitAcknowledgments == false)
            {
                //check, that No deadletter message for tracking is sent.
                _publisher.Verify(v => v.PublishEventAsync(It.IsAny <IntegrationEvent <DeadLetterEventDescriptor <JObject> > >(), It.IsAny <string>(), It.IsAny <bool>()), Times.Never);
            }
            else
            {
                //check, that deadltter message for tracking is equal to the one sent to the deadletter queue. Routing key must be the same
                _publisher.Verify(v => v.PublishEventAsync(It.IsAny <IntegrationEvent <DeadLetterEventDescriptor <JObject> > >(), It.IsAny <string>(), It.IsAny <bool>()), Times.Once);

                actualTrackingMessageRouting.Should().Be(string.Concat("deadletter.", _subscriberName));
                actualPersistantMode.Should().BeTrue();
                actualTrackingMessage.CorrelationId.Should().Be(expectedDeadletterqueueevent.CorrelationId);
                actualTrackingMessage.Content.ShouldBeEquivalentTo(expectedDeadletterqueueevent.Content);
                actualTrackingMessage.EventType.Should()
                .Be(expectedDeadletterqueueevent.EventType);
            }
        }
예제 #15
0
 public void Apply(BookingCreated e)
 {
     created = true;
 }