예제 #1
0
        public async Task produces_expected_message_with_headers_using_default_serializer()
        {
            var spy = new KafkaProducerSpy();

            var sut = A.Producer
                      .With(spy)
                      .With(new MessageIdGeneratorStub(() => "1"))
                      .With(A.OutgoingMessageRegistry
                            .Register <Message>("foo", "bar", @event => @event.Id)
                            .Build()
                            )
                      .Build();

            await sut.Produce(
                message : new Message {
                Id = "dummyId"
            },
                headers : new Dictionary <string, object>
            {
                { "foo-key", "foo-value" }
            }
                );

            var expectedValue = @"{""messageId"":""1"",""type"":""bar"",""foo-key"":""foo-value"",""data"":{""id"":""dummyId""}}";

            Assert.Equal(expectedValue, spy.Value);
        }
예제 #2
0
        public async Task produces_message_to_expected_topic()
        {
            var spy = new KafkaProducerSpy();

            var expectedTopic = "foo";

            var sut = A.Producer
                      .With(spy)
                      .With(A.OutgoingMessageRegistry
                            .Register <Message>(expectedTopic, "bar", @event => @event.Id)
                            .Build()
                            )
                      .Build();

            await sut.Produce(
                message : new Message {
                Id = "dummyId"
            },
                headers : new Dictionary <string, object>
            {
                { "foo-key", "foo-value" }
            }
                );

            Assert.Equal(expectedTopic, spy.Topic);
        }
예제 #3
0
        public async Task produces_message_with_expected_serialized_value()
        {
            var expectedValue = "foo-value";

            var spy = new KafkaProducerSpy(new PayloadSerializerStub(expectedValue));

            var sut = A.Producer
                      .With(spy)
                      .With(A.OutgoingMessageRegistry
                            .Register <Message>("foo", "bar", @event => @event.Id)
                            .Build()
                            )
                      .Build();

            await sut.Produce(
                message : new Message {
                Id = "dummyId"
            },
                headers : new Dictionary <string, object>
            {
                { "foo-key", "foo-value" }
            }
                );

            Assert.Equal(expectedValue, spy.Value);
        }
예제 #4
0
        public async Task Can_produce_message()
        {
            var spy = new KafkaProducerSpy();

            var services = new ServiceCollection();

            services.AddProducerFor <SimpleSender>(options =>
            {
                options.WithBootstrapServers("dummy");
                options.WithKafkaProducerFactory(() => spy);
                options.WithMessageIdGenerator(new MessageIdGeneratorStub(() => "qux"));
                options.Register <DummyMessage>("foo", "bar", x => "baz");
            });

            var provider = services.BuildServiceProvider();

            var simpleSender = provider.GetRequiredService <SimpleSender>();
            var producer     = simpleSender.Producer;

            await producer.Produce(new DummyMessage());

            Assert.Equal("foo", spy.LastMessage.Topic);
            Assert.Equal("qux", spy.LastMessage.MessageId);
            Assert.Equal("bar", spy.LastMessage.Type);
            Assert.Equal("baz", spy.LastMessage.Key);
        }
예제 #5
0
        public async Task Can_create_outgoing_message_from_registry_with_expected_raw_message()
        {
            const string dummyMessageId   = "foo_id";
            const string dummyAggregateId = "dummyId";

            var spy = new KafkaProducerSpy();
            var sut = A.Producer
                      .With(spy)
                      .With(A.OutgoingMessageRegistry
                            .Register <DummyMessage>(DummyTopic, DummyType, x => x.AggregateId)
                            .Build()
                            )
                      .With(new MessageIdGeneratorStub(() => dummyMessageId))
                      .Build();

            await sut.Produce(new DummyMessage(dummyAggregateId));

            var expected = $@"{{
                                ""messageId"":""{dummyMessageId}"",
                                ""type"":""{DummyType}"",
                                ""causationId"":""foo_id"",
                                ""correlationId"":""foo_id"",
                                ""data"":{{
                                    ""aggregateId"":""{dummyAggregateId}""
                                    }}
                                }}";

            AssertJson.Equal(expected, spy.Value);
        }
예제 #6
0
        public async Task Can_processes_unpublished_outbox_messages()
        {
            var dummyMessageId = Guid.NewGuid();
            var spy            = new KafkaProducerSpy();
            var sut            = A.OutboxProcessor
                                 .With(new FakeOutboxPersistence(A.OutboxMessage
                                                                 .WithMessageId(dummyMessageId)
                                                                 .WithTopic("foo")
                                                                 .WithKey("bar")
                                                                 .WithType("baz")
                                                                 .WithValue("qux")
                                                                 .OccurredOnUtc(DateTime.UtcNow)
                                                                 ))
                                 .With(A.Producer
                                       .With(spy)
                                       .Build()
                                       )
                                 .Build();

            await sut.ProcessUnpublishedOutboxMessages(CancellationToken.None);

            Assert.Equal(dummyMessageId.ToString(), spy.LastMessage.MessageId);
            Assert.Equal("foo", spy.LastMessage.Topic);
            Assert.Equal("bar", spy.LastMessage.Key);
            Assert.Equal("baz", spy.LastMessage.Type);
            Assert.Equal("qux", spy.LastMessage.Value);
        }
예제 #7
0
        public async Task produces_message_with_expected_partition_key()
        {
            var spy = new KafkaProducerSpy();

            var expectedKey = "foo-partition-key";

            var sut = A.Producer
                      .With(spy)
                      .With(A.OutgoingMessageRegistry
                            .Register <Message>("foo", "bar", @event => @event.Id)
                            .Build()
                            )
                      .Build();

            await sut.Produce(
                message : new Message {
                Id = expectedKey
            },
                headers : new Dictionary <string, object>
            {
                { "foo-key", "foo-value" }
            }
                );

            Assert.Equal(expectedKey, spy.Key);
        }
예제 #8
0
        public async Task produces_message_using_metadata()
        {
            var spy = new KafkaProducerSpy();

            var expectedKey = "foo-partition-key";

            var sut = A.Producer
                      .With(spy)
                      .With(A.OutgoingMessageRegistry
                            .Register <Message>("foo", "bar", @event => @event.Id)
                            .Build()
                            )
                      .Build();

            await sut.Produce(
                message : new Message {
                Id = expectedKey
            },
                headers : new Metadata
            {
                CausationId   = "my-causation",
                CorrelationId = "my-correlation"
            }
                );

            Assert.Equal(expectedKey, spy.Key);
        }
예제 #9
0
        public async Task produces_message_with_expected_value()
        {
            var expected = "foo value 123";
            var spy      = new KafkaProducerSpy(new PayloadSerializerStub(expected));

            var payloadStub = new PayloadDescriptorBuilder().Build();
            await spy.Produce(payloadStub);

            Assert.Equal(expected, spy.Value);
        }
        public async Task Can_produce_outbox_message()
        {
            var spy               = new KafkaProducerSpy();
            var services          = new ServiceCollection();
            var fake              = new FakeOutboxPersistence();
            var dummyNotification = new DummyNotification();
            var messageId         = Guid.NewGuid().ToString();

            services.AddLogging();
            services.AddOutbox(options =>
            {
                options.WithMessageIdGenerator(new MessageIdGeneratorStub(() => messageId));
                options.Register <DummyMessage>("foo", "bar", x => "baz");

                options.WithOutboxMessageRepository(serviceProvider => fake);
                options.WithNotifier(serviceProvider => dummyNotification);
            });
            services.AddOutboxProducer(options =>
            {
                options.WithBootstrapServers("localhost");
                options.WithKafkaProducerFactory(() => spy);
                options.WithUnitOfWorkFactory(serviceProvider => fake);
                options.WithNotification(serviceProvider => dummyNotification);
            });

            var provider = services.BuildServiceProvider();
            var outbox   = provider.GetRequiredService <OutboxQueue>();

            await outbox.Enqueue(new[] { new DummyMessage() });

            var pollingPublisher = provider
                                   .GetServices <IHostedService>()
                                   .OfType <OutboxDispatcherHostedService>()
                                   .First();

            using (var cts = new CancellationTokenSource())
            {
                cts.CancelAfter(10);

                pollingPublisher.ProcessOutbox(cts.Token);
            }

            Assert.True(fake.OutboxMessages.All(x => x.ProcessedUtc.HasValue));

            Assert.True(fake.Committed);

            Assert.Equal("foo", spy.LastMessage.Topic);
            Assert.Equal(messageId, spy.LastMessage.MessageId);
            Assert.Equal("bar", spy.LastMessage.Type);
            Assert.Equal("baz", spy.LastMessage.Key);
//            Assert.Equal("", spy.LastOutgoingMessage.Value);
        }
예제 #11
0
        public async Task produces_message_with_expected_key()
        {
            var spy = new KafkaProducerSpy();

            var expected = "foo partition key";

            var payloadStub = new PayloadDescriptorBuilder()
                              .WithPartitionKey(expected)
                              .Build();

            await spy.Produce(payloadStub);

            Assert.Equal(expected, spy.Key);
        }
예제 #12
0
        public async Task produces_to_expected_topic()
        {
            var spy = new KafkaProducerSpy();

            var expected = "foo topic name";

            var payloadStub = new PayloadDescriptorBuilder()
                              .WithTopicName(expected)
                              .Build();

            await spy.Produce(payloadStub);

            Assert.Equal(expected, spy.Topic);
        }
예제 #13
0
        public async Task Can_produce_message()
        {
            var spy = new KafkaProducerSpy();

            var sut = A.Producer
                      .With(spy)
                      .With(A.OutgoingMessageRegistry
                            .Register <Message>("foo", "bar", @event => @event.Id)
                            .Build()
                            )
                      .Build();

            await sut.Produce(new Message { Id = "dummyId" });

            Assert.Equal("foo", spy.Topic);
            Assert.Equal("dummyId", spy.Key);
        }
예제 #14
0
        public async Task Can_produce_outbox_message()
        {
            var spy       = new KafkaProducerSpy();
            var services  = new ServiceCollection();
            var fake      = new FakeOutboxPersistence();
            var messageId = Guid.NewGuid().ToString();

            services.AddLogging();
            services.AddProducer(options =>
            {
                options.WithBootstrapServers("localhost");
                options.WithKafkaProducerFactory(new KafkaProducerFactoryStub(spy));
                options.WithMessageIdGenerator(new MessageIdGeneratorStub(() => messageId));
                options.Register <DummyMessage>("foo", "bar", x => "baz");

                options.AddOutbox(opt =>
                {
                    opt.WithOutboxMessageRepository(serviceProvider => fake);
                    opt.WithOutboxPublisher(pub => { pub.WithUnitOfWorkFactory(serviceProvider => fake); });
                });
            });
            var provider = services.BuildServiceProvider();
            var outbox   = provider.GetRequiredService <IOutbox>();

            await outbox.Enqueue(new[] { new DummyMessage(), });

            var pollingPublisher = provider.GetServices <IHostedService>().FirstOrDefault(x => x is PollingPublisher);

            using (CancellationTokenSource cts = new CancellationTokenSource())
            {
                cts.CancelAfter(500);

                await pollingPublisher.StartAsync(cts.Token);
            }

            Assert.True(fake.OutboxMessages.All(x => x.ProcessedUtc.HasValue));

            Assert.Equal("foo", spy.LastMessage.Topic);
            Assert.Equal(messageId, spy.LastMessage.MessageId);
            Assert.Equal("bar", spy.LastMessage.Type);
            Assert.Equal("baz", spy.LastMessage.Key);
//            Assert.Equal("", spy.LastOutgoingMessage.Value);
        }
예제 #15
0
        public void when_disposing_the_factory_all_kafka_producers_are_also_disposed()
        {
            var spy = new KafkaProducerSpy();

            using (var sut = new ProducerFactoryBuilder().Build())
            {
                var producerConfiguration = new ProducerConfigurationBuilder()
                                            .WithKafkaProducerFactory(() => spy)
                                            .Build();

                sut.ConfigureProducer(
                    producerName: "foo",
                    configuration: producerConfiguration,
                    outgoingMessageRegistry: new OutgoingMessageRegistry()
                    );

                sut.Get("foo");
            }

            Assert.True(spy.WasDisposed);
        }
예제 #16
0
        public async Task Can_processes_unpublished_outbox_messages()
        {
            var spy = new KafkaProducerSpy();
            var sut = A.OutboxDispatcher
                      .With(new FakeOutboxPersistence(A.OutboxEntry
                                                      .WithTopic("foo")
                                                      .WithKey("bar")
                                                      .WithValue("baz")
                                                      ))
                      .With(A.OutboxProducer
                            .With(spy)
                            .Build()
                            )
                      .Build();

            await sut.Dispatch(CancellationToken.None);

            Assert.Equal("foo", spy.Topic);
            Assert.Equal("bar", spy.Key);
            Assert.Equal("baz", spy.Value);
        }
예제 #17
0
        public async Task produces_message_using_message_handler_context()
        {
            var spy = new KafkaProducerSpy();

            var sut = A.Producer
                      .With(spy)
                      .With(new MessageIdGeneratorStub(() => "1"))
                      .With(A.OutgoingMessageRegistry
                            .Register <Message>("foo", "bar", @event => @event.Id)
                            .Build()
                            )
                      .Build();

            await sut.Produce(
                message : new Message {
                Id = "0"
            },
                context : new MessageHandlerContext(new Metadata
            {
                CausationId   = "my-causation",
                CorrelationId = "my-correlation"
            })
                );


            var expected = @"
                            {
                            ""messageId"":""1"",
                            ""type"":""bar"",
                            ""correlationId"":""my-correlation"",
                            ""causationId"":""1"",
                            ""data"":{
                                ""id"":""0""
                                }
                            }";

            AssertJson.Equal(expected, spy.Value);
        }