Example #1
0
        public async Task OnConnected_SendingMessage_MessageSent()
        {
            Host.ConfigureServices(
                services => services
                .AddLogging()
                .AddSilverback()
                .UseModel()
                .WithConnectionToMessageBroker(options => options.AddMockedMqtt())
                .AddMqttEndpoints(
                    endpoints => endpoints
                    .Configure(
                        config => config
                        .WithClientId("e2e-test")
                        .ConnectViaTcp("e2e-mqtt-broker"))
                    .AddOutbound <IIntegrationEvent>(
                        endpoint => endpoint.ProduceTo(DefaultTopicName))
                    .AddInbound(
                        endpoint => endpoint
                        .ConsumeFrom(DefaultTopicName)))
                .AddScopedBrokerCallbackHandler <SendMessageConnectedCallbackHandler>()
                .AddIntegrationSpyAndSubscriber())
            .Run();

            await AsyncTestingUtil.WaitAsync(() => Helper.Spy.OutboundEnvelopes.Count >= 1);

            Helper.Spy.OutboundEnvelopes.Should().HaveCount(1);
            Helper.Spy.OutboundEnvelopes[0].Message.Should().BeOfType <TestEventOne>();
        }
Example #2
0
        public async Task Abort_WhileAsyncEnumeratingStreams_EnumerationAborted()
        {
            int?count    = null;
            var provider = new MessageStreamProvider <int>();
            var stream   = provider.CreateStream <int>();

            var enumerationTask = Task.Run(
                async() =>
            {
                count = await stream.CountAsync();
            });

            await provider.PushAsync(1);

            await provider.PushAsync(2);

            await provider.PushAsync(3);

            count.Should().BeNull();

            provider.Abort();

            await AsyncTestingUtil.WaitAsync(() => enumerationTask.IsCompleted);

            count.Should().BeNull();
            enumerationTask.Status.Should().Be(TaskStatus.Canceled);
        }
        public async Task StartAsync_WithDbLockManager_OnlyOneTaskIsExecutedSimultaneously()
        {
            bool executed1 = false;
            bool executed2 = false;

            var service1 = new TestRecurringDistributedBackgroundService(stoppingToken =>
            {
                executed1 = true;
                return(Task.CompletedTask);
            }, new DbDistributedLockManager(_servicesProvider));
            await service1.StartAsync(CancellationToken.None);

            await AsyncTestingUtil.WaitAsync(() => executed1);

            var service2 = new TestRecurringDistributedBackgroundService(_ =>
            {
                executed2 = true;
                return(Task.CompletedTask);
            }, new DbDistributedLockManager(_servicesProvider));
            await service2.StartAsync(CancellationToken.None);

            await AsyncTestingUtil.WaitAsync(() => executed2, 100);

            executed1.Should().BeTrue();
            executed2.Should().BeFalse();

            await service1.StopAsync(CancellationToken.None);

            await AsyncTestingUtil.WaitAsync(() => executed2);

            executed2.Should().BeTrue();
        }
Example #4
0
        public async Task PushAsync_WhileEnumerating_BackpressureIsHandled()
        {
            var stream = new MessageStreamEnumerable <int>();

            using var enumerator = stream.GetEnumerator();

            var pushTask1 = stream.PushAsync(new PushedMessage(1, 1));
            var pushTask2 = stream.PushAsync(new PushedMessage(2, 2));
            var pushTask3 = stream.PushAsync(new PushedMessage(3, 3));

            enumerator.MoveNext();

            await Task.Delay(100);

            pushTask1.IsCompleted.Should().BeFalse();

            enumerator.MoveNext();

            await AsyncTestingUtil.WaitAsync(() => pushTask1.IsCompleted);

            pushTask1.IsCompleted.Should().BeTrue();

            await Task.Delay(100);

            pushTask2.IsCompleted.Should().BeFalse();
            pushTask3.IsCompleted.Should().BeFalse();

            enumerator.MoveNext();

            await AsyncTestingUtil.WaitAsync(() => pushTask2.IsCompleted);

            pushTask2.IsCompleted.Should().BeTrue();
            pushTask3.IsCompleted.Should().BeFalse();
        }
        public async Task Publish_MessageStreamProvider_MessagesNotAutomaticallyEnumerated()
        {
            var receivedEnumeratedStreams = 0;

            var streamPublisher = new StreamPublisher(
                PublisherTestsHelper.GetPublisher(
                    builder => builder
                    .AddDelegateSubscriber(
                        (IReadOnlyCollection <IEvent> enumerable) =>
            {
                Interlocked.Increment(ref receivedEnumeratedStreams);
            })
                    .AddDelegateSubscriber(
                        (List <TestEventOne> list) => { Interlocked.Increment(ref receivedEnumeratedStreams); })));

            var streamProvider = new MessageStreamProvider <IEvent>();

            await streamPublisher.PublishAsync(streamProvider);

            await streamProvider.PushAsync(new TestEventOne(), false);

            await streamProvider.PushAsync(new TestEventTwo(), false);

            await streamProvider.CompleteAsync();

            await AsyncTestingUtil.WaitAsync(() => receivedEnumeratedStreams >= 1, TimeSpan.FromMilliseconds(500));

            receivedEnumeratedStreams.Should().Be(0);
        }
Example #6
0
        public async Task Streaming_DisconnectWhileObserving_ObserverCompleted()
        {
            bool completed        = false;
            var  receivedMessages = new ConcurrentBag <TestEventOne>();

            Host.ConfigureServices(
                services => services
                .AddLogging()
                .AddSilverback()
                .AsObservable()
                .UseModel()
                .WithConnectionToMessageBroker(options => options.AddMockedKafka())
                .AddKafkaEndpoints(
                    endpoints => endpoints
                    .Configure(
                        config =>
            {
                config.BootstrapServers = "PLAINTEXT://e2e";
            })
                    .AddOutbound <IIntegrationEvent>(
                        endpoint => endpoint.ProduceTo(DefaultTopicName))
                    .AddInbound(
                        endpoint => endpoint
                        .ConsumeFrom(DefaultTopicName)
                        .Configure(
                            config =>
            {
                config.GroupId = "consumer1";
            })))
                .AddDelegateSubscriber(
                    (IMessageStreamObservable <TestEventOne> observable) =>
                    observable.Subscribe(
                        message => receivedMessages.Add(message),
                        () => completed = true)))
            .Run();

            var publisher = Host.ScopedServiceProvider.GetRequiredService <IEventPublisher>();
            await publisher.PublishAsync(
                new TestEventOne
            {
                Content = "Message 1"
            });

            await publisher.PublishAsync(
                new TestEventOne
            {
                Content = "Message 2"
            });

            await Helper.WaitUntilAllMessagesAreConsumedAsync();

            await AsyncTestingUtil.WaitAsync(() => receivedMessages.Count >= 2);

            receivedMessages.Should().HaveCount(2);

            await Helper.Broker.DisconnectAsync();

            completed.Should().BeTrue();
            DefaultTopic.GetCommittedOffsetsCount("consumer1").Should().Be(2);
        }
        public async Task Publish_MessageStreamProvider_MessagesNotAutomaticallyEnumerated()
        {
            var receivedEnumeratedStreams = 0;

            var serviceProvider = ServiceProviderHelper.GetServiceProvider(
                services => services
                .AddFakeLogger()
                .AddSilverback()
                .AsObservable()
                .AddDelegateSubscriber(
                    (IReadOnlyCollection <IEvent> _) =>
            {
                Interlocked.Increment(ref receivedEnumeratedStreams);
            })
                .AddDelegateSubscriber(
                    (List <TestEventOne> _) => { Interlocked.Increment(ref receivedEnumeratedStreams); }));
            var streamPublisher = serviceProvider.GetRequiredService <IStreamPublisher>();

            var streamProvider = new MessageStreamProvider <IEvent>();

            await streamPublisher.PublishAsync(streamProvider);

            await streamProvider.PushAsync(new TestEventOne(), false);

            await streamProvider.PushAsync(new TestEventTwo(), false);

            await streamProvider.CompleteAsync();

            await AsyncTestingUtil.WaitAsync(
                () => receivedEnumeratedStreams >= 1,
                TimeSpan.FromMilliseconds(500));

            receivedEnumeratedStreams.Should().Be(0);
        }
Example #8
0
        public async Task PartitionEofCallback_PartitionEofEnabled_HandlerInvoked()
        {
            var message = new TestEventOne
            {
                Content = "Hello E2E!"
            };

            Host.ConfigureServices(
                services => services
                .AddLogging()
                .AddSilverback()
                .UseModel()
                .AddSingletonBrokerCallbackHandler <KafkaPartitionEofCallback>()
                .WithConnectionToMessageBroker(
                    options => options
                    .AddMockedKafka(
                        mockedKafkaOptions => mockedKafkaOptions.WithDefaultPartitionsCount(5)))
                .AddKafkaEndpoints(
                    endpoints => endpoints
                    .Configure(
                        config =>
            {
                config.BootstrapServers = "PLAINTEXT://tests";
            })
                    .AddOutbound <IIntegrationEvent>(
                        endpoint => endpoint.ProduceTo(DefaultTopicName))
                    .AddInbound(
                        endpoint => endpoint
                        .ConsumeFrom(DefaultTopicName)
                        .Configure(
                            config =>
            {
                config.GroupId            = "consumer1";
                config.EnablePartitionEof = true;
            })))
                .AddIntegrationSpyAndSubscriber())
            .Run();

            var callbackHandlerKafkaEndOfPartitionReached = (KafkaPartitionEofCallback)Host
                                                            .ScopedServiceProvider
                                                            .GetServices <IBrokerCallback>()
                                                            .First(service => service is KafkaPartitionEofCallback);

            await AsyncTestingUtil.WaitAsync(
                () => callbackHandlerKafkaEndOfPartitionReached.AllPartitionsEofCallbackCount == 5);

            var kafkaTestingHelper = Host.ServiceProvider.GetRequiredService <IKafkaTestingHelper>();

            var publisher = Host.ScopedServiceProvider.GetRequiredService <IEventPublisher>();
            await publisher.PublishAsync(message);

            await kafkaTestingHelper.WaitUntilAllMessagesAreConsumedAsync();

            await AsyncTestingUtil.WaitAsync(
                () => callbackHandlerKafkaEndOfPartitionReached.AllPartitionsEofCallbackCount == 6);

            // There are 5 partitions and one message will be published, so in fact 6 times the end of the partition should be reached
            callbackHandlerKafkaEndOfPartitionReached.AllPartitionsEofCallbackCount.Should().Be(6);
            kafkaTestingHelper.Spy.OutboundEnvelopes.Should().HaveCount(1);
        }
        public async Task Publish_MessageStreamProviderOfEnvelopes_OnlyAutoUnwrapMessagesReceived()
        {
            var receivedEvents = new List <IEvent>();

            var serviceProvider = ServiceProviderHelper.GetServiceProvider(
                services => services
                .AddFakeLogger()
                .AddSilverback()
                .AsObservable()
                .AddDelegateSubscriber(
                    (IMessageStreamObservable <IEvent> observable) =>
            {
                observable.Subscribe(message => receivedEvents.Add(message));
            }));
            var streamPublisher = serviceProvider.GetRequiredService <IStreamPublisher>();

            var streamProvider = new MessageStreamProvider <IEnvelope>();
            await streamPublisher.PublishAsync(streamProvider);

            await streamProvider.PushAsync(new TestEnvelope(new TestEventOne(), false), false);

            await streamProvider.PushAsync(new TestEnvelope(new TestEventTwo()));

            await AsyncTestingUtil.WaitAsync(() => receivedEvents.Count >= 1);

            receivedEvents.Should().HaveCount(1);
            receivedEvents[0].Should().BeOfType <TestEventTwo>();
        }
Example #10
0
        public async Task Abort_WhileEnumerating_EnumerationAborted()
        {
            var completed = false;
            var stream    = new MessageStreamEnumerable <int>();

            using var enumerator = stream.GetEnumerator();

            // ReSharper disable once AccessToDisposedClosure
            var enumerationTask = Task.Run(
                () =>
            {
                enumerator.MoveNext();
                completed = true;
            });

            completed.Should().BeFalse();

            stream.Abort();

            // Give the other thread a chance to exit the MoveNext
            await AsyncTestingUtil.WaitAsync(() => enumerationTask.IsCompleted);

            completed.Should().BeFalse();
            enumerationTask.Status.Should().Be(TaskStatus.Faulted);
            enumerationTask.Exception !.InnerExceptions.First().Should().BeAssignableTo <OperationCanceledException>();
        }
        public async Task PauseAndResume_SimpleTask_ExecutionPausedAndResumed()
        {
            int executions = 0;

            var service = new TestRecurringDistributedBackgroundService(
                _ =>
            {
                executions++;
                return(Task.CompletedTask);
            },
                _serviceProvider.GetRequiredService <DbDistributedLockManager>());
            await service.StartAsync(CancellationToken.None);

            await AsyncTestingUtil.WaitAsync(() => executions > 1);

            executions.Should().BeGreaterThan(0);

            service.Pause();
            await Task.Delay(50);

            var executionsBeforeStop = executions;

            await Task.Delay(500);

            executions.Should().Be(executionsBeforeStop);

            service.Resume();

            await AsyncTestingUtil.WaitAsync(() => executions > executionsBeforeStop);

            executions.Should().BeGreaterThan(executionsBeforeStop);
        }
        public async Task Publish_MessageStreamProviderOfEnvelopes_OnlyAutoUnwrapMessagesReceived()
        {
            var receivedEvents = new List <IEvent>();

            var streamPublisher = new StreamPublisher(
                PublisherTestsHelper.GetPublisher(
                    builder => builder
                    .AddDelegateSubscriber(
                        (IMessageStreamEnumerable <IEvent> enumerable) =>
            {
                foreach (var envelope in enumerable)
                {
                    receivedEvents.Add(envelope);
                }
            })));

            var streamProvider = new MessageStreamProvider <IEnvelope>();
            await streamPublisher.PublishAsync(streamProvider);

            await streamProvider.PushAsync(new TestEnvelope(new TestEventOne(), false), false);

            await streamProvider.PushAsync(new TestEnvelope(new TestEventTwo()));

            await AsyncTestingUtil.WaitAsync(() => receivedEvents.Count >= 1);

            receivedEvents.Should().HaveCount(1);
            receivedEvents[0].Should().BeOfType <TestEventTwo>();
        }
Example #13
0
        public async Task CompleteAsync_WhileEnumerating_EnumerationCompleted()
        {
            var completed = false;
            var stream    = new MessageStreamEnumerable <int>();

            using var enumerator = stream.GetEnumerator();

            // The next MoveNext reaches the end of the enumerable
            // ReSharper disable once AccessToDisposedClosure
            Task.Run(
                () =>
            {
                enumerator.MoveNext();
                completed = true;
            }).FireAndForget();

            completed.Should().BeFalse();

            await stream.CompleteAsync();

            // Give the other thread a chance to exit the MoveNext
            await AsyncTestingUtil.WaitAsync(() => completed);

            completed.Should().BeTrue();
        }
        public async Task Publish_MessageStreamProvidePlusBehavior_MessagesReceived()
        {
            var receivedStreams = 0;
            var receivedEvents  = 0;

            var testBehavior    = new TestBehavior();
            var serviceProvider = ServiceProviderHelper.GetServiceProvider(
                services => services
                .AddFakeLogger()
                .AddSilverback()
                .AddDelegateSubscriber(
                    (IMessageStreamEnumerable <IEvent> enumerable) =>
            {
                Interlocked.Increment(ref receivedStreams);
                foreach (var dummy in enumerable)
                {
                    Interlocked.Increment(ref receivedEvents);
                }
            })
                .AddSingletonBehavior(testBehavior));
            var streamPublisher = serviceProvider.GetRequiredService <IStreamPublisher>();

            var streamProvider = new MessageStreamProvider <IEvent>();

            await streamPublisher.PublishAsync(streamProvider);

            await streamProvider.PushAsync(new TestEventOne());

            await streamProvider.PushAsync(new TestEventTwo());

            await AsyncTestingUtil.WaitAsync(() => receivedEvents >= 2);

            receivedStreams.Should().Be(1);
            receivedEvents.Should().Be(2);
        }
        public async Task Publish_StreamProviderOfEnvelopes_OnlyMatchingUnwrappedMessagesReceived()
        {
            var receivedStreamsOfOnes = 0;
            var receivedTestEventOnes = 0;
            var receivedStreamsOfTwos = 0;
            var receivedTestEventTwos = 0;

            var serviceProvider = ServiceProviderHelper.GetServiceProvider(
                services => services
                .AddFakeLogger()
                .AddSilverback()
                .AddDelegateSubscriber(
                    (IMessageStreamEnumerable <TestEventOne> enumerable) =>
            {
                Interlocked.Increment(ref receivedStreamsOfOnes);
                foreach (var dummy in enumerable)
                {
                    Interlocked.Increment(ref receivedTestEventOnes);
                }
            })
                .AddDelegateSubscriber(
                    (IMessageStreamEnumerable <TestEventTwo> enumerable) =>
            {
                Interlocked.Increment(ref receivedStreamsOfTwos);
                foreach (var dummy in enumerable)
                {
                    Interlocked.Increment(ref receivedTestEventTwos);
                }
            }));
            var streamPublisher = serviceProvider.GetRequiredService <IStreamPublisher>();

            var stream = new MessageStreamProvider <IEnvelope>();
            await streamPublisher.PublishAsync(stream);

            await stream.PushAsync(new TestEnvelope(new TestEventTwo()));

            await stream.PushAsync(new TestEnvelope(new TestEventTwo()));

            await AsyncTestingUtil.WaitAsync(() => receivedTestEventTwos >= 2);

            receivedStreamsOfOnes.Should().Be(0);
            receivedTestEventOnes.Should().Be(0);
            receivedStreamsOfTwos.Should().Be(1);
            receivedTestEventTwos.Should().Be(2);

            await stream.PushAsync(new TestEnvelope(new TestEventOne()));

            await stream.PushAsync(new TestEnvelope(new TestEventTwo()));

            await stream.PushAsync(new TestEnvelope(new TestEventOne()));

            await stream.PushAsync(new TestEnvelope(new TestEventTwo()));

            await AsyncTestingUtil.WaitAsync(() => receivedTestEventTwos >= 4);

            receivedStreamsOfOnes.Should().Be(1);
            receivedTestEventOnes.Should().Be(2);
            receivedStreamsOfTwos.Should().Be(1);
            receivedTestEventTwos.Should().Be(4);
        }
        public async Task Publish_MessageStreamProvidePlusBehavior_StreamedMessagesReceived()
        {
            var receivedStreams = 0;
            var receivedEvents  = 0;

            var testBehavior    = new TestBehavior();
            var streamPublisher = new StreamPublisher(
                PublisherTestsHelper.GetPublisher(
                    builder => builder
                    .AddDelegateSubscriber(
                        (IMessageStreamEnumerable <IEvent> enumerable) =>
            {
                Interlocked.Increment(ref receivedStreams);
                foreach (var dummy in enumerable)
                {
                    Interlocked.Increment(ref receivedEvents);
                }
            }),
                    new IBehavior[] { testBehavior }));

            var streamProvider = new MessageStreamProvider <IEvent>();

            await streamPublisher.PublishAsync(streamProvider);

            await streamProvider.PushAsync(new TestEventOne());

            await streamProvider.PushAsync(new TestEventTwo());

            await AsyncTestingUtil.WaitAsync(() => receivedEvents >= 2);

            receivedStreams.Should().Be(1);
            receivedEvents.Should().Be(2);
        }
Example #17
0
        public async Task PushAsync_WhileAsyncEnumeratingStream_BackpressureIsHandled()
        {
            var provider   = new MessageStreamProvider <int>();
            var stream     = provider.CreateStream <int>();
            var enumerator = stream.GetAsyncEnumerator();

            var pushTask1 = provider.PushAsync(1);
            var pushTask2 = provider.PushAsync(2);
            var pushTask3 = provider.PushAsync(3);

            await enumerator.MoveNextAsync();

            await Task.Delay(100);

            pushTask1.IsCompleted.Should().BeFalse();

            await enumerator.MoveNextAsync();

            await AsyncTestingUtil.WaitAsync(() => pushTask1.IsCompleted);

            pushTask1.IsCompleted.Should().BeTrue();

            await Task.Delay(100);

            pushTask2.IsCompleted.Should().BeFalse();
            pushTask3.IsCompleted.Should().BeFalse();

            await enumerator.MoveNextAsync();

            await AsyncTestingUtil.WaitAsync(() => pushTask2.IsCompleted);

            pushTask2.IsCompleted.Should().BeTrue();
            pushTask3.IsCompleted.Should().BeFalse();
        }
Example #18
0
        public async Task OnConnected_DefaultSettings_CallbackInvoked()
        {
            var callbackHandler = new FakeConnectedCallbackHandler();

            Host.ConfigureServices(
                services => services
                .AddLogging()
                .AddSilverback()
                .UseModel()
                .WithConnectionToMessageBroker(options => options.AddMockedMqtt())
                .AddMqttEndpoints(
                    endpoints => endpoints
                    .Configure(
                        config => config
                        .WithClientId("e2e-test")
                        .ConnectViaTcp("e2e-mqtt-broker"))
                    .AddOutbound <IIntegrationEvent>(
                        endpoint => endpoint.ProduceTo(DefaultTopicName))
                    .AddInbound(
                        endpoint => endpoint
                        .ConsumeFrom(DefaultTopicName)))
                .AddSingletonBrokerCallbackHandler(callbackHandler)
                .AddIntegrationSpyAndSubscriber())
            .Run();

            await AsyncTestingUtil.WaitAsync(() => callbackHandler.CallsCount > 0);

            callbackHandler.CallsCount.Should().Be(1);
        }
        public async Task Publish_MessageStreamProviderOfEnvelopes_OnlyMatchingUnwrappedMessagesReceived()
        {
            var receivedStreamsOfOnes = 0;
            var receivedTestEventOnes = 0;
            var receivedStreamsOfTwos = 0;
            var receivedTestEventTwos = 0;

            var streamPublisher = new StreamPublisher(
                PublisherTestsHelper.GetPublisher(
                    builder => builder
                    .AddDelegateSubscriber(
                        (IMessageStreamEnumerable <TestEventOne> enumerable) =>
            {
                Interlocked.Increment(ref receivedStreamsOfOnes);
                foreach (var dummy in enumerable)
                {
                    Interlocked.Increment(ref receivedTestEventOnes);
                }
            })
                    .AddDelegateSubscriber(
                        (IMessageStreamEnumerable <TestEventTwo> enumerable) =>
            {
                Interlocked.Increment(ref receivedStreamsOfTwos);
                foreach (var dummy in enumerable)
                {
                    Interlocked.Increment(ref receivedTestEventTwos);
                }
            })));

            var stream = new MessageStreamProvider <IEnvelope>();
            await streamPublisher.PublishAsync(stream);

            await stream.PushAsync(new TestEnvelope(new TestEventTwo()));

            await stream.PushAsync(new TestEnvelope(new TestEventTwo()));

            await AsyncTestingUtil.WaitAsync(() => receivedTestEventTwos >= 2);

            receivedStreamsOfOnes.Should().Be(0);
            receivedTestEventOnes.Should().Be(0);
            receivedStreamsOfTwos.Should().Be(1);
            receivedTestEventTwos.Should().Be(2);

            await stream.PushAsync(new TestEnvelope(new TestEventOne()));

            await stream.PushAsync(new TestEnvelope(new TestEventTwo()));

            await stream.PushAsync(new TestEnvelope(new TestEventOne()));

            await stream.PushAsync(new TestEnvelope(new TestEventTwo()));

            await AsyncTestingUtil.WaitAsync(() => receivedTestEventTwos >= 4);

            receivedStreamsOfOnes.Should().Be(1);
            receivedTestEventOnes.Should().Be(2);
            receivedStreamsOfTwos.Should().Be(1);
            receivedTestEventTwos.Should().Be(4);
        }
        public async Task Publish_MessageStreamProvider_OnlyRequiredStreamsPublished()
        {
            var receivedStreams = 0;

            var serviceProvider = ServiceProviderHelper.GetServiceProvider(
                services => services
                .AddFakeLogger()
                .AddSilverback()
                .AsObservable()
                .AddDelegateSubscriber(
                    (IMessageStreamObservable <IEvent> observable) =>
            {
                Interlocked.Increment(ref receivedStreams);
                observable.Subscribe(_ => { });
            })
                .AddDelegateSubscriber(
                    (IMessageStreamObservable <TestEventOne> observable) =>
            {
                Interlocked.Increment(ref receivedStreams);
                observable.Subscribe(_ => { });
            })
                .AddDelegateSubscriber(
                    (IMessageStreamObservable <TestCommandOne> observable) =>
            {
                Interlocked.Increment(ref receivedStreams);
                observable.Subscribe(_ => { });
            }));
            var streamPublisher = serviceProvider.GetRequiredService <IStreamPublisher>();

            var streamProvider1 = new MessageStreamProvider <IEvent>();
            var streamProvider2 = new MessageStreamProvider <IEvent>();

            await Task.Delay(100);

            receivedStreams.Should().Be(0);

            streamPublisher.Publish(streamProvider1);
            await streamPublisher.PublishAsync(streamProvider2);

            await streamProvider1.PushAsync(new TestEventTwo());

            await Task.Delay(100);

            receivedStreams.Should().Be(1);

            await streamProvider1.PushAsync(new TestEventOne());

            await AsyncTestingUtil.WaitAsync(() => receivedStreams >= 2);

            receivedStreams.Should().Be(2);

            await streamProvider2.PushAsync(new TestEventOne());

            await AsyncTestingUtil.WaitAsync(() => receivedStreams >= 4);

            receivedStreams.Should().Be(4);
        }
Example #21
0
        public async Task DisconnectAsync_WithoutAutoCommit_PendingOffsetsCommitted()
        {
            int receivedMessages = 0;

            Host.ConfigureServices(
                services => services
                .AddLogging()
                .AddSilverback()
                .UseModel()
                .WithConnectionToMessageBroker(options => options.AddMockedKafka())
                .AddKafkaEndpoints(
                    endpoints => endpoints
                    .Configure(
                        config =>
            {
                config.BootstrapServers = "PLAINTEXT://e2e";
            })
                    .AddOutbound <IIntegrationEvent>(
                        endpoint => endpoint.ProduceTo(DefaultTopicName))
                    .AddInbound(
                        endpoint => endpoint
                        .ConsumeFrom(DefaultTopicName)
                        .Configure(
                            config =>
            {
                config.GroupId          = "consumer1";
                config.EnableAutoCommit = false;
                config.CommitOffsetEach = 10;
            })))
                .AddDelegateSubscriber((TestEventOne _) => receivedMessages++))
            .Run();

            var publisher = Host.ScopedServiceProvider.GetRequiredService <IEventPublisher>();
            await publisher.PublishAsync(
                new TestEventOne
            {
                Content = "one"
            });

            await publisher.PublishAsync(
                new TestEventOne
            {
                Content = "two"
            });

            await publisher.PublishAsync(
                new TestEventOne
            {
                Content = "three"
            });

            await AsyncTestingUtil.WaitAsync(() => receivedMessages == 3);

            await Helper.Broker.DisconnectAsync();

            DefaultTopic.GetCommittedOffsetsCount("consumer1").Should().Be(3);
        }
Example #22
0
        public async Task Batch_FromMultiplePartitions_ConcurrentlyConsumed()
        {
            var receivedBatches = new List <List <TestEventOne> >();

            Host.ConfigureServices(
                services => services
                .AddLogging()
                .AddSilverback()
                .UseModel()
                .WithConnectionToMessageBroker(
                    options => options.AddMockedKafka(
                        mockedKafkaOptions => mockedKafkaOptions.WithDefaultPartitionsCount(3)))
                .AddEndpoints(
                    endpoints => endpoints
                    .AddOutbound <IIntegrationEvent>(new KafkaProducerEndpoint(DefaultTopicName))
                    .AddInbound(
                        new KafkaConsumerEndpoint(DefaultTopicName)
            {
                Configuration =
                {
                    GroupId          = "consumer1",
                    EnableAutoCommit = false,
                    CommitOffsetEach = 1
                },
                Batch = new BatchSettings
                {
                    Size = 10
                }
            }))
                .AddDelegateSubscriber(
                    async(IMessageStreamEnumerable <TestEventOne> eventsStream) =>
            {
                var list = new List <TestEventOne>();
                lock (receivedBatches)
                {
                    receivedBatches.Add(list);
                }

                await foreach (var message in eventsStream)
                {
                    list.Add(message);
                }
            }))
            .Run();

            var publisher = Host.ScopedServiceProvider.GetRequiredService <IEventPublisher>();

            for (int i = 1; i <= 10; i++)
            {
                await publisher.PublishAsync(new TestEventOne { Content = $"{i}" });
            }

            await AsyncTestingUtil.WaitAsync(() => receivedBatches.Sum(batch => batch.Count) == 10);

            receivedBatches.Count.Should().BeGreaterThan(1);
            receivedBatches.Sum(batch => batch.Count).Should().Be(10);
        }
        public async Task StatusInfo_PollTimeoutWithAutoRecovery_Reconnected()
        {
            Host.ConfigureServices(
                services => services
                .AddLogging()
                .AddSilverback()
                .UseModel()
                .WithConnectionToMessageBroker(options => options.AddMockedKafka())
                .AddKafkaEndpoints(
                    endpoints => endpoints
                    .Configure(
                        config =>
            {
                config.BootstrapServers = "PLAINTEXT://e2e";
            })
                    .AddOutbound <IIntegrationEvent>(
                        endpoint => endpoint.ProduceTo(DefaultTopicName))
                    .AddInbound(
                        endpoint => endpoint
                        .ConsumeFrom(DefaultTopicName)
                        .Configure(
                            config =>
            {
                config.GroupId            = "consumer1";
                config.EnableAutoRecovery = true;
            })))
                .AddIntegrationSpyAndSubscriber())
            .Run(waitUntilBrokerConnected: false);

            var consumer = (KafkaConsumer)Helper.Broker.Consumers[0];

            await AsyncTestingUtil.WaitAsync(() => consumer.StatusInfo.Status == ConsumerStatus.Ready);

            consumer.StatusInfo.Status.Should().Be(ConsumerStatus.Ready);

            // Simulate a local poll timeout
            var timeoutMonitor = (KafkaConsumerLocalTimeoutMonitor)Host.ServiceProvider
                                 .GetServices <IBrokerCallback>()
                                 .Single(service => service is KafkaConsumerLocalTimeoutMonitor);

            timeoutMonitor.OnConsumerLog(
                new LogMessage(
                    "rdkafka#consumer-1",
                    SyslogLevel.Warning,
                    "MAXPOLL",
                    "[thrd:main]: Application maximum poll interval (10000ms) exceeded by 89ms (adjust max.poll.interval.ms for long-running message processing): leaving group"),
                consumer);

            await AsyncTestingUtil.WaitAsync(() => consumer.StatusInfo.History.Count >= 5);

            consumer.IsConnected.Should().BeTrue();
            consumer.StatusInfo.Status.Should().Be(ConsumerStatus.Ready);
            string.Join("->", consumer.StatusInfo.History.TakeLast(3).Select(change => change.Status))
            .Should().BeEquivalentTo("Disconnected->Connected->Ready");
        }
        public async Task Validation_ThrowException_InvalidMessageNotConsumed()
        {
            bool received = false;

            Host.ConfigureServices(
                services =>
            {
                services
                .AddLogging()
                .AddSilverback()
                .UseModel()
                .WithConnectionToMessageBroker(options => options.AddMockedKafka())
                .AddKafkaEndpoints(
                    endpoints => endpoints
                    .Configure(
                        config =>
                {
                    config.BootstrapServers = "PLAINTEXT://tests";
                })
                    .AddOutbound <IIntegrationEvent>(
                        endpoint => endpoint.ProduceTo(DefaultTopicName))
                    .AddInbound <TestValidationMessage>(
                        endpoint => endpoint
                        .ConsumeFrom(DefaultTopicName)
                        .ValidateMessage(true)
                        .Configure(
                            config =>
                {
                    config.GroupId = "consumer1";
                })))
                .AddDelegateSubscriber(
                    (IInboundEnvelope _) =>
                {
                    received = true;
                })
                .AddIntegrationSpyAndSubscriber();
            })
            .Run();

            var producer = Helper.Broker.GetProducer(DefaultTopicName);

            await producer.ProduceAsync(Encoding.UTF8.GetBytes("{\"String10\": \"1234567890abcd\"}"));

            await Helper.WaitUntilAllMessagesAreConsumedAsync();

            Helper.Spy.OutboundEnvelopes.Should().HaveCount(1);
            Helper.Spy.InboundEnvelopes.Should().HaveCount(0);
            DefaultTopic.GetCommittedOffsetsCount("consumer1").Should().Be(0);
            received.Should().BeFalse();

            await AsyncTestingUtil.WaitAsync(() => Helper.Broker.Consumers[0].IsConnected == false);

            Helper.Broker.Consumers[0].IsConnected.Should().BeFalse();
        }
        public async Task Publish_MessageStreamProvider_OnlyRequiredStreamsPublished()
        {
            var receivedStreams = 0;

            var streamPublisher = new StreamPublisher(
                PublisherTestsHelper.GetPublisher(
                    builder => builder
                    .AddDelegateSubscriber(
                        (IMessageStreamEnumerable <IEvent> enumerable) =>
            {
                Interlocked.Increment(ref receivedStreams);
                var dummy = enumerable.ToList();
            })
                    .AddDelegateSubscriber(
                        (IMessageStreamEnumerable <TestEventOne> enumerable) =>
            {
                Interlocked.Increment(ref receivedStreams);
                var dummy = enumerable.ToList();
            })
                    .AddDelegateSubscriber(
                        (IMessageStreamEnumerable <TestCommandOne> enumerable) =>
            {
                Interlocked.Increment(ref receivedStreams);
                var dummy = enumerable.ToList();
            })));

            var streamProvider1 = new MessageStreamProvider <IEvent>();
            var streamProvider2 = new MessageStreamProvider <IEvent>();

            await Task.Delay(100);

            receivedStreams.Should().Be(0);

            streamPublisher.Publish(streamProvider1);
            await streamPublisher.PublishAsync(streamProvider2);

            await streamProvider1.PushAsync(new TestEventTwo());

            await Task.Delay(100);

            receivedStreams.Should().Be(1);

            await streamProvider1.PushAsync(new TestEventOne());

            await AsyncTestingUtil.WaitAsync(() => receivedStreams >= 2);

            receivedStreams.Should().Be(2);

            await streamProvider2.PushAsync(new TestEventOne());

            await AsyncTestingUtil.WaitAsync(() => receivedStreams >= 4);

            receivedStreams.Should().Be(4);
        }
Example #26
0
        public async Task Inbound_ThrowIfUnhandled_ConsumerStoppedIfMessageIsNotHandled()
        {
            var received = 0;

            Host.ConfigureServices(
                services => services
                .AddLogging()
                .AddSilverback()
                .UseModel()
                .WithConnectionToMessageBroker(options => options.AddMockedKafka())
                .AddKafkaEndpoints(
                    endpoints => endpoints
                    .Configure(
                        config =>
            {
                config.BootstrapServers = "PLAINTEXT://e2e";
            })
                    .AddOutbound <IIntegrationEvent>(
                        endpoint => endpoint.ProduceTo(DefaultTopicName))
                    .AddInbound(
                        endpoint => endpoint
                        .ConsumeFrom(DefaultTopicName)
                        .Configure(
                            config =>
            {
                config.GroupId = "consumer1";
            })
                        .ThrowIfUnhandled()))
                .AddDelegateSubscriber((TestEventOne _) => received++))
            .Run();

            var publisher = Host.ScopedServiceProvider.GetRequiredService <IEventPublisher>();

            await publisher.PublishAsync(
                new TestEventOne
            {
                Content = "Handled message"
            });

            await Helper.WaitUntilAllMessagesAreConsumedAsync();

            received.Should().Be(1);

            await publisher.PublishAsync(
                new TestEventTwo
            {
                Content = "Unhandled message"
            });

            await AsyncTestingUtil.WaitAsync(() => Helper.Broker.Consumers[0].IsConnected == false);

            Helper.Broker.Consumers[0].IsConnected.Should().BeFalse();
        }
Example #27
0
        public async Task PartitionEofCallback_PartitionEofEnabledForMultipleConsumers_HandlerInvoked()
        {
            Host.ConfigureServices(
                services => services
                .AddLogging()
                .AddSilverback()
                .UseModel()
                .AddSingletonBrokerCallbackHandler <KafkaPartitionEofCallback>()
                .WithConnectionToMessageBroker(
                    options => options
                    .AddMockedKafka(
                        mockedKafkaOptions => mockedKafkaOptions.WithDefaultPartitionsCount(5)))
                .AddKafkaEndpoints(
                    endpoints => endpoints
                    .Configure(
                        config =>
            {
                config.BootstrapServers = "PLAINTEXT://tests";
            })
                    .AddOutbound <IIntegrationEvent>(
                        endpoint => endpoint.ProduceTo(DefaultTopicName))
                    .AddInbound(
                        endpoint => endpoint
                        .ConsumeFrom(DefaultTopicName)
                        .Configure(
                            config =>
            {
                config.GroupId            = "consumer1";
                config.EnablePartitionEof = true;
            }))
                    .AddInbound(
                        endpoint => endpoint
                        .ConsumeFrom(DefaultTopicName)
                        .Configure(
                            config =>
            {
                config.GroupId            = "consumer2";
                config.EnablePartitionEof = true;
            })))
                .AddIntegrationSpyAndSubscriber())
            .Run();

            var callbackHandlerKafkaEndOfPartitionReached = (KafkaPartitionEofCallback)Host
                                                            .ScopedServiceProvider
                                                            .GetServices <IBrokerCallback>()
                                                            .First(service => service is KafkaPartitionEofCallback);

            await AsyncTestingUtil.WaitAsync(
                () => callbackHandlerKafkaEndOfPartitionReached.AllPartitionsEofCallbackCount == 10);

            // There are 5 partitions and 2 consumers
            callbackHandlerKafkaEndOfPartitionReached.AllPartitionsEofCallbackCount.Should().Be(10);
        }
Example #28
0
        public async Task StatusInfo_ConsumingAndDisconnecting_StatusHistoryRecorded()
        {
            Host.ConfigureServices(
                services => services
                .AddLogging()
                .AddSilverback()
                .UseModel()
                .WithConnectionToMessageBroker(
                    options => options.AddMockedMqtt(
                        mockedKafkaOptions =>
                        mockedKafkaOptions.DelayConnection(TimeSpan.FromMilliseconds(200))))
                .AddMqttEndpoints(
                    endpoints => endpoints
                    .Configure(
                        config => config
                        .WithClientId("e2e-test")
                        .ConnectViaTcp("e2e-mqtt-broker"))
                    .AddOutbound <IIntegrationEvent>(
                        endpoint => endpoint.ProduceTo(DefaultTopicName))
                    .AddInbound(
                        endpoint => endpoint
                        .ConsumeFrom(DefaultTopicName)))
                .AddIntegrationSpyAndSubscriber())
            .Run(waitUntilBrokerConnected: false);

            var consumer = Helper.Broker.Consumers[0];

            consumer.StatusInfo.History.Should().HaveCount(1);
            consumer.StatusInfo.History.Last().Status.Should().Be(ConsumerStatus.Connected);
            consumer.StatusInfo.History.Last().Timestamp.Should().NotBeNull();

            await AsyncTestingUtil.WaitAsync(() => consumer.StatusInfo.History.Count >= 2);

            consumer.StatusInfo.History.Should().HaveCount(2);
            consumer.StatusInfo.History.Last().Status.Should().Be(ConsumerStatus.Ready);
            consumer.StatusInfo.History.Last().Timestamp.Should().NotBeNull();

            var publisher = Host.ScopedServiceProvider.GetRequiredService <IEventPublisher>();
            await publisher.PublishAsync(new TestEventOne());

            await Helper.WaitUntilAllMessagesAreConsumedAsync();

            consumer.StatusInfo.History.Should().HaveCount(3);
            consumer.StatusInfo.History.Last().Status.Should().Be(ConsumerStatus.Consuming);
            consumer.StatusInfo.History.Last().Timestamp.Should().NotBeNull();

            await Helper.Broker.DisconnectAsync();

            consumer.StatusInfo.History.Should().HaveCount(4);
            consumer.StatusInfo.History.Last().Status.Should()
            .Be(ConsumerStatus.Disconnected);
            consumer.StatusInfo.History.Last().Timestamp.Should().NotBeNull();
        }
Example #29
0
        public async Task Rebalance_WithoutAutoCommit_PendingOffsetsCommitted()
        {
            int receivedMessages = 0;

            Host.ConfigureServices(
                services => services
                .AddLogging()
                .AddSilverback()
                .UseModel()
                .WithConnectionToMessageBroker(options => options.AddMockedKafka())
                .AddEndpoints(
                    endpoints => endpoints
                    .AddOutbound <IIntegrationEvent>(new KafkaProducerEndpoint(DefaultTopicName))
                    .AddInbound(
                        new KafkaConsumerEndpoint(DefaultTopicName)
            {
                Configuration =
                {
                    GroupId              = "consumer1",
                    EnableAutoCommit     = false,
                    AutoCommitIntervalMs =          50,
                    CommitOffsetEach     = 10
                }
            }))
                .AddDelegateSubscriber((TestEventOne _) => receivedMessages++))
            .Run();

            var publisher = Host.ScopedServiceProvider.GetRequiredService <IEventPublisher>();
            await publisher.PublishAsync(
                new TestEventOne
            {
                Content = "one"
            });

            await publisher.PublishAsync(
                new TestEventOne
            {
                Content = "two"
            });

            await publisher.PublishAsync(
                new TestEventOne
            {
                Content = "three"
            });

            await AsyncTestingUtil.WaitAsync(() => receivedMessages == 3);

            DefaultTopic.Rebalance();

            DefaultTopic.GetCommittedOffsetsCount("consumer1").Should().Be(3);
        }
Example #30
0
        public async Task Batch_SubscribingToStream_OnlyMatchingStreamsReceived()
        {
            int receivedBatches1 = 0;
            int receivedBatches2 = 0;

            var serviceProvider = Host.ConfigureServices(
                services => services
                .AddLogging()
                .AddSilverback()
                .UseModel()
                .WithConnectionToMessageBroker(
                    options => options.AddMockedKafka(
                        mockedKafkaOptions => mockedKafkaOptions.WithDefaultPartitionsCount(1)))
                .AddEndpoints(
                    endpoints => endpoints
                    .AddOutbound <IIntegrationEvent>(new KafkaProducerEndpoint(DefaultTopicName))
                    .AddInbound(
                        new KafkaConsumerEndpoint(DefaultTopicName)
            {
                Configuration = new KafkaConsumerConfig
                {
                    GroupId          = "consumer1",
                    EnableAutoCommit = false,
                    CommitOffsetEach = 1
                },
                Batch = new BatchSettings
                {
                    Size = 3
                }
            }))
                .AddDelegateSubscriber(
                    (IMessageStreamEnumerable <TestEventOne> eventsStream) =>
            {
                receivedBatches1++;
                var dummy = eventsStream.ToList();
            })
                .AddDelegateSubscriber(
                    (IMessageStreamEnumerable <TestEventTwo> eventsStream) => receivedBatches2++))
                                  .Run();

            var publisher = serviceProvider.GetRequiredService <IEventPublisher>();

            for (int i = 1; i <= 5; i++)
            {
                await publisher.PublishAsync(new TestEventOne { Content = $"{i}" });
            }

            await AsyncTestingUtil.WaitAsync(() => receivedBatches1 >= 2);

            receivedBatches1.Should().Be(2);
            receivedBatches2.Should().Be(0);
        }