public async Task ServiceBusTopicMessagePumpWithNamespaceScopedConnectionString_PublishesServiceBusMessage_MessageSuccessfullyProcessed() { // Arrange var config = TestConfig.Create(); string topicConnectionString = config.GetServiceBusConnectionString(ServiceBusEntityType.Topic); var properties = ServiceBusConnectionStringProperties.Parse(topicConnectionString); string namespaceConnectionString = properties.GetNamespaceConnectionString(); var options = new WorkerOptions(); options.AddEventGridPublisher(config) .AddServiceBusTopicMessagePump( topicName: properties.EntityPath, subscriptionName: "Test-Receive-All-Topic-Only", getConnectionStringFromConfigurationFunc: configuration => namespaceConnectionString, configureMessagePump: opt => opt.AutoComplete = true) .WithServiceBusMessageHandler <OrdersAzureServiceBusMessageHandler, Order>(); // Act await using (var worker = await Worker.StartNewAsync(options)) await using (var service = await TestMessagePumpService.StartNewAsync(config, _logger)) { // Assert await service.SimulateMessageProcessingAsync(topicConnectionString); } }
public async Task ServiceBusQueueMessagePumpUsingManagedIdentity_PublishServiceBusMessage_MessageSuccessfullyProcessed() { // Arrange var config = TestConfig.Create(); string connectionString = config.GetServiceBusConnectionString(ServiceBusEntityType.Queue); ServiceBusConnectionStringProperties properties = ServiceBusConnectionStringProperties.Parse(connectionString); ServicePrincipal servicePrincipal = config.GetServiceBusServicePrincipal(); string tenantId = config.GetTenantId(); using (TemporaryEnvironmentVariable.Create(EnvironmentVariables.AzureTenantId, tenantId)) using (TemporaryEnvironmentVariable.Create(EnvironmentVariables.AzureServicePrincipalClientId, servicePrincipal.ClientId)) using (TemporaryEnvironmentVariable.Create(EnvironmentVariables.AzureServicePrincipalClientSecret, servicePrincipal.ClientSecret)) { var options = new WorkerOptions(); options.AddEventGridPublisher(config) .AddServiceBusQueueMessagePumpUsingManagedIdentity( queueName: properties.EntityPath, serviceBusNamespace: properties.FullyQualifiedNamespace, clientId: servicePrincipal.ClientId, configureMessagePump: opt => opt.AutoComplete = true) .WithServiceBusMessageHandler <OrdersAzureServiceBusMessageHandler, Order>(); // Act await using (var worker = await Worker.StartNewAsync(options)) await using (var service = await TestMessagePumpService.StartNewAsync(config, _logger)) { // Assert await service.SimulateMessageProcessingAsync(connectionString); } } }
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); } }
public async Task ServiceBusQueueMessagePumpWithContextAndBodyFilteringWithSerializer_RoutesServiceBusMessage_MessageSuccessfullyProcessed() { // Arrange var config = TestConfig.Create(); string connectionString = config.GetServiceBusConnectionString(ServiceBusEntityType.Queue); var options = new WorkerOptions(); options.AddEventGridPublisher(config) .AddServiceBusQueueMessagePump(configuration => connectionString, opt => opt.AutoComplete = true) .WithServiceBusMessageHandler <PassThruOrderMessageHandler, Order>(messageContextFilter: context => false) .WithServiceBusMessageHandler <CustomerMessageHandler, Customer>(messageBodyFilter: message => true) .WithServiceBusMessageHandler <OrderBatchMessageHandler, OrderBatch>( messageContextFilter: context => context != null, messageBodySerializerImplementationFactory: serviceProvider => { var logger = serviceProvider.GetService <ILogger <OrderBatchMessageBodySerializer> >(); return(new OrderBatchMessageBodySerializer(logger)); }, messageBodyFilter: message => message.Orders.Length == 1); // Act await using (var worker = await Worker.StartNewAsync(options)) await using (var service = await TestMessagePumpService.StartNewAsync(config, _logger)) { // Assert await service.SimulateMessageProcessingAsync(connectionString); } }
/// <summary> /// Starts a new instance of the <see cref="TestMessagePumpService"/> type to simulate messages. /// </summary> public static async Task <TestMessagePumpService> StartNewAsync( ServiceBusEntity entity, TestConfig config, ITestOutputHelper outputWriter) { var service = new TestMessagePumpService(entity, config, outputWriter); await service.StartAsync(); return(service); }
/// <summary> /// Starts a new instance of the <see cref="TestMessagePumpService"/> type to simulate messages. /// </summary> /// <param name="config">The configuration instance to retrieve the Azure Service Bus test infrastructure authentication information.</param> /// <param name="logger">The instance to log diagnostic messages during the interaction with teh Azure Service Bus test infrastructure.</param> /// <exception cref="ArgumentNullException">Thrown when the <paramref name="config"/> or the <paramref name="logger"/> is <c>null</c>.</exception> public static async Task <TestMessagePumpService> StartNewAsync( TestConfig config, ILogger logger) { Guard.NotNull(config, nameof(config)); Guard.NotNull(logger, nameof(logger)); var service = new TestMessagePumpService(config, logger); await service.StartAsync(); return(service); }
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)); } }
public async Task ServiceBusMessagePump_RotateServiceBusConnectionKeys_MessagePumpRestartsThenMessageSuccessfullyProcessed() { // Arrange var config = TestConfig.Create(); KeyRotationConfig keyRotationConfig = config.GetKeyRotationConfig(); _logger.LogInformation("Using Service Principal [ClientID: '{ClientId}']", keyRotationConfig.ServicePrincipal.ClientId); var client = new ServiceBusConfiguration(keyRotationConfig, _logger); string freshConnectionString = await client.RotateConnectionStringKeysForQueueAsync(KeyType.PrimaryKey); ServicePrincipalAuthentication authentication = keyRotationConfig.ServicePrincipal.CreateAuthentication(); IKeyVaultClient keyVaultClient = await authentication.AuthenticateAsync(); await SetConnectionStringInKeyVaultAsync(keyVaultClient, keyRotationConfig, freshConnectionString); var options = new WorkerOptions(); options.AddEventGridPublisher(config) .AddSingleton <ISecretProvider>(serviceProvider => { return(new KeyVaultSecretProvider( new ServicePrincipalAuthentication(keyRotationConfig.ServicePrincipal.ClientId, keyRotationConfig.ServicePrincipal.ClientSecret), new KeyVaultConfiguration(keyRotationConfig.KeyVault.VaultUri))); }) .AddServiceBusQueueMessagePump(keyRotationConfig.KeyVault.SecretName, opt => opt.AutoComplete = true) .WithServiceBusMessageHandler <OrdersAzureServiceBusMessageHandler, Order>(); await using (var worker = await Worker.StartNewAsync(options)) { string newSecondaryConnectionString = await client.RotateConnectionStringKeysForQueueAsync(KeyType.SecondaryKey); await SetConnectionStringInKeyVaultAsync(keyVaultClient, keyRotationConfig, newSecondaryConnectionString); await using (var service = await TestMessagePumpService.StartNewAsync(config, _logger)) { // Act string newPrimaryConnectionString = await client.RotateConnectionStringKeysForQueueAsync(KeyType.PrimaryKey); // Assert await service.SimulateMessageProcessingAsync(newPrimaryConnectionString); } } }
public async Task ServiceBusMessagePumpWithServiceBusFallback_PublishServiceBusMessage_MessageSuccessfullyProcessed() { // Arrange var config = TestConfig.Create(); string connectionString = config.GetServiceBusConnectionString(ServiceBusEntityType.Queue); var options = new WorkerOptions(); options.AddEventGridPublisher(config) .AddServiceBusQueueMessagePump(configuration => connectionString, opt => opt.AutoComplete = true) .WithServiceBusMessageHandler <PassThruOrderMessageHandler, Order>((AzureServiceBusMessageContext context) => false) .WithServiceBusFallbackMessageHandler <OrdersServiceBusFallbackMessageHandler>(); await using (var worker = await Worker.StartNewAsync(options)) await using (var service = await TestMessagePumpService.StartNewAsync(config, _logger)) { // Act / Assert await service.SimulateMessageProcessingAsync(connectionString); } }
public async Task ServiceBusTopicMessagePumpWithServiceBusAbandon_PublishServiceBusMessage_MessageSuccessfullyProcessed() { // Arrange var config = TestConfig.Create(); string connectionString = config.GetServiceBusConnectionString(ServiceBusEntityType.Topic); var options = new WorkerOptions(); options.AddEventGridPublisher(config) .AddServiceBusTopicMessagePump("Test-Receive-All-Topic-Only", configuration => connectionString, opt => opt.AutoComplete = false) .WithServiceBusMessageHandler <OrdersAzureServiceBusAbandonMessageHandler, Order>(); await using (var worker = await Worker.StartNewAsync(options)) await using (var service = await TestMessagePumpService.StartNewAsync(config, _logger)) { // Act await service.SimulateMessageProcessingAsync(connectionString); } }
public async Task ServiceBusQueueMessagePumpWithIgnoringMissingMembersDeserialization_PublishesServiceBusMessage_MessageGetsProcessedByDifferentMessageHandler() { // Arrange var config = TestConfig.Create(); string connectionString = config.GetServiceBusConnectionString(ServiceBusEntityType.Queue); var options = new WorkerOptions(); options.AddEventGridPublisher(config) .AddServiceBusQueueMessagePump(configuration => connectionString, opt => opt.Deserialization.AdditionalMembers = AdditionalMemberHandling.Ignore) .WithServiceBusMessageHandler <OrderV2AzureServiceBusMessageHandler, OrderV2>(); // Act await using (var worker = await Worker.StartNewAsync(options)) await using (var service = await TestMessagePumpService.StartNewAsync(config, _logger)) { // Assert await service.SimulateMessageProcessingAsync(connectionString); } }
public async Task ServiceBusTopicMessagePumpWithBodyFiltering_RoutesServiceBusMessage_MessageSuccessfullyProcessed() { // Arrange var config = TestConfig.Create(); string connectionString = config.GetServiceBusConnectionString(ServiceBusEntityType.Topic); var options = new WorkerOptions(); options.AddEventGridPublisher(config) .AddServiceBusTopicMessagePump("Test-Receive-All-Topic-Only", configuration => connectionString, opt => opt.AutoComplete = true) .WithServiceBusMessageHandler <CustomerMessageHandler, Customer>((Customer body) => body is null) .WithServiceBusMessageHandler <OrdersAzureServiceBusMessageHandler, Order>((Order body) => body.Id != null) .WithMessageHandler <PassThruOrderMessageHandler, Order, AzureServiceBusMessageContext>((Order body) => false); // Act await using (var worker = await Worker.StartNewAsync(options)) await using (var service = await TestMessagePumpService.StartNewAsync(config, _logger)) { // Assert await service.SimulateMessageProcessingAsync(connectionString); } }
public async Task ServiceBusMessagePump_PublishServiceBusMessage_MessageSuccessfullyProcessed() { // Arrange var config = TestConfig.Create(); const ServiceBusEntity entity = ServiceBusEntity.Queue; var commandArguments = new[] { CommandArgument.CreateSecret("EVENTGRID_TOPIC_URI", config.GetTestInfraEventGridTopicUri()), CommandArgument.CreateSecret("EVENTGRID_AUTH_KEY", config.GetTestInfraEventGridAuthKey()), CommandArgument.CreateSecret("ARCUS_SERVICEBUS_CONNECTIONSTRING", config.GetServiceBusConnectionString(entity)), }; using (var project = await ServiceBusWorkerProject.StartNewWithAsync <ServiceBusQueueProgram>(config, _outputWriter, commandArguments)) { await using (var service = await TestMessagePumpService.StartNewAsync(entity, config, _outputWriter)) { // Act / Assert await service.SimulateMessageProcessingAsync(); } } }
public async Task ServiceBusQueueMessagePumpWithNamespaceScopedConnectionString_PublishesServiceBusMessage_MessageSuccessfullyProcessed() { // Arrange var config = TestConfig.Create(); string entityConnectionString = config.GetServiceBusConnectionString(ServiceBusEntityType.Queue); var properties = ServiceBusConnectionStringProperties.Parse(entityConnectionString); string namespaceConnectionString = properties.GetNamespaceConnectionString(); var options = new WorkerOptions(); options.AddEventGridPublisher(config) .AddServiceBusQueueMessagePump(properties.EntityPath, configuration => namespaceConnectionString, opt => opt.AutoComplete = true) .WithServiceBusMessageHandler <OrdersAzureServiceBusMessageHandler, Order>(); // Act await using (var worker = await Worker.StartNewAsync(options)) await using (var service = await TestMessagePumpService.StartNewAsync(config, _logger)) { // Assert await service.SimulateMessageProcessingAsync(entityConnectionString); } }
public async Task ServiceBusTopicMessagePumpWithSubscriptionNameOver50_PublishServiceBusMessage_MessageSuccessfullyProcessed() { // Arrange var config = TestConfig.Create(); string connectionString = config.GetServiceBusConnectionString(ServiceBusEntityType.Topic); var options = new WorkerOptions(); options.AddEventGridPublisher(config) .AddServiceBusTopicMessagePump( "Test-Receive-All-Topic-Only-with-an-azure-servicebus-topic-subscription-name-over-50-characters", configuration => connectionString, opt => opt.AutoComplete = true) .WithServiceBusMessageHandler <OrdersAzureServiceBusMessageHandler, Order>(); // Act await using (var worker = await Worker.StartNewAsync(options)) await using (var service = await TestMessagePumpService.StartNewAsync(config, _logger)) { // Assert await service.SimulateMessageProcessingAsync(connectionString); } }
public async Task ServiceBusQueueMessagePumpWithContextAndBodyFiltering_RoutesServiceBusMessage_MessageSuccessfullyProcessed() { // Arrange var config = TestConfig.Create(); string connectionString = config.GetServiceBusConnectionString(ServiceBusEntityType.Queue); var options = new WorkerOptions(); options.AddEventGridPublisher(config) .AddServiceBusQueueMessagePump(configuration => connectionString, opt => opt.AutoComplete = true) .WithServiceBusMessageHandler <CustomerMessageHandler, Customer>(context => context.Properties.ContainsKey("NotExisting"), body => false) .WithServiceBusMessageHandler <OrdersAzureServiceBusMessageHandler, Order>( context => context.Properties["Topic"].ToString() == "Orders", body => body.Id != null); // Act await using (var worker = await Worker.StartNewAsync(options)) await using (var service = await TestMessagePumpService.StartNewAsync(config, _logger)) { // Assert await service.SimulateMessageProcessingAsync(connectionString); } }
public async Task ServiceBusQueueMessagePumpWithBatchedMessages_PublishServiceBusMessage_MessageSuccessfullyProcessed() { // Arrange var config = TestConfig.Create(); string connectionString = config.GetServiceBusConnectionString(ServiceBusEntityType.Queue); var options = new WorkerOptions(); options.AddEventGridPublisher(config) .AddServiceBusQueueMessagePump(configuration => connectionString, opt => opt.AutoComplete = true) .WithServiceBusMessageHandler <OrderBatchMessageHandler, OrderBatch>(messageBodySerializerImplementationFactory: serviceProvider => { var logger = serviceProvider.GetService <ILogger <OrderBatchMessageBodySerializer> >(); return(new OrderBatchMessageBodySerializer(logger)); }); // Act await using (var worker = await Worker.StartNewAsync(options)) await using (var service = await TestMessagePumpService.StartNewAsync(config, _logger)) { // Assert await service.SimulateMessageProcessingAsync(connectionString); } }
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); } }