public void IsSubscribed_ShouldCallDataService_WhenNoError() { // Arrange var subscription = new SubscriptionBuilder() .Build(); mockDataService.Setup(ds => ds.IsSubscribed( subscription.PortalId, subscription.UserId, subscription.SubscriptionTypeId, subscription.ObjectKey, subscription.ModuleId, subscription.TabId)).Returns(SubscriptionDataReaderMockHelper.CreateEmptySubscriptionReader()).Verifiable(); //Act subscriptionController.IsSubscribed(subscription); // Assert mockDataService.Verify(ds => ds.IsSubscribed( subscription.PortalId, subscription.UserId, subscription.SubscriptionTypeId, subscription.ObjectKey, subscription.ModuleId, subscription.TabId), Times.Once); }
public void AddSubscription_ShouldCallDataService_WhenNoError() { // Arrange var subscription = new SubscriptionBuilder() .Build(); mockDataService.Setup(ds => ds.AddSubscription( subscription.UserId, subscription.PortalId, subscription.SubscriptionTypeId, subscription.ObjectKey, subscription.Description, subscription.ModuleId, subscription.TabId, subscription.ObjectData)).Verifiable(); //Act subscriptionController.AddSubscription(subscription); // Assert mockDataService.Verify(ds => ds.AddSubscription( subscription.UserId, subscription.PortalId, subscription.SubscriptionTypeId, subscription.ObjectKey, subscription.Description, subscription.ModuleId, subscription.TabId, subscription.ObjectData), Times.Once); }
/// <summary> /// Adds an event handler to the subscription, adding the specified retry policy /// </summary> /// <param name="builder">Subscription builder</param> /// <param name="retryPolicy">Polly retry policy</param> /// <typeparam name="THandler">Event handler type</typeparam> /// <returns></returns> public static SubscriptionBuilder AddEventHandlerWithRetries <THandler>( this SubscriptionBuilder builder, IAsyncPolicy retryPolicy ) where THandler : class, IEventHandler => builder.AddCompositionEventHandler <THandler, PollyEventHandler>( h => new PollyEventHandler(h, retryPolicy) );
public void IsSubscribed_ShouldReturnFalse_WhenUserDoesNotHavePermissionOnTheSubscription() { // Arrange var subscription = new SubscriptionBuilder() .Build(); var subscriptionCollection = new[] { subscription }; mockDataService.Setup(ds => ds.IsSubscribed( subscription.PortalId, subscription.UserId, subscription.SubscriptionTypeId, subscription.ObjectKey, It.IsAny <int>(), It.IsAny <int>())).Returns(SubscriptionDataReaderMockHelper.CreateSubscriptionReader(subscriptionCollection)); subscriptionSecurityController .Setup(ssc => ssc.HasPermission(It.IsAny <Subscription>())).Returns(false); //Act var isSubscribed = subscriptionController.IsSubscribed(subscription); // Assert Assert.AreEqual(false, isSubscribed); }
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 SubscriptionBusServiceBuilder Configure(SubscriptionBusServiceBuilder builder) { SubscriptionBuilder subscriptionBuilder = _configurator.Configure(); builder.AddSubscriptionBuilder(subscriptionBuilder); return(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(); }
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 SubscriptionBuilder <TSubscription, TOptions> UseCheckpointStore <TSubscription, TOptions, T>( this SubscriptionBuilder <TSubscription, TOptions> builder ) where T : class, ICheckpointStore where TSubscription : EventStoreCatchUpSubscriptionBase <TOptions> where TOptions : CatchUpSubscriptionOptions { builder.Services.TryAddSingleton <T>(); return(builder.AddParameterMap <ICheckpointStore, T>()); }
/// <summary> /// Adds an event handler to the subscription, adding the specified retry policy /// </summary> /// <param name="builder">Subscription builder</param> /// <param name="getHandler">Function to construct the handler</param> /// <param name="retryPolicy">Polly retry policy</param> /// <typeparam name="THandler">Event handler type</typeparam> /// <returns></returns> public static SubscriptionBuilder AddEventHandlerWithRetries <THandler>( this SubscriptionBuilder builder, Func <IServiceProvider, THandler> getHandler, IAsyncPolicy retryPolicy ) where THandler : class, IEventHandler => builder.AddCompositionEventHandler( getHandler, h => new PollyEventHandler(h, retryPolicy) );
//////////////////////////////////////////////////////////////// //// PUBLIC OPERATIONS //////////////////////////////////////////////////////////////// /// <summary> /// Creates a subscription with the specified parameters. /// </summary> /// <param name="parameters">The parameters.</param> /// <returns></returns> public SubscriptionResponse Create(IDictionary <string, string> parameters) { SubscriptionRequest request = base.CreateBaseRequest <SubscriptionRequest>(ServerType.RecurringPayment, parameters); SubscriptionBuilder builder = new SubscriptionBuilder(request); request.Entity = builder.Entity; return(this.recurringPaymentService.CreateSubscription(request)); }
public void AddSubscription_ShouldThrowArgumentOutOfRangeException_WhenSubscriptionSubscriptionTypePropertyIsNegative() { // Arrange var subscription = new SubscriptionBuilder() .WithSubscriptionTypeId(-1) .Build(); //Act, Assert Assert.Throws <ArgumentOutOfRangeException>(() => subscriptionController.AddSubscription(subscription)); }
public void AddSubscription_ShouldThrowArgumentNullException_WhenSubscriptionObjectKeyIsNull() { // Arrange var subscription = new SubscriptionBuilder() .WithObjectKey(null) .Build(); //Act, Assert Assert.Throws <ArgumentNullException>(() => subscriptionController.AddSubscription(subscription)); }
public static SubscriptionBuilder AddDefaultSubscription <TEvent>( this SubscriptionBuilder subscriptionBuilder, Func <IntegrationEvent <TEvent>, Task> consumer, Func <IntegrationEvent <TEvent>, Exception, Task> deadLetterCallback = null) where TEvent : class { var lambdaConsumer = new LambdaConsumer <TEvent>(consumer); subscriptionBuilder.AddDefaultSubscription(() => lambdaConsumer, deadLetterCallback); return(subscriptionBuilder); }
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(); }
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()); }
/// <summary> /// Build a subscription using common options /// </summary> /// <typeparam name="TPayload">The type of object to listen for</typeparam> /// <param name="messageBus">The message bus</param> /// <param name="build">Lambda function to setup the subscription builder.</param> /// <returns>The subscription token which, when disposed, cancels the subscription.</returns> public static IDisposable Subscribe <TPayload>(this IPubSubBus messageBus, Action <ITopicSubscriptionBuilder <TPayload> > build) { Assert.ArgumentNotNull(messageBus, nameof(messageBus)); Assert.ArgumentNotNull(build, nameof(build)); var builder = new SubscriptionBuilder <TPayload>(messageBus, messageBus.WorkerPool); build(builder); var subscription = builder.BuildSubscription(); var token = messageBus.Subscribe(builder.Topics, subscription); return(builder.WrapToken(token)); }
/// <summary> /// Creates a new instance of <see cref="IMessagingBus"/>. /// </summary> /// <returns> /// The created instance of <see cref="IMessagingBus"/> /// </returns> public IMessagingBus BuildSubscribers() { IMessagingConfig config = MessagingConfig.Build(); config.Validate(); ILoggerFactory loggerFactory = ServiceResolver.ResolveService <ILoggerFactory>(); JustSayingBus bus = CreateBus(config, loggerFactory); IAwsClientFactoryProxy proxy = CreateFactoryProxy(); IVerifyAmazonQueues creator = new AmazonQueueCreator(proxy, loggerFactory); SubscriptionBuilder.Configure(bus, ServiceResolver, creator, proxy, loggerFactory); return(bus); }
public void Build_A_Raw_Subscription() { var collectionName = "testCollection"; new SubscriptionBuilder(_db.NotificationService) .Collection <Model>(collectionName) .Raw .As <ISubscriptionBuilderBase>() .Subscription .Collection .Should() .Be(collectionName); new SubscriptionBuilder(_db.NotificationService) .Collection <Model>(null) .Raw .As <ISubscriptionBuilderBase>() .Subscription .Collection .Should() .BeNull(); var sub = new SubscriptionBuilder(_db.NotificationService) .Collection <Model>(collectionName) .Raw .As <ISubscriptionBuilderBase>() .Subscription; sub.Collection.Should().Be(collectionName); var castedSub = sub.As <CollectionRawSubscription <Model> >(); castedSub.Collection.Should().Be(collectionName); var builder = new CollectionRawSubscriptionBuilder <Model>(_db.NotificationService, castedSub); // before subscribing castedSub.Observer.Should().BeNull(); builder.Subscribe(listObj => { }); // after subscribing castedSub.Observer.Should().NotBeNull(); }
public async Task Subscriber_SeveralNetworkDisconnected_CallbackDelegateRunOnce() { //prepare IConfiguration configuration = InitializeConfiguration(); const int maxRetryCount = 1; const int maxPrefetchCount = 1; using (IContainer container = ConfigurationHelper.ConfigureContainer(configuration)) { //create Subscriber var testEntitySubscriberFactory = container.Resolve <ISubscriberFactory>(); var subscriberName = $"Publiser_TemporaryQueue.testSubscriber_{Guid.NewGuid()}"; var numberOfRuns = 0; ISubscriber subscriber = await testEntitySubscriberFactory .CreateSubscriberAsync(subscriberName, () => { numberOfRuns++; }, new List <string> { "*.entity.create.testEntity", }, maxRetryCount, maxPrefetchCount); // create Subscriber subscriber.Subscribe(SubscriptionBuilder.Create() .AddSubscription("testEntityCreated", () => (IConsumer <string>)null) .Build()); var managementClient = InitializeManagementClient(configuration); const int disconnectedNum = 5; for (int i = 0; i < disconnectedNum; i++) { await CloseRabbitConnection(managementClient); await Task.Delay(500); } numberOfRuns.Should().Be(1); } }
public static IServiceCollection AddSubscription <T, TOptions>( this IServiceCollection services, string subscriptionId, Action <SubscriptionBuilder <T, TOptions> > configureSubscription ) where T : EventSubscription <TOptions> where TOptions : SubscriptionOptions { Ensure.NotNull(configureSubscription); var builder = new SubscriptionBuilder <T, TOptions>( Ensure.NotNull(services), Ensure.NotEmptyString(subscriptionId) ); configureSubscription(builder); services.TryAddSingleton <ISubscriptionHealth, SubscriptionHealthCheck>(); if (typeof(IMeasuredSubscription).IsAssignableFrom(typeof(T))) { services.AddSingleton(GetGapMeasure); } return(services .AddSubscriptionBuilder(builder) .AddSingleton(sp => GetBuilder(sp).ResolveSubscription(sp)) .AddSingleton <IHostedService>( sp => new SubscriptionHostedService( GetBuilder(sp).ResolveSubscription(sp), sp.GetService <ISubscriptionHealth>(), sp.GetService <ILoggerFactory>() ) )); SubscriptionBuilder <T, TOptions> GetBuilder(IServiceProvider sp) => sp.GetSubscriptionBuilder <T, TOptions>(subscriptionId); GetSubscriptionGap GetGapMeasure(IServiceProvider sp) { var subscription = GetBuilder(sp).ResolveSubscription(sp) as IMeasuredSubscription; return(subscription !.GetMeasure()); } }
public async Task Subscriber_NetworkDisconnected_CallbackExecuted() { //prepare IConfiguration configuration = InitializeConfiguration(); const int subscriberNum = 5; var disconnectedEventFired = new bool[subscriberNum]; const int maxRetryCount = 1; const int maxPrefetchCount = 1; using (IContainer container = ConfigurationHelper.ConfigureContainer(configuration)) { //create Subscriber var testEntitySubscriberFactory = container.Resolve <ISubscriberFactory>(); for (int i = 0; i < subscriberNum; i++) { var index = i; ISubscriber subscriber = await testEntitySubscriberFactory .CreateSubscriberAsync($"Publiser_TemporaryQueue.testSubscriber_{Guid.NewGuid()}", () => { disconnectedEventFired[index] = true; }, new List <string> { "*.entity.create.testEntity", }, maxRetryCount, maxPrefetchCount); // create Subscriber subscriber.Subscribe(SubscriptionBuilder.Create() .AddSubscription("testEntityCreated", () => (IConsumer <string>)null) .Build()); } var managementClient = InitializeManagementClient(configuration); await CloseRabbitConnection(managementClient); await Task.Delay(100); disconnectedEventFired.ShouldAllBeEquivalentTo(true); } }
public void DeleteSubscriptionType_ShouldNotCallDeleteSubscriptionDataService_WhenSubscriptionDoesNotExist() { // Arrange var subscription = new SubscriptionBuilder() .Build(); mockDataService.Setup(ds => ds.IsSubscribed( subscription.PortalId, subscription.UserId, subscription.SubscriptionTypeId, subscription.ObjectKey, It.IsAny <int>(), It.IsAny <int>())).Returns(SubscriptionDataReaderMockHelper.CreateEmptySubscriptionReader()); //Act subscriptionController.DeleteSubscription(subscription); //Assert mockDataService.Verify(ds => ds.DeleteSubscription(It.IsAny <int>()), Times.Never); }
public void IsSubscribed_ShouldReturnFalse_IfUserIsNotSubscribed() { // Arrange var subscription = new SubscriptionBuilder() .Build(); mockDataService.Setup(ds => ds.IsSubscribed( subscription.PortalId, subscription.UserId, subscription.SubscriptionTypeId, subscription.ObjectKey, It.IsAny <int>(), It.IsAny <int>())).Returns(SubscriptionDataReaderMockHelper.CreateEmptySubscriptionReader()); //Act var isSubscribed = subscriptionController.IsSubscribed(subscription); // Assert Assert.AreEqual(false, isSubscribed); }
public void DeleteSubscriptionType_ShouldCallDeleteSubscriptionDataService_WhenSubscriptionExists() { // Arrange var subscription = new SubscriptionBuilder() .Build(); this.mockDataService.Setup(ds => ds.IsSubscribed( subscription.PortalId, subscription.UserId, subscription.SubscriptionTypeId, subscription.ObjectKey, It.IsAny <int>(), It.IsAny <int>())).Returns(SubscriptionDataReaderMockHelper.CreateSubscriptionReader(new[] { subscription })); this.mockDataService.Setup(ds => ds.DeleteSubscription(It.IsAny <int>())).Verifiable(); // Act this.subscriptionController.DeleteSubscription(subscription); // Assert this.mockDataService.Verify(ds => ds.DeleteSubscription(It.IsAny <int>()), Times.Once); }
public static IServiceCollection AddSubscriptionBuilder <T, TOptions>( this IServiceCollection services, SubscriptionBuilder <T, TOptions> builder ) where T : EventSubscription <TOptions> where TOptions : SubscriptionOptions { if (services.Any(x => x is NamedDescriptor named && named.Name == builder.SubscriptionId)) { throw new InvalidOperationException( $"Existing subscription builder with id {builder.SubscriptionId} already registered" ); } var descriptor = new NamedDescriptor( builder.SubscriptionId, typeof(SubscriptionBuilder <T, TOptions>), builder ); services.Add(descriptor); services.Configure(builder.SubscriptionId, builder.ConfigureOptions); return(services); }
public async Task Subscriber_NetworkDisconnected_TemporaryQueueIsDeleted() { //prepare IConfiguration configuration = InitializeConfiguration(); const int maxRetryCount = 1; const int maxPrefetchCount = 1; using (IContainer container = ConfigurationHelper.ConfigureContainer(configuration)) { //create Subscriber var testEntitySubscriberFactory = container.Resolve <ISubscriberFactory>(); var subscriberName = $"Publiser_TemporaryQueue.testSubscriber_{Guid.NewGuid()}"; ISubscriber subscriber = await testEntitySubscriberFactory .CreateSubscriberAsync(subscriberName, () => { }, new List <string> { "*.entity.create.testEntity", }, maxRetryCount, maxPrefetchCount); // create Subscriber subscriber.Subscribe(SubscriptionBuilder.Create() .AddSubscription("testEntityCreated", () => (IConsumer <string>)null) .Build()); var managementClient = InitializeManagementClient(configuration); await CloseRabbitConnection(managementClient); await Task.Delay(100); var queuExists = await CheckQueueExists(managementClient, subscriberName); queuExists.Should().BeFalse(); } }
public void AddSubscription_ShouldFilledUpTheSubscriptionIdPropertyOfTheInputSubscriptionEntity_WhenNoError() { // Arrange const int expectedSubscriptionId = 12; var subscription = new SubscriptionBuilder() .Build(); mockDataService.Setup(ds => ds.AddSubscription( subscription.UserId, subscription.PortalId, subscription.SubscriptionTypeId, subscription.ObjectKey, subscription.Description, subscription.ModuleId, subscription.TabId, subscription.ObjectData)).Returns(expectedSubscriptionId); //Act subscriptionController.AddSubscription(subscription); // Assert Assert.AreEqual(expectedSubscriptionId, subscription.SubscriptionId); }
public void AddSubscriptionBuilder(SubscriptionBuilder builder) { _builders.Add(builder); }
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 }); }