private async Task ServiceBusMessagePump_PublishServiceBusMessage_MessageSuccessfullyProcessed(Encoding messageEncoding, string connectionStringKey) { // Arrange var operationId = Guid.NewGuid().ToString(); var transactionId = Guid.NewGuid().ToString(); var connectionString = Configuration.GetValue <string>(connectionStringKey); ServiceBusConnectionStringProperties serviceBusConnectionString = ServiceBusConnectionStringProperties.Parse(connectionString); await using (var client = new ServiceBusClient(connectionString)) await using (ServiceBusSender messageSender = client.CreateSender(serviceBusConnectionString.EntityPath)) { var order = OrderGenerator.Generate(); var orderMessage = order.AsServiceBusMessage(operationId, transactionId, encoding: messageEncoding); // Act await messageSender.SendMessageAsync(orderMessage); // Assert var receivedEvent = _serviceBusEventConsumerHost.GetReceivedEvent(operationId); Assert.NotEmpty(receivedEvent); var deserializedEventGridMessage = EventParser.Parse(receivedEvent); Assert.NotNull(deserializedEventGridMessage); var orderCreatedEvent = Assert.Single(deserializedEventGridMessage.Events); Assert.NotNull(orderCreatedEvent); var orderCreatedEventData = orderCreatedEvent.GetPayload <OrderCreatedEventData>(); Assert.NotNull(orderCreatedEventData); Assert.NotNull(orderCreatedEventData.CorrelationInfo); Assert.Equal(order.Id, orderCreatedEventData.Id); Assert.Equal(order.Amount, orderCreatedEventData.Amount); Assert.Equal(order.ArticleNumber, orderCreatedEventData.ArticleNumber); Assert.Equal(transactionId, orderCreatedEventData.CorrelationInfo.TransactionId); Assert.Equal(operationId, orderCreatedEventData.CorrelationInfo.OperationId); Assert.NotEmpty(orderCreatedEventData.CorrelationInfo.CycleId); } }
static void Main() { // Use the following request URI if you're running this console // application in a Docker container var requestUri = "http://*****:*****@customer} placed {@order}", customer, order); Thread.Sleep(1000); } }
private static ServiceBusReceivedMessage CreateMessage(string key = null, object value = null, string correlationId = null) { Order order = OrderGenerator.Generate(); ServiceBusReceivedMessage message = order.AsServiceBusReceivedMessage(key, value, correlationId); return(message); }
public async Task WithServiceBusRouting_WithMessageHandlerMessageBodySerializer_DeserializesCustomMessage() { // Arrange var services = new ServiceCollection(); var collection = new ServiceBusMessageHandlerCollection(services); var ignoredHandler = new StubServiceBusMessageHandler <TestMessage>(); var spyHandler = new StubServiceBusMessageHandler <Order>(); var expectedMessage = new TestMessage { TestProperty = "Some value" }; string expectedBody = JsonConvert.SerializeObject(expectedMessage); var serializer = new TestMessageBodySerializer(expectedBody, OrderGenerator.Generate()); collection.WithServiceBusMessageHandler <StubServiceBusMessageHandler <Order>, Order>(messageBodySerializer: serializer, implementationFactory: serviceProvider => spyHandler) .WithServiceBusMessageHandler <StubServiceBusMessageHandler <TestMessage>, TestMessage>(implementationFactory: serviceProvider => ignoredHandler); // Act services.AddServiceBusMessageRouting(); // Assert IServiceProvider provider = services.BuildServiceProvider(); var router = provider.GetRequiredService <IAzureServiceBusMessageRouter>(); AzureServiceBusMessageContext context = AzureServiceBusMessageContextFactory.Generate(); var correlationInfo = new MessageCorrelationInfo("operation-id", "transaction-id"); ServiceBusReceivedMessage message = expectedMessage.AsServiceBusReceivedMessage(); await router.RouteMessageAsync(message, context, correlationInfo, CancellationToken.None); Assert.True(spyHandler.IsProcessed); Assert.False(ignoredHandler.IsProcessed); }
private async Task ServiceBusMessagePump_PublishServiceBusMessage_MessageSuccessfullyProcessed(Encoding messageEncoding, string connectionStringKey) { // Arrange var operationId = Guid.NewGuid().ToString(); var transactionId = Guid.NewGuid().ToString(); var messageSender = CreateServiceBusSender(connectionStringKey); var order = OrderGenerator.Generate(); var orderMessage = order.WrapInServiceBusMessage(operationId, transactionId, encoding: messageEncoding); // Act await messageSender.SendAsync(orderMessage); // Assert var receivedEvent = _serviceBusEventConsumerHost.GetReceivedEvent(operationId); Assert.NotEmpty(receivedEvent); var deserializedEventGridMessage = EventGridParser.Parse <OrderCreatedEvent>(receivedEvent); Assert.NotNull(deserializedEventGridMessage); var orderCreatedEvent = Assert.Single(deserializedEventGridMessage.Events); var orderCreatedEventData = orderCreatedEvent.GetPayload <OrderCreatedEventData>(); Assert.NotNull(orderCreatedEventData); Assert.NotNull(orderCreatedEventData.CorrelationInfo); Assert.Equal(order.Id, orderCreatedEventData.Id); Assert.Equal(order.Amount, orderCreatedEventData.Amount); Assert.Equal(order.ArticleNumber, orderCreatedEventData.ArticleNumber); Assert.Equal(transactionId, orderCreatedEventData.CorrelationInfo.TransactionId); Assert.Equal(operationId, orderCreatedEventData.CorrelationInfo.OperationId); Assert.NotEmpty(orderCreatedEventData.CorrelationInfo.CycleId); }
public async Task WithServiceBusMessageRouting_WithMessageHandlerMessageBodyFilter_GoesThroughRegisteredMessageHandlers() { // Arrange var services = new ServiceCollection(); var collection = new ServiceBusMessageHandlerCollection(services); var ignoredHandler = new StubServiceBusMessageHandler <Order>(); var spyHandler = new StubServiceBusMessageHandler <Order>(); collection.WithServiceBusMessageHandler <StubServiceBusMessageHandler <Order>, Order>( messageBodyFilter: body => true, implementationFactory: serviceProvider => spyHandler) .WithServiceBusMessageHandler <StubServiceBusMessageHandler <Order>, Order>( messageBodyFilter: body => false, implementationFactory: serviceProvider => ignoredHandler); // Act services.AddServiceBusMessageRouting(); // Assert IServiceProvider provider = services.BuildServiceProvider(); var router = provider.GetRequiredService <IAzureServiceBusMessageRouter>(); AzureServiceBusMessageContext context = AzureServiceBusMessageContextFactory.Generate(); var correlationInfo = new MessageCorrelationInfo("operation-id", "transaction-id"); Order order = OrderGenerator.Generate(); ServiceBusReceivedMessage message = order.AsServiceBusReceivedMessage(); await router.RouteMessageAsync(message, context, correlationInfo, CancellationToken.None); Assert.True(spyHandler.IsProcessed); Assert.False(ignoredHandler.IsProcessed); }
public async Task ServiceBusQueueMessagePumpWithServiceBusDeadLetterOnFallback_PublishServiceBusMessage_MessageSuccessfullyProcessed() { // Arrange var config = TestConfig.Create(); string connectionString = config.GetServiceBusConnectionString(ServiceBusEntityType.Queue); var options = new WorkerOptions(); options.AddServiceBusQueueMessagePump( configuration => connectionString, opt => opt.AutoComplete = false) .WithServiceBusMessageHandler <ShipmentAzureServiceBusMessageHandler, Shipment>((AzureServiceBusMessageContext context) => true) .WithServiceBusFallbackMessageHandler <OrdersAzureServiceBusDeadLetterFallbackMessageHandler>(); Order order = OrderGenerator.Generate(); await using (var worker = await Worker.StartNewAsync(options)) await using (var service = await TestMessagePumpService.StartNewAsync(config, _logger)) { // Act await service.SendMessageToServiceBusAsync(connectionString, order.AsServiceBusMessage()); // Assert await service.AssertDeadLetterMessageAsync(connectionString); } }
static void Main() { // NOTE: Use of ElasticsearchJsonFormatter is optional (but recommended as it produces // 'idiomatic' json). If you don't want to take a dependency on // Serilog.Formatting.Elasticsearch package you can also use other json formatters // such as Serilog.Formatting.Json.JsonFormatter. // Console sink send logs to stdout which will then be read by logspout ILogger logger = new LoggerConfiguration() .Enrich.WithExceptionDetails() .WriteTo.Console(new ElasticsearchJsonFormatter()) .CreateLogger() .ForContext <Program>(); var customerGenerator = new CustomerGenerator(); var orderGenerator = new OrderGenerator(); var exceptionGenerator = new ExceptionGenerator(); while (true) { var customer = customerGenerator.Generate(); var order = orderGenerator.Generate(); logger.Information("{@customer} placed {@order}", customer, order); var exception = exceptionGenerator.Generate(); if (exception != null) { logger.Error(exception, "Problem with {@order} placed by {@customer}", order, customer); } Thread.Sleep(1000); } }
static void Main() { Console.WriteLine("Starting application producing log events..."); var configuration = new ConfigurationBuilder() .AddInMemoryCollection(new[] { new KeyValuePair <string, string>("apiKey", "secret-api-key") }) .Build(); var logger = new LoggerConfiguration() .WriteTo.Console() .WriteTo.Http( requestUri: "http://*****:*****@customer} placed {@order}", customer, order); Thread.Sleep(1000); } }
public void CreateMessage_GetSystemProperties_Succeeds() { // Arrange Order order = OrderGenerator.Generate(); ServiceBusReceivedMessage message = order.AsServiceBusReceivedMessage(); // Act AzureServiceBusSystemProperties systemProperties = message.GetSystemProperties(); // Assert Assert.NotNull(systemProperties); }
public async Task WithServiceBusRouting_WithMessageHandlerCanHandleAllFiltersAtOnce_AndStillFindsTheRightMessageHandler() { // Arrange var services = new ServiceCollection(); var collection = new ServiceBusMessageHandlerCollection(services); var ignoredHandler1 = new StubServiceBusMessageHandler <TestMessage>(); var ignoredHandler2 = new StubServiceBusMessageHandler <TestMessage>(); var ignoredHandler3 = new StubServiceBusMessageHandler <Order>(); var spyHandler = new StubServiceBusMessageHandler <Order>(); AzureServiceBusMessageContext context = AzureServiceBusMessageContextFactory.Generate(); var expectedMessage = new TestMessage { TestProperty = "Some value" }; string expectedBody = JsonConvert.SerializeObject(expectedMessage); var serializer = new TestMessageBodySerializer(expectedBody, OrderGenerator.Generate()); collection .WithServiceBusMessageHandler <StubServiceBusMessageHandler <Order>, Order>( messageContextFilter: ctx => ctx != null, messageBodyFilter: body => body != null, messageBodySerializer: new TestMessageBodySerializer(expectedBody, new Customer()), implementationFactory: serviceProvider => ignoredHandler3) .WithServiceBusMessageHandler <StubServiceBusMessageHandler <TestMessage>, TestMessage>( messageBodyFilter: body => body is null, implementationFactory: serviceProvider => ignoredHandler2) .WithServiceBusMessageHandler <StubServiceBusMessageHandler <Order>, Order>( messageBodySerializer: serializer, messageBodyFilter: body => body.Customer != null, messageContextFilter: ctx => ctx.MessageId.StartsWith("message-id"), implementationFactory: serviceProvider => spyHandler) .WithServiceBusMessageHandler <StubServiceBusMessageHandler <TestMessage>, TestMessage>() .WithServiceBusMessageHandler <StubServiceBusMessageHandler <TestMessage>, TestMessage>( implementationFactory: serviceProvider => ignoredHandler1); // Act services.AddServiceBusMessageRouting(); // Assert IServiceProvider provider = services.BuildServiceProvider(); var router = provider.GetRequiredService <IAzureServiceBusMessageRouter>(); var correlationInfo = new MessageCorrelationInfo("operation-id", "transaction-id"); ServiceBusReceivedMessage message = expectedMessage.AsServiceBusReceivedMessage(); await router.RouteMessageAsync(message, context, correlationInfo, CancellationToken.None); Assert.True(spyHandler.IsProcessed); Assert.False(ignoredHandler1.IsProcessed); Assert.False(ignoredHandler2.IsProcessed); Assert.False(ignoredHandler3.IsProcessed); }
public void CreateEventArgs_WithServiceBusReceiver_GetsServiceBusReceiverSucceeds() { // Arrange Order order = OrderGenerator.Generate(); ServiceBusReceivedMessage message = order.AsServiceBusReceivedMessage(); var expectedReceiver = Mock.Of <ServiceBusReceiver>(); // Act var eventArgs = new ProcessMessageEventArgs(message, expectedReceiver, CancellationToken.None); // Assert ServiceBusReceiver actualReceiver = eventArgs.GetServiceBusReceiver(); Assert.Equal(expectedReceiver, actualReceiver); }
public async Task ServiceBusMessagePump_FailureDuringMessageHandling_TracksCorrelationInApplicationInsights() { // Arrange var config = TestConfig.Create(); string connectionString = config.GetServiceBusConnectionString(ServiceBusEntityType.Queue); var spySink = new InMemoryLogSink(); var options = new WorkerOptions(); options.Configure(host => host.UseSerilog((context, currentConfig) => { currentConfig .MinimumLevel.Debug() .MinimumLevel.Override("Microsoft", LogEventLevel.Information) .Enrich.FromLogContext() .Enrich.WithVersion() .Enrich.WithComponentName("Service Bus Queue Worker") .WriteTo.Sink(spySink); })); options.AddServiceBusQueueMessagePump(configuration => connectionString, opt => opt.AutoComplete = true) .WithServiceBusMessageHandler <OrdersSabotageAzureServiceBusMessageHandler, Order>(); string operationId = $"operation-{Guid.NewGuid()}", transactionId = $"transaction-{Guid.NewGuid()}"; ServiceBusMessage orderMessage = OrderGenerator.Generate().AsServiceBusMessage(operationId, transactionId); await using (var worker = await Worker.StartNewAsync(options)) { await using (var service = await TestMessagePumpService.StartNewAsync(config, _logger)) { // Act await service.SendMessageToServiceBusAsync(connectionString, orderMessage); } // Assert RetryAssertUntilTelemetryShouldBeAvailable(() => { Assert.Contains(spySink.CurrentLogEmits, log => log.Exception?.InnerException?.Message.Contains("Sabotage") == true && log.ContainsProperty(ContextProperties.Correlation.OperationId, operationId) && log.ContainsProperty(ContextProperties.Correlation.TransactionId, transactionId)); }, timeout: TimeSpan.FromMinutes(1)); } }
/// <summary> /// Simulate the message processing of the message pump using the Service Bus. /// </summary> public async Task SimulateMessageProcessingAsync() { if (_serviceBusEventConsumerHost is null) { throw new InvalidOperationException( "Cannot simulate the message pump because the service is not yet started; please start this service before simulating"); } var operationId = Guid.NewGuid().ToString(); var transactionId = Guid.NewGuid().ToString(); string connectionString = _configuration.GetServiceBusConnectionString(_entity); var serviceBusConnectionStringBuilder = new ServiceBusConnectionStringBuilder(connectionString); var messageSender = new MessageSender(serviceBusConnectionStringBuilder); try { Order order = OrderGenerator.Generate(); Message orderMessage = order.WrapInServiceBusMessage(operationId, transactionId); await messageSender.SendAsync(orderMessage); string receivedEvent = _serviceBusEventConsumerHost.GetReceivedEvent(operationId); Assert.NotEmpty(receivedEvent); EventGridEventBatch <OrderCreatedEvent> eventBatch = EventGridParser.Parse <OrderCreatedEvent>(receivedEvent); Assert.NotNull(eventBatch); OrderCreatedEvent orderCreatedEvent = Assert.Single(eventBatch.Events); Assert.NotNull(orderCreatedEvent); var orderCreatedEventData = orderCreatedEvent.GetPayload <OrderCreatedEventData>(); Assert.NotNull(orderCreatedEventData); Assert.NotNull(orderCreatedEventData.CorrelationInfo); Assert.Equal(order.Id, orderCreatedEventData.Id); Assert.Equal(order.Amount, orderCreatedEventData.Amount); Assert.Equal(order.ArticleNumber, orderCreatedEventData.ArticleNumber); Assert.Equal(transactionId, orderCreatedEventData.CorrelationInfo.TransactionId); Assert.Equal(operationId, orderCreatedEventData.CorrelationInfo.OperationId); Assert.NotEmpty(orderCreatedEventData.CorrelationInfo.CycleId); } finally { await messageSender.CloseAsync(); } }
public void WrapInServiceBusMessage_BasicWithEncoding_ReturnsValidServiceBusMessageWithSpecifiedEncoding() { // Arrange var originalMessagePayload = OrderGenerator.Generate(); var expectedEncoding = Encoding.ASCII; // Act var serviceBusMessage = originalMessagePayload.WrapInServiceBusMessage(encoding: expectedEncoding); // Assert Assert.NotNull(serviceBusMessage); Assert.Null(serviceBusMessage.CorrelationId); var userProperties = serviceBusMessage.UserProperties; Assert.True(userProperties.ContainsKey(PropertyNames.ContentType)); Assert.True(userProperties.ContainsKey(PropertyNames.Encoding)); Assert.False(userProperties.ContainsKey(PropertyNames.TransactionId)); ArcusAssert.MatchesDictionaryEntry(PropertyNames.ContentType, ExpectedDefaultContentType, userProperties); AssertMessagePayload(serviceBusMessage, userProperties, expectedEncoding, originalMessagePayload); }
public void WrapInServiceBusMessage_BasicWithoutOptions_ReturnsValidServiceBusMessage() { // Arrange var messagePayload = OrderGenerator.Generate(); // Act var serviceBusMessage = messagePayload.WrapInServiceBusMessage(); // Assert Assert.NotNull(serviceBusMessage); Assert.Null(serviceBusMessage.CorrelationId); var userProperties = serviceBusMessage.UserProperties; Assert.True(userProperties.ContainsKey(PropertyNames.ContentType)); Assert.True(userProperties.ContainsKey(PropertyNames.Encoding)); Assert.False(userProperties.ContainsKey(PropertyNames.TransactionId)); ArcusAssert.MatchesDictionaryEntry(PropertyNames.ContentType, ExpectedDefaultContentType, userProperties); ArcusAssert.MatchesDictionaryEntry(PropertyNames.Encoding, ExpectedDefaultEncoding, userProperties); AssertMessagePayload(serviceBusMessage, userProperties, ExpectedDefaultEncoding, messagePayload); }
/// <summary> /// Simulate the message processing of the message pump using the Azure Service Bus. /// </summary> /// <param name="connectionString">The connection string used to send a Azure Service Bus message to the respectively running message pump.</param> /// <exception cref="ArgumentException">Thrown when the <paramref name="connectionString"/> is blank.</exception> public async Task SimulateMessageProcessingAsync(string connectionString) { Guard.NotNullOrWhitespace(connectionString, nameof(connectionString)); if (_serviceBusEventConsumerHost is null) { throw new InvalidOperationException( "Cannot simulate the message pump because the service is not yet started; please start this service before simulating"); } var operationId = Guid.NewGuid().ToString(); var transactionId = Guid.NewGuid().ToString(); Order order = OrderGenerator.Generate(); ServiceBusMessage orderMessage = order.AsServiceBusMessage(operationId, transactionId); orderMessage.ApplicationProperties["Topic"] = "Orders"; await SendMessageToServiceBusAsync(connectionString, orderMessage); string receivedEvent = _serviceBusEventConsumerHost.GetReceivedEvent(operationId, retryCount: 10); Assert.NotEmpty(receivedEvent); EventBatch <Event> eventBatch = EventParser.Parse(receivedEvent); Assert.NotNull(eventBatch); Event orderCreatedEvent = Assert.Single(eventBatch.Events); Assert.NotNull(orderCreatedEvent); var orderCreatedEventData = orderCreatedEvent.GetPayload <OrderCreatedEventData>(); Assert.NotNull(orderCreatedEventData); Assert.NotNull(orderCreatedEventData.CorrelationInfo); Assert.Equal(order.Id, orderCreatedEventData.Id); Assert.Equal(order.Amount, orderCreatedEventData.Amount); Assert.Equal(order.ArticleNumber, orderCreatedEventData.ArticleNumber); Assert.Equal(transactionId, orderCreatedEventData.CorrelationInfo.TransactionId); Assert.Equal(operationId, orderCreatedEventData.CorrelationInfo.OperationId); Assert.NotEmpty(orderCreatedEventData.CorrelationInfo.CycleId); }
public void WrapInServiceBusMessage_BasicWithOperationId_ReturnsValidServiceBusMessageWithSpecifiedCorrelationId() { // Arrange Order messagePayload = OrderGenerator.Generate(); var operationId = Guid.NewGuid().ToString(); // Act ServiceBusMessage serviceBusMessage = messagePayload.AsServiceBusMessage(operationId: operationId); // Assert Assert.NotNull(serviceBusMessage); Assert.Equal(operationId, serviceBusMessage.CorrelationId); IDictionary <string, object> userProperties = serviceBusMessage.ApplicationProperties; Assert.True(userProperties.ContainsKey(PropertyNames.ContentType)); Assert.True(userProperties.ContainsKey(PropertyNames.Encoding)); Assert.False(userProperties.ContainsKey(PropertyNames.TransactionId)); ArcusAssert.MatchesDictionaryEntry(PropertyNames.ContentType, ExpectedDefaultContentType, userProperties); ArcusAssert.MatchesDictionaryEntry(PropertyNames.Encoding, ExpectedDefaultEncoding, userProperties); AssertMessagePayload(serviceBusMessage, userProperties, ExpectedDefaultEncoding, messagePayload); }
static void Main() { ILogger logger = new LoggerConfiguration() .WriteTo.DurableHttpUsingFileSizeRolledBuffers( requestUri: "http://*****:*****@customer} placed {@order}", customer, order); Thread.Sleep(1000); } }
static void Main() { ILogger logger = new LoggerConfiguration() .WriteTo.DurableHttp( requestUri: "http://*****:*****@customer} placed {@order}", customer, order); Thread.Sleep(1000); } }
public async Task ServiceBusQueueMessagePumpWithServiceBusDeadLetterAfterContextPredicate_PublishServiceBusMessage_MessageSuccessfullyProcessed() { // Arrange var config = TestConfig.Create(); string connectionString = config.GetServiceBusConnectionString(ServiceBusEntityType.Queue); var options = new WorkerOptions(); options.AddServiceBusQueueMessagePump(configuration => connectionString, opt => opt.AutoComplete = false) .WithServiceBusMessageHandler <CustomerMessageHandler, Customer>(context => context.Properties["Topic"].ToString() == "Customers") .WithServiceBusMessageHandler <OrdersAzureServiceBusDeadLetterMessageHandler, Order>(context => context.Properties["Topic"].ToString() == "Orders") .WithMessageHandler <PassThruOrderMessageHandler, Order, AzureServiceBusMessageContext>((AzureServiceBusMessageContext context) => false); Order order = OrderGenerator.Generate(); await using (var worker = await Worker.StartNewAsync(options)) await using (var service = await TestMessagePumpService.StartNewAsync(config, _logger)) { // Act await service.SendMessageToServiceBusAsync(connectionString, order.AsServiceBusMessage()); // Assert await service.AssertDeadLetterMessageAsync(connectionString); } }
static void Main() { ILogger logger = new LoggerConfiguration() .WriteTo.Udp( "localhost", 7071, AddressFamily.InterNetwork, new Log4jTextFormatter()) .WriteTo.Console() .CreateLogger(); var customerGenerator = new CustomerGenerator(); var orderGenerator = new OrderGenerator(); while (true) { var customer = customerGenerator.Generate(); var order = orderGenerator.Generate(); logger.Information("{@customer} placed {@order}", customer, order); Thread.Sleep(1000); } }