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); }
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); }
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(); }