public static Tuple <ISubscriber, SubscriptionBuilder> AddEmptyDefaultSubscribtion(this ISubscriber subscriber)
        {
            var builder       = SubscriptionBuilder.Create();
            var emptyconsumer = new DoNothingConsumer <object>();

            builder.AddDefaultSubscription(() => emptyconsumer);
            return(new Tuple <ISubscriber, SubscriptionBuilder>(subscriber, builder));
        }
        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();
        }
Ejemplo n.º 3
0
        public static Tuple <ISubscriber, SubscriptionBuilder> AddDefaultSubscribtion <TEvent>(
            this ISubscriber subscriber,
            Func <IntegrationEvent <TEvent>, Task> consumer,
            Func <IntegrationEvent <TEvent>, Exception, Task> deadLetterCallback = null) where TEvent : class
        {
            var builder = SubscriptionBuilder.Create().AddDefaultSubscription(consumer, deadLetterCallback);

            return(new Tuple <ISubscriber, SubscriptionBuilder>(subscriber, builder));
        }
        public static Tuple <ISubscriber, SubscriptionBuilder> AddSubscription <TEvent>(
            this ISubscriber subscriber,
            string eventType,
            Func <IntegrationEvent <TEvent>, Task> consumer,
            Func <IntegrationEvent <TEvent>, Exception, Task> deadLetterCallback = null) where TEvent : class
        {
            var lambdaConsumer = new LambdaConsumer <TEvent>(consumer);
            var builder        = SubscriptionBuilder.Create().AddSubscription(eventType, () => lambdaConsumer, deadLetterCallback);

            return(new Tuple <ISubscriber, SubscriptionBuilder>(subscriber, builder));
        }
        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();
        }
Ejemplo n.º 6
0
        public async Task SubscribeAsync()
        {
            Subscriber = await _subscriberFactory.CreateSubscriberAsync(
                $"assert_queue_{Guid.NewGuid().ToString().Replace("-", "_")}",
                _routingKey, 1);

            var subscriptionBuilder = SubscriptionBuilder.Create();

            foreach (var eventType in _eventTypes.Distinct())
            {
                subscriptionBuilder.AddSubscription(eventType, () => this);
            }
            Subscriber.Subscribe(subscriptionBuilder.Build());
        }
Ejemplo n.º 7
0
        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);
            }
        }
Ejemplo n.º 8
0
        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);
            }
        }
Ejemplo n.º 9
0
        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();
            }
        }
Ejemplo n.º 10
0
        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();
        }
Ejemplo n.º 11
0
        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);
        }
Ejemplo n.º 12
0
        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 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_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();
        }
Ejemplo n.º 15
0
        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 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();
        }
Ejemplo n.º 17
0
        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_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();
        }
Ejemplo n.º 19
0
        static void Main(string[] args)
        {
            Console.WriteLine("Subscriber started to work.");
            var configurationBuilder = new ConfigurationBuilder()
                                       .AddJsonFile("appsettings.json", false, true);
            var configuration = configurationBuilder.Build();

            var containerBuilder = new ContainerBuilder();

            containerBuilder.RegisterModule(new PubSubRabbitmqModule(configuration));
            var container = containerBuilder.Build();

            SerilogInitializer.Initialize();

            var maxretrycount = int.Parse(configuration["maxretrycount"]);

            //all the entitites creation
            var dynamicObjectSubscriberFactory =
                container.Resolve <ISubscriberFactory>();
            ISubscriber sharingHandlerSubscriber =
                dynamicObjectSubscriberFactory.CreateSubscriberAsync("sharingruleshandler"
                                                                     , new List <string> {
                "*.table.create.*"
            },
                                                                     maxretrycount).Result;

            IConsumer <JObject> sharingHandlerConsumer =
                new ChangeTrackerTableCreateConsumer();

            sharingHandlerSubscriber.Subscribe(SubscriptionBuilder.Create().AddDefaultSubscription(() => sharingHandlerConsumer).Build());

            //typed consumer
            var         bookingCreatedSubscriberFactory = container.Resolve <ISubscriberFactory>();
            ISubscriber typedSubscriber =
                bookingCreatedSubscriberFactory.CreateSubscriberAsync("typedbookingcreatedconsumer", new List <string> {
                "*.table.create.*"
            },
                                                                      maxretrycount).Result;
            IConsumer <BookingCreated> typedConsumer = new TypedConsumer();

            typedSubscriber.Subscribe(SubscriptionBuilder.Create().AddDefaultSubscription(() => typedConsumer).Build());

            //relationship creation entitites
            var relationshipCreatedSubscriberFactory =
                container.Resolve <ISubscriberFactory>();
            ISubscriber bpmRelationshipCreateSubscriber =
                relationshipCreatedSubscriberFactory.CreateSubscriberAsync("bpmRelationshipCreateHandler",
                                                                           new List <string> {
                "*.table.create.relationship"
            }, maxretrycount).Result;

            IConsumer <RelationshipCreated> bpmRelationshipCreateConsumer = new ChangeTrackerTableCreateRelationshipBpmConsumer();

            bpmRelationshipCreateSubscriber.Subscribe(
                SubscriptionBuilder
                .Create()
                .AddDefaultSubscription(() => bpmRelationshipCreateConsumer)
                .Build());

            //all the entities creation. 2 different handlers for 2 different event types.
            ISubscriber forDemultiplexerConsumerSubscriber =
                dynamicObjectSubscriberFactory
                .CreateSubscriberAsync("DemultiplexerRelationshipAndBookingHandler",
                                       new List <string> {
                "*.table.create.*"
            }, maxretrycount).Result;

            var changeTrackerTableCreateRelationshipBpmConsumer =
                new ChangeTrackerTableCreateRelationshipBpmConsumer();
            var changeTrackerTableCreateConsumer =
                new ChangeTrackerTableCreateConsumer();


            forDemultiplexerConsumerSubscriber.Subscribe(
                SubscriptionBuilder
                .Create()
                .AddSubscription <RelationshipCreated>("relationshipcreated",
                                                       () => changeTrackerTableCreateRelationshipBpmConsumer)
                .AddSubscription("bookingcreated", () => changeTrackerTableCreateConsumer)
                .AddDefaultSubscription(() => new UnknownEventTypeConsumer())
                .Build());


            Console.WriteLine("Press button to exit");
            string exit = Console.ReadLine();

            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();
        }
Ejemplo n.º 21
0
        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);
        }
Ejemplo n.º 22
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
            });
        }
Ejemplo n.º 23
0
        static async Task <int> Main(string[] args)
        {
            Console.WriteLine("Test trackable Subscriber Host started to work.");
            var configurationBuilder = new ConfigurationBuilder()
                                       .AddJsonFile("appsettings.json", false, true);
            var configuration = configurationBuilder.Build();

            var containerBuilder = new ContainerBuilder();

            containerBuilder.RegisterModule(new PubSubRabbitmqModule(configuration));
            containerBuilder.RegisterModule(new PubSubExtensionModule());
            var container = containerBuilder.Build();

            SerilogInitializer.Initialize();

            var trackerFactory =
                container.Resolve <ITrackerFactory>();

            //constants
            string trackerName                 = "servicecontroller";
            string activityGeneratorName       = "activitygenerator";
            string emailsignatureName          = "emailsignature";
            string taggerName                  = "tagger";
            string activitygeneratorroutingkey = "exchangecollector.create.email";
            string emailsignatureroutingkey    = "changetracker.table.create.activity";
            string taggeroutingkey             = "changetracker.table.create.activity";
            string exchangeeventtype           = "email.created";
            string changetrackereventtype      = "activity.create";

            //Let's create tracking subscriber that tracks processing events from activity generator and email signature
            var serviceController = await trackerFactory.CreateTrackerAsync(trackerName, true,
                                                                            new List <string>() { activityGeneratorName, emailsignatureName }, 0, 1);

            var subscriberFactory = container.Resolve <ISubscriberFactory>();

            //Let's create activity generator and email signature parser whose messages' processing we want to track
            var activitygenerator = await subscriberFactory.CreateSubscriberAsync(activityGeneratorName, true,
                                                                                  new List <string> {
                activitygeneratorroutingkey
            }, 0, 1, true);

            var emailsignatureparser = await subscriberFactory.CreateSubscriberAsync(emailsignatureName, true,
                                                                                     new List <string> {
                emailsignatureroutingkey
            }, 0, 1, true);

            var activityGeneratorConsumer =
                new ActivityGeneratorConsumer();
            var emailSignatureParserConsumer =
                new EmailSignatureParserConsumer();

            activitygenerator.Subscribe(
                SubscriptionBuilder
                .Create()
                .AddSubscription(exchangeeventtype,
                                 () => activityGeneratorConsumer)
                .Build());

            emailsignatureparser.Subscribe(
                SubscriptionBuilder
                .Create()
                .AddSubscription(changetrackereventtype,
                                 () => emailSignatureParserConsumer)
                .Build());

            //Let's create tagger. We are not going to track its message processing. Tagger will recieve the same messages as Email Signature Parser will do.
            var taggerConsumer =
                new TaggerConsumer();

            var tagger = await subscriberFactory.CreateSubscriberAsync(taggerName,
                                                                       new List <string> {
                taggeroutingkey
            }, 0, 1, false);

            tagger.Subscribe(
                SubscriptionBuilder
                .Create()
                .AddSubscription(changetrackereventtype,
                                 () => taggerConsumer)
                .Build());

            //Let's process events sent to the tracking queue
            var trackerConsumer =
                new TrackerConsumer();


            serviceController.Subscribe(
                SubscriptionBuilder
                .Create()
                .AddSubscription <string>(exchangeeventtype,
                                          () => trackerConsumer)
                .AddSubscription <string>(changetrackereventtype,
                                          () => trackerConsumer)
                .Build(),
                SubscriptionBuilder
                .Create()
                .AddSubscription <DeadLetterEventDescriptor <EmailCreated> >(exchangeeventtype,
                                                                             () => trackerConsumer)
                .AddSubscription <DeadLetterEventDescriptor <ActivityCreated> >(changetrackereventtype,
                                                                                () => trackerConsumer)
                .Build());

            //Let's publish something
            var publisher = container.Resolve <IPublisher>();

            while (true)
            {
                Console.WriteLine("Press the appropriate button to publish the event: (e) - email created, (a) - activity created");
                string input = Console.ReadLine();
                if (input == "e")
                {
                    EmailCreated emailCreated =
                        new EmailCreated()
                    {
                        email = "*****@*****.**" + DateTime.Now.Minute, pathtos3 = "emails\\" + Guid.NewGuid()
                    };

                    var emailCreatedIntegrationEvent = new IntegrationEvent <EmailCreated>()
                    {
                        CorrelationId = Guid.NewGuid(),
                        Content       = emailCreated,
                        EventType     = exchangeeventtype
                    };

                    Console.WriteLine($"The email created event with correlation id {emailCreatedIntegrationEvent.CorrelationId} is going to be published");

                    await publisher.PublishEventAsync(emailCreatedIntegrationEvent,
                                                      activitygeneratorroutingkey);
                }

                if (input == "a")
                {
                    ActivityCreated activityCreated =
                        new ActivityCreated()
                    {
                        subject = "email subject" + DateTime.Now.Minute, accountid = Guid.NewGuid().ToString(),
                        id      = Guid.NewGuid().ToString(), type = "email"
                    };

                    var acivtityCreatedIntegrationEvent = new IntegrationEvent <ActivityCreated>()
                    {
                        Content   = activityCreated,
                        EventType = changetrackereventtype
                    };

                    Console.WriteLine($"The activity created event with correlation id {acivtityCreatedIntegrationEvent.CorrelationId} is going to be published");

                    await publisher.PublishEventAsync(acivtityCreatedIntegrationEvent,
                                                      emailsignatureroutingkey);
                }
            }
        }