public async Task BasicPubSubOnTopic()
        {
            var concurrency = 2;
            var subscribers = 2;
            var topic       = "test-ping";

            MessageBusBuilder
            .Produce <PingMessage>(x =>
            {
                x.DefaultTopic(topic);
                // this is optional
                x.WithModifier((message, sbMessage) =>
                {
                    // set the Azure SB message ID
                    sbMessage.MessageId = $"ID_{message.Counter}";
                    // set the Azure SB message partition key
                    sbMessage.PartitionKey = message.Counter.ToString(CultureInfo.InvariantCulture);
                });
            })
            .Do(builder => Enumerable.Range(0, subscribers).ToList().ForEach(i =>
            {
                builder.Consume <PingMessage>(x => x
                                              .Topic(topic)
                                              .SubscriptionName($"subscriber-{i}") // ensure subscription exists on the ServiceBus topic
                                              .WithConsumer <PingConsumer>()
                                              .Instances(concurrency));
            }));

            await BasicPubSub(concurrency, subscribers, subscribers).ConfigureAwait(false);
        }
        public void BasicReqResp()
        {
            // arrange

            // ensure the topic has 2 partitions
            var topic = "test-echo";
            var echoRequestHandler = new EchoRequestHandler();

            MessageBusBuilder
            .Produce <EchoRequest>(x =>
            {
                x.DefaultTopic(topic);
            })
            .Handle <EchoRequest, EchoResponse>(x => x.Topic(topic)
                                                .Group("handler")          // ensure consumer group exists on the event hub
                                                .WithHandler <EchoRequestHandler>()
                                                .Instances(2))
            .ExpectRequestResponses(x =>
            {
                x.ReplyToTopic("test-echo-resp");
                x.Group("response-reader");     // ensure consumer group exists on the event hub
                x.DefaultTimeout(TimeSpan.FromSeconds(30));
            })
            .WithDependencyResolver(new LookupDependencyResolver(f =>
            {
                if (f == typeof(EchoRequestHandler))
                {
                    return(echoRequestHandler);
                }
                throw new InvalidOperationException();
            }));

            var messageBus = MessageBus.Value;

            // act

            var requests = Enumerable
                           .Range(0, NumberOfMessages)
                           .Select(i => new EchoRequest {
                Index = i, Message = $"Echo {i}"
            })
                           .ToList();

            var responses = new List <Tuple <EchoRequest, EchoResponse> >();

            requests.AsParallel().ForAll(req =>
            {
                var resp = messageBus.Send(req).Result;
                lock (responses)
                {
                    responses.Add(Tuple.Create(req, resp));
                }
            });

            // assert

            // all messages got back
            responses.Count.Should().Be(NumberOfMessages);
            responses.All(x => x.Item1.Message == x.Item2.Message).Should().BeTrue();
        }
        public async Task BasicPubSubOnQueue()
        {
            var concurrency = 2;
            var subscribers = 2;
            var queue       = "test-ping-queue";

            MessageBusBuilder
            .Produce <PingMessage>(x =>
            {
                x.DefaultQueue(queue);
                // this is optional
                x.WithModifier((message, sbMessage) =>
                {
                    // set the Azure SB message ID
                    sbMessage.MessageId = $"ID_{message.Counter}";
                    // set the Azure SB message partition key
                    sbMessage.PartitionKey = message.Counter.ToString(CultureInfo.InvariantCulture);
                });
            })
            .Do(builder => Enumerable.Range(0, subscribers).ToList().ForEach(i =>
            {
                builder.Consume <PingMessage>(x => x
                                              .Queue(queue)
                                              .WithConsumer <PingConsumer>()
                                              .Instances(concurrency));
            }));

            await BasicPubSub(concurrency, subscribers, 1).ConfigureAwait(false);
        }
        public async Task BasicReqRespOnTopic()
        {
            var topic = "test-echo";

            MessageBusBuilder
            .Produce <EchoRequest>(x =>
            {
                x.DefaultTopic(topic);
                // this is optional
                x.WithModifier((message, sbMessage) =>
                {
                    // set the Azure SB message ID
                    sbMessage.MessageId = $"ID_{message.Index}";
                    // set the Azure SB message partition key
                    sbMessage.PartitionKey = message.Index.ToString(CultureInfo.InvariantCulture);
                });
            })
            .Handle <EchoRequest, EchoResponse>(x => x.Topic(topic)
                                                .SubscriptionName("handler")
                                                .WithHandler <EchoRequestHandler>()
                                                .Instances(2))
            .ExpectRequestResponses(x =>
            {
                x.ReplyToTopic("test-echo-resp");
                x.SubscriptionName("response-consumer");
                x.DefaultTimeout(TimeSpan.FromSeconds(60));
            });

            await BasicReqResp().ConfigureAwait(false);
        }
Example #5
0
 public MessageBusBuilder initBus(MessageBusBuilder bus)
 {
     return(bus
            .Produce <MessageRequest>(x => x.DefaultTopic("Send"))
            .Handle <MessageRequest, MessageResponse>(x => x.Topic("Send").WithHandler <Handler>())
            .ExpectRequestResponses(x => x.ReplyToTopic("Respond")));
 }
        public void BasicPubSub()
        {
            // arrange
            var topic = "test-ping";

            var pingConsumer = new PingConsumer();

            MessageBusBuilder
            .Produce <PingMessage>(x => x.DefaultTopic(topic))
            .Consume <PingMessage>(x => x.Topic(topic)
                                   .Group("subscriber")              // ensure consumer group exists on the event hub
                                   .WithConsumer <PingConsumer>()
                                   .Instances(2))
            .WithDependencyResolver(new LookupDependencyResolver(f =>
            {
                if (f == typeof(PingConsumer))
                {
                    return(pingConsumer);
                }
                throw new InvalidOperationException();
            }));

            var kafkaMessageBus = MessageBus.Value;

            // act

            // publish
            var stopwatch = Stopwatch.StartNew();

            var messages = Enumerable
                           .Range(0, NumberOfMessages)
                           .Select(i => new PingMessage {
                Counter = i, Timestamp = DateTime.UtcNow
            })
                           .ToList();

            messages
            .AsParallel()
            .ForAll(m => kafkaMessageBus.Publish(m).Wait());

            stopwatch.Stop();
            Log.InfoFormat(CultureInfo.InvariantCulture, "Published {0} messages in {1}", messages.Count, stopwatch.Elapsed);

            // consume
            stopwatch.Restart();
            var messagesReceived = ConsumeFromTopic(pingConsumer);

            stopwatch.Stop();
            Log.InfoFormat(CultureInfo.InvariantCulture, "Consumed {0} messages in {1}", messagesReceived.Count, stopwatch.Elapsed);

            // assert

            // all messages got back
            messagesReceived.Count.Should().Be(messages.Count);
        }
        public async Task BasicReqRespOnTopic()
        {
            var topic = "test-echo";

            MessageBusBuilder
            .Produce <EchoRequest>(x =>
            {
                x.DefaultTopic(topic);
            })
            .Handle <EchoRequest, EchoResponse>(x => x.Topic(topic)
                                                .WithHandler <EchoRequestHandler>()
                                                .Instances(2))
            .ExpectRequestResponses(x =>
            {
                x.ReplyToTopic("test-echo-resp");
                x.DefaultTimeout(TimeSpan.FromSeconds(60));
            });

            await BasicReqResp().ConfigureAwait(false);
        }
        public async Task BasicPubSubOnTopic()
        {
            var concurrency = 2;
            var subscribers = 2;
            var topic       = "test-ping";

            MessageBusBuilder
            .Produce <PingMessage>(x =>
            {
                x.DefaultTopic(topic);
            })
            .Do(builder => Enumerable.Range(0, subscribers).ToList().ForEach(i =>
            {
                builder.Consume <PingMessage>(x => x
                                              .Topic(topic)
                                              .WithConsumer <PingConsumer>()
                                              .Instances(concurrency));
            }));

            await BasicPubSub(concurrency, subscribers).ConfigureAwait(false);
        }
Example #9
0
 public MessageBusBuilder initBus(MessageBusBuilder bus)
 {
     return(bus
            .Produce <BasicControlMessage>(x => x.DefaultTopic("Controls")));
 }
        public async Task BasicReqResp()
        {
            // arrange

            // ensure the topic has 2 partitions
            var topic = $"{TopicPrefix}test-echo";
            var echoRequestHandler = new EchoRequestHandler();

            MessageBusBuilder
            .Produce <EchoRequest>(x =>
            {
                x.DefaultTopic(topic);
                // Partition #0 for even indices
                // Partition #1 for odd indices
                x.PartitionProvider((m, t) => m.Index % 2);
            })
            .Handle <EchoRequest, EchoResponse>(x => x.Topic(topic)
                                                .WithHandler <EchoRequestHandler>()
                                                .Group("handler")
                                                .Instances(2)
                                                .CheckpointEvery(1000)
                                                .CheckpointAfter(TimeSpan.FromSeconds(60)))
            .ExpectRequestResponses(x =>
            {
                x.ReplyToTopic($"{TopicPrefix}test-echo-resp");
                x.Group("response-reader");
                // for subsequent test runs allow enough time for kafka to reassign the partitions
                x.DefaultTimeout(TimeSpan.FromSeconds(60));
                x.CheckpointEvery(100);
                x.CheckpointAfter(TimeSpan.FromSeconds(10));
            })
            .WithDependencyResolver(new LookupDependencyResolver(f =>
            {
                if (f == typeof(EchoRequestHandler))
                {
                    return(echoRequestHandler);
                }
                throw new InvalidOperationException();
            }));

            var kafkaMessageBus = MessageBus.Value;

            // act

            var requests = Enumerable
                           .Range(0, NumberOfMessages)
                           .Select(i => new EchoRequest {
                Index = i, Message = $"Echo {i}"
            })
                           .ToList();

            var responses = new ConcurrentBag <ValueTuple <EchoRequest, EchoResponse> >();
            await Task.WhenAll(requests.Select(async req =>
            {
                var resp = await kafkaMessageBus.Send(req);
                responses.Add((req, resp));
            }));

            await WaitWhileMessagesAreFlowing(() => responses.Count);

            // assert

            // all messages got back
            responses.Count.Should().Be(NumberOfMessages);
            responses.All(x => x.Item1.Message == x.Item2.Message).Should().BeTrue();
        }
        public async Task BasicPubSub()
        {
            // arrange

            // ensure the topic has 2 partitions
            var topic = $"{TopicPrefix}test-ping";

            var pingConsumer = new PingConsumer(_loggerFactory.CreateLogger <PingConsumer>());

            MessageBusBuilder
            .Produce <PingMessage>(x =>
            {
                x.DefaultTopic(topic);
                // Partition #0 for even counters
                // Partition #1 for odd counters
                x.PartitionProvider((m, t) => m.Counter % 2);
            })
            .Consume <PingMessage>(x =>
            {
                x.Topic(topic)
                .WithConsumer <PingConsumer>()
                .Group("subscriber")
                .Instances(2)
                .CheckpointEvery(1000)
                .CheckpointAfter(TimeSpan.FromSeconds(600));
            })
            .WithDependencyResolver(new LookupDependencyResolver(f =>
            {
                if (f == typeof(PingConsumer))
                {
                    return(pingConsumer);
                }
                throw new InvalidOperationException();
            }));

            var messageBus = MessageBus.Value;

            // act

            // publish
            var stopwatch = Stopwatch.StartNew();

            var messages = Enumerable
                           .Range(0, NumberOfMessages)
                           .Select(i => new PingMessage {
                Counter = i, Timestamp = DateTime.UtcNow
            })
                           .ToList();

            await Task.WhenAll(messages.Select(m => messageBus.Publish(m)));

            stopwatch.Stop();
            _logger.LogInformation("Published {0} messages in {1}", messages.Count, stopwatch.Elapsed);

            // consume
            stopwatch.Restart();

            await WaitWhileMessagesAreFlowing(() => pingConsumer.Messages.Count);

            var messagesReceived = pingConsumer.Messages;

            stopwatch.Stop();
            _logger.LogInformation("Consumed {0} messages in {1}", messagesReceived.Count, stopwatch.Elapsed);

            // assert

            // all messages got back
            messagesReceived.Count.Should().Be(messages.Count);

            // Partition #0 => Messages with even counter
            messagesReceived
            .Where(x => x.Item2 == 0)
            .All(x => x.Item1.Counter % 2 == 0)
            .Should().BeTrue();

            // Partition #1 => Messages with odd counter
            messagesReceived
            .Where(x => x.Item2 == 1)
            .All(x => x.Item1.Counter % 2 == 1)
            .Should().BeTrue();
        }
        public void BasicPubSub()
        {
            // arrange

            // ensure the topic has 2 partitions
            var topic = "test-ping";

            var pingConsumer = new PingConsumer();

            MessageBusBuilder
            .Produce <PingMessage>(x =>
            {
                x.DefaultTopic(topic);
                // Partition #0 for even counters
                // Partition #1 for odd counters
                x.PartitionProvider((m, t) => m.Counter % 2);
            })
            .Consume <PingMessage>(x => x.Topic(topic)
                                   .Group("subscriber")
                                   .WithConsumer <PingConsumer>()
                                   .Instances(2))
            .WithDependencyResolver(new LookupDependencyResolver(f =>
            {
                if (f == typeof(PingConsumer))
                {
                    return(pingConsumer);
                }
                throw new InvalidOperationException();
            }));

            var messageBus = MessageBus.Value;

            // act

            // publish
            var stopwatch = Stopwatch.StartNew();

            var messages = Enumerable
                           .Range(0, NumberOfMessages)
                           .Select(i => new PingMessage {
                Counter = i, Timestamp = DateTime.UtcNow
            })
                           .ToList();

            messages
            .AsParallel()
            .ForAll(m => messageBus.Publish(m).Wait());

            stopwatch.Stop();
            Log.InfoFormat(CultureInfo.InvariantCulture, "Published {0} messages in {1}", messages.Count, stopwatch.Elapsed);

            // consume
            stopwatch.Restart();
            var messagesReceived = ConsumeFromTopic(pingConsumer);

            stopwatch.Stop();
            Log.InfoFormat(CultureInfo.InvariantCulture, "Consumed {0} messages in {1}", messagesReceived.Count, stopwatch.Elapsed);

            // assert

            // all messages got back
            messagesReceived.Count.Should().Be(messages.Count);

            // Partition #0 => Messages with even counter
            messagesReceived
            .Where(x => x.Item2 == 0)
            .All(x => x.Item1.Counter % 2 == 0)
            .Should().BeTrue();

            // Partition #1 => Messages with odd counter
            messagesReceived
            .Where(x => x.Item2 == 1)
            .All(x => x.Item1.Counter % 2 == 1)
            .Should().BeTrue();
        }