### Minimal ASP.NET Core Setup Source: https://havret.github.io/dotnet-activemq-artemis-client/docs/dependency-injection This example demonstrates registering ArtemisNetClient services and configuring a connection, consumer, and producer within an ASP.NET Core application. Ensure AddActiveMqHostedService is called to automatically start consumers and producers. ```csharp var builder = WebApplication.CreateBuilder(args); builder.Services.AddActiveMqHostedService(); var endpoint = Endpoint.Create( host: "localhost", port: 5672, user: "artemis", password: "artemis"); var activeMq = builder.Services.AddActiveMq( name: "my-artemis", endpoints: new[] { endpoint }); activeMq.AddConsumer( address: "orders.incoming", routingType: RoutingType.Anycast, handler: async (message, consumer, serviceProvider, cancellationToken) => { var publisher = serviceProvider.GetRequiredService(); var orderId = message.GetBody(); await publisher.PublishAccepted(orderId, cancellationToken); await consumer.AcceptAsync(message); }); activeMq.AddProducer("orders.events", RoutingType.Multicast); var app = builder.Build(); app.Run(); public sealed class OrderEventsProducer { private readonly IProducer _producer; public OrderEventsProducer(IProducer producer) => _producer = producer; public Task PublishAccepted(string orderId, CancellationToken cancellationToken) { return _producer.SendAsync(new Message($"accepted:{orderId}"), cancellationToken); } } ``` -------------------------------- ### Install Hosting Package Source: https://havret.github.io/dotnet-activemq-artemis-client/docs/dependency-injection For ASP.NET Core or generic hosted applications, install the hosting package in addition to the DI package. ```bash dotnet add package ArtemisNetClient.Extensions.Hosting ``` -------------------------------- ### Add ArtemisNetClient.Testing NuGet Package Source: https://havret.github.io/dotnet-activemq-artemis-client/docs/testing Install the ArtemisNetClient.Testing NuGet package using the dotnet CLI. ```bash dotnet add package ArtemisNetClient.Testing ``` -------------------------------- ### Complete Example: Multi-Criteria Filtering Source: https://havret.github.io/dotnet-activemq-artemis-client/docs/message-filtering Demonstrates a complete scenario of creating a consumer with a complex filter expression and sending messages, illustrating which messages are received based on the criteria. This example showcases the practical application of combined filtering logic. ```csharp await using var connection = await connectionFactory.CreateAsync(endpoint); var address = "orders"; // Create consumer that only receives high-priority, pending orders for the premium tier await using var consumer = await connection.CreateConsumerAsync(new ConsumerConfiguration { Address = address, RoutingType = RoutingType.Anycast, FilterExpression = "AMQPriority >= 7 AND status = 'pending' AND tier = 'premium'" }); // Create producer and send various messages await using var producer = await connection.CreateProducerAsync(address, RoutingType.Anycast); // This message will be received (matches all criteria) await producer.SendAsync(new Message("order1") { Priority = 9, ApplicationProperties = { ["status"] = "pending", ["tier"] = "premium" } }); // This message will NOT be received (priority too low) await producer.SendAsync(new Message("order2") { Priority = 4, ApplicationProperties = { ["status"] = "pending", ["tier"] = "premium" } }); // This message will NOT be received (wrong status) await producer.SendAsync(new Message("order3") { Priority = 8, ApplicationProperties = { ["status"] = "completed", ["tier"] = "premium" } }); var message = await consumer.ReceiveAsync(cancellationToken); Console.WriteLine(message.GetBody()); // Output: "order1" ``` -------------------------------- ### Install ActiveMQ.Artemis.Client NuGet Package Source: https://havret.github.io/dotnet-activemq-artemis-client/docs/getting-started Use the dotnet CLI to add the ActiveMQ.Artemis.Client NuGet package to your project. ```bash dotnet add package ArtemisNetClient ``` -------------------------------- ### Install DI-only Package Source: https://havret.github.io/dotnet-activemq-artemis-client/docs/dependency-injection Use this command to add the dependency injection extensions package for ArtemisNetClient. ```bash dotnet add package ArtemisNetClient.Extensions.DependencyInjection ``` -------------------------------- ### Enable Topology Declaration for Consumers Source: https://havret.github.io/dotnet-activemq-artemis-client/docs/dependency-injection Enable queue and address declaration when the application starts. This is useful for ensuring that messaging infrastructure is set up automatically. ```csharp activeMq .AddConsumer( address: "orders.incoming", routingType: RoutingType.Anycast, queue: "orders-service", handler: async (message, consumer, serviceProvider, cancellationToken) => { await consumer.AcceptAsync(message); }) .EnableQueueDeclaration() .EnableAddressDeclaration(); ``` -------------------------------- ### Configure Linear Backoff Recovery Policy Source: https://havret.github.io/dotnet-activemq-artemis-client/docs/auto-recovery Use Linear Backoff for connection recovery with delays that increase linearly. This example sets 5 retries with initial delays of 100, 200, 300, 400, and 500ms. ```csharp var linearBackoff = RecoveryPolicyFactory.LinearBackoff( initialDelay: TimeSpan.FromMilliseconds(100), retryCount: 5); ``` -------------------------------- ### Configure Linear Backoff with Custom Factor Source: https://havret.github.io/dotnet-activemq-artemis-client/docs/auto-recovery Customize the linear backoff delay by specifying a growth factor. This example uses a factor of 2, resulting in delays of 100, 300, 500, 700, and 900ms. ```csharp var linearBackoff = RecoveryPolicyFactory.LinearBackoff( initialDelay: TimeSpan.FromMilliseconds(100), retryCount: 5, factor: 2); ``` -------------------------------- ### Configure Exponential Backoff with Custom Factor Source: https://havret.github.io/dotnet-activemq-artemis-client/docs/auto-recovery Customize the exponential backoff delay by specifying a growth factor. This example uses a factor of 4.0, resulting in delays of 100, 200, 400, 800, and 1600ms. ```csharp var exponentialBackoff = RecoveryPolicyFactory.ExponentialBackoff( initialDelay: TimeSpan.FromMilliseconds(100), retryCount: 5, factor: 4.0); ``` -------------------------------- ### Configure Exponential Backoff Recovery Policy Source: https://havret.github.io/dotnet-activemq-artemis-client/docs/auto-recovery Use Exponential Backoff for connection recovery where delays increase exponentially (initialDelay x 2^attempt). This example sets 5 retries with an initial delay of 100ms. ```csharp var exponentialBackoff = RecoveryPolicyFactory.ExponentialBackoff( initialDelay: TimeSpan.FromMilliseconds(100), retryCount: 5); ``` -------------------------------- ### Configure Constant Backoff Recovery Policy Source: https://havret.github.io/dotnet-activemq-artemis-client/docs/auto-recovery Use Constant Backoff to retry connection recovery with a fixed delay between attempts. This example sets 5 retries with a 1-second delay. ```csharp var constantBackoff = RecoveryPolicyFactory.ConstantBackoff( delay: TimeSpan.FromSeconds(1), retryCount: 5); ``` -------------------------------- ### Demonstrate NoLocal Filter Functionality Source: https://havret.github.io/dotnet-activemq-artemis-client/docs/message-filtering This example illustrates the NoLocal filter by sending messages from two different connections to the same multicast address. The consumer, configured with NoLocalFilter=true on connection 1, will only receive the message sent from connection 2, effectively filtering out its own connection's message. ```csharp var address = "news.updates"; // Create first connection with producer and consumer await using var connection1 = await connectionFactory.CreateAsync(endpoint); await using var producer1 = await connection1.CreateProducerAsync(address, RoutingType.Multicast); await using var consumer = await connection1.CreateConsumerAsync(new ConsumerConfiguration { Address = address, RoutingType = RoutingType.Multicast, NoLocalFilter = true }); // Create second connection with producer await using var connection2 = await connectionFactory.CreateAsync(endpoint); await using var producer2 = await connection2.CreateProducerAsync(address, RoutingType.Multicast); // Send messages from both connections await producer1.SendAsync(new Message("from connection 1")); await producer2.SendAsync(new Message("from connection 2")); // Consumer will only receive the message from connection 2 var message = await consumer.ReceiveAsync(cancellationToken); Console.WriteLine(message.GetBody()); // Output: "from connection 2" ``` -------------------------------- ### Retrieve Message Payload Source: https://havret.github.io/dotnet-activemq-artemis-client/docs/message-payload Get the message body by specifying the expected type `T`. Returns `default(T)` if the type does not match the payload type. ```csharp var body = message.GetBody(); ``` -------------------------------- ### Configure Fast First Recovery Policy Source: https://havret.github.io/dotnet-activemq-artemis-client/docs/auto-recovery Enable immediate recovery after the first connection failure by setting `fastFirst: true` in the recovery policy factory. ```csharp var recoveryPolicy = RecoveryPolicyFactory.ExponentialBackoff( initialDelay: TimeSpan.FromMilliseconds(100), retryCount: 5, factor: 4.0, fastFirst: true); ``` -------------------------------- ### Configure Failover with Multiple Endpoints Source: https://havret.github.io/dotnet-activemq-artemis-client/docs/auto-recovery Set up failover by providing a list of endpoints to `ConnectionFactory.CreateAsync`. The client will attempt to reconnect to subsequent endpoints in a round-robin fashion if a connection is lost. ```csharp var masterEndpoint = Endpoint.Create( host: "master", port: 5672, user: "guest", password: "guest", scheme: Scheme.Amqp); var slaveEndpoint = Endpoint.Create( host: "slave", port: 5672, user: "guest", password: "guest", scheme: Scheme.Amqp); var connectionFactory = new ConnectionFactory(); var connection = await connectionFactory.CreateAsync(new[] { masterEndpoint, slaveEndpoint }); ``` -------------------------------- ### Request Side Registration (Dependency Injection) Source: https://havret.github.io/dotnet-activemq-artemis-client/docs/request-reply Register `IRequestReplyClient` with `AddRequestReplyClient()` and `AddActiveMqHostedService()` for automatic startup in hosted applications. ```csharp var builder = WebApplication.CreateBuilder(args); builder.Services.AddActiveMqHostedService(); var endpoint = Endpoint.Create("localhost", 5672, "guest", "guest"); var activeMq = builder.Services.AddActiveMq("bookstore-cluster", new[] { endpoint }); activeMq.AddRequestReplyClient(); public sealed class BookstoreRequestClient { private readonly IRequestReplyClient _requestReplyClient; public BookstoreRequestClient(IRequestReplyClient requestReplyClient) { _requestReplyClient = requestReplyClient; } public Task SendAsync(string payload, CancellationToken cancellationToken) { return _requestReplyClient.SendAsync( "bookstore.requests", RoutingType.Anycast, new Message(payload), cancellationToken); } } ``` -------------------------------- ### Create an IConsumer Source: https://havret.github.io/dotnet-activemq-artemis-client/docs/getting-started Create an IConsumer instance to receive messages from a specific queue. Ensure the connection is established before creating the consumer. ```csharp var consumer = await connection.CreateConsumerAsync("a1", RoutingType.Anycast); ``` -------------------------------- ### Configure Connection Events Source: https://havret.github.io/dotnet-activemq-artemis-client/docs/dependency-injection Set up event handlers for the created IConnection, such as listening for connection closed events. This allows for custom logic when the connection state changes. ```csharp activeMq.ConfigureConnection((_, connection) => { connection.ConnectionClosed += (_, args) => { Console.WriteLine($"Connection closed. Error={args.Error}"); }; }); ``` -------------------------------- ### Establish a Connection to Artemis Broker Source: https://havret.github.io/dotnet-activemq-artemis-client/docs/getting-started Instantiate a ConnectionFactory and use it to asynchronously create a connection to the specified Artemis broker endpoint. ```csharp var connectionFactory = new ConnectionFactory(); var endpoint = Endpoint.Create("localhost", 5672, "guest", "guest"); var connection = await connectionFactory.CreateAsync(endpoint); ``` -------------------------------- ### Response Side Implementation (Core Client) Source: https://havret.github.io/dotnet-activemq-artemis-client/docs/request-reply Create a consumer to receive requests. When sending a reply, ensure the `ReplyTo` address and `CorrelationId` from the incoming message are used. ```csharp var connectionFactory = new ConnectionFactory(); var endpoint = Endpoint.Create("localhost", 5672, "guest", "guest"); var connection = await connectionFactory.CreateAsync(endpoint); await using var consumer = await connection.CreateConsumerAsync("my-address", RoutingType.Anycast); var request = await consumer.ReceiveAsync(); await using var producer = await connection1.CreateAnonymousProducerAsync(); await producer.SendAsync(request.ReplyTo, new Message("bar") { CorrelationId = request.CorrelationId }); await consumer.AcceptAsync(request); ``` -------------------------------- ### Import ActiveMQ.Artemis.Client Namespace Source: https://havret.github.io/dotnet-activemq-artemis-client/docs/getting-started Import the necessary namespace to use the core API interfaces and classes for the .NET Client for Apache Artemis. ```csharp using ActiveMQ.Artemis.Client; ``` -------------------------------- ### Request Side Implementation (Core Client) Source: https://havret.github.io/dotnet-activemq-artemis-client/docs/request-reply Use `IRequestReplyClient` to send messages and asynchronously listen for responses. Ensure the connection and client are properly disposed. ```csharp var connectionFactory = new ConnectionFactory(); var endpoint = Endpoint.Create("localhost", 5672, "guest", "guest"); var connection = await connectionFactory.CreateAsync(endpoint); await using var requestReplyClient = await connection.CreateRequestReplyClientAsync(); var response = await requestReplyClient.SendAsync("my-address", RoutingType.Anycast, new Message("foo"), default); var test = response.GetBody(); // bar ``` -------------------------------- ### Import Namespaces Source: https://havret.github.io/dotnet-activemq-artemis-client/docs/dependency-injection These are the essential namespaces to import when using ArtemisNetClient's dependency injection and hosting extensions. ```csharp using ActiveMQ.Artemis.Client; using ActiveMQ.Artemis.Client.Extensions.DependencyInjection; using ActiveMQ.Artemis.Client.Extensions.Hosting; ``` -------------------------------- ### Create an Endpoint Configuration Source: https://havret.github.io/dotnet-activemq-artemis-client/docs/getting-started Configure the connection endpoint for an Artemis broker, specifying host, port, user, password, and security scheme. ```csharp Endpoint.Create( host: "localhost", port: 5672, user: "guest", password: "guest", scheme: Scheme.Amqp); ``` -------------------------------- ### Response Side Registration (Dependency Injection) Source: https://havret.github.io/dotnet-activemq-artemis-client/docs/request-reply Register a consumer for incoming requests and an anonymous producer for replies. The handler must use `message.ReplyTo` and copy `message.CorrelationId`. ```csharp var builder = WebApplication.CreateBuilder(args); builder.Services.AddActiveMqHostedService(); var endpoint = Endpoint.Create("localhost", 5672, "guest", "guest"); var activeMq = builder.Services.AddActiveMq("bookstore-cluster", new[] { endpoint }); activeMq.AddAnonymousProducer(); activeMq.AddConsumer( address: "bookstore.requests", routingType: RoutingType.Anycast, handler: async (message, consumer, serviceProvider, cancellationToken) => { var replyProducer = serviceProvider.GetRequiredService(); await replyProducer.SendAsync( message.ReplyTo, new Message("accepted") { CorrelationId = message.CorrelationId }, cancellationToken); await consumer.AcceptAsync(message); }); public sealed class ReplyProducer { private readonly IAnonymousProducer _producer; public ReplyProducer(IAnonymousProducer producer) { _producer = producer; } public Task SendAsync(string address, Message message, CancellationToken cancellationToken) { return _producer.SendAsync(address, message, cancellationToken); } } ``` -------------------------------- ### Creating a Producer for a Specific Address Source: https://havret.github.io/dotnet-activemq-artemis-client/docs/getting-started Use IProducer to send messages to a specific address and routing type. Create producers once and reuse them for efficiency. ```csharp var producer = await connection.CreateProducerAsync("a1", RoutingType.Anycast); ``` -------------------------------- ### Configure Linear Backoff with Max Delay Source: https://havret.github.io/dotnet-activemq-artemis-client/docs/auto-recovery Set a maximum delay for linear backoff when using an infinite number of retries. This prevents excessively long waits between recovery attempts. ```csharp var linearBackoff = RecoveryPolicyFactory.LinearBackoff( initialDelay: TimeSpan.FromMilliseconds(100), maxDelay: TimeSpan.FromSeconds(15)); ``` -------------------------------- ### Create a New Message Source: https://havret.github.io/dotnet-activemq-artemis-client/docs/message-payload Instantiate a new `Message` object with a string payload. ```csharp var message = new Message("foo"); ``` -------------------------------- ### Configure Connection Factory Settings Source: https://havret.github.io/dotnet-activemq-artemis-client/docs/dependency-injection Customize the connection factory for transport, logging, recovery, or message ID settings. This is done by providing a configuration delegate to ConfigureConnectionFactory. ```csharp activeMq.ConfigureConnectionFactory((serviceProvider, factory) => { factory.LoggerFactory = serviceProvider.GetRequiredService(); factory.AutomaticRecoveryEnabled = true; }); ``` -------------------------------- ### Handle Request-Reply Messages and Send Response Source: https://havret.github.io/dotnet-activemq-artemis-client/docs/dependency-injection Configure a consumer to handle incoming requests, process them, and send a reply. The reply must include the original message's CorrelationId and be sent to the message.ReplyTo address. ```csharp activeMq.AddAnonymousProducer(); activeMq.AddConsumer( address: "bookstore.requests", routingType: RoutingType.Anycast, handler: async (message, consumer, serviceProvider, cancellationToken) => { var replyProducer = serviceProvider.GetRequiredService(); await replyProducer.SendAsync( message.ReplyTo, new Message("ok") { CorrelationId = message.CorrelationId }, cancellationToken); await consumer.AcceptAsync(message); }); ``` -------------------------------- ### Subscribing to Connection Recovery Errors Source: https://havret.github.io/dotnet-activemq-artemis-client/docs/auto-recovery Demonstrates how to subscribe to the ConnectionRecoveryError event to react when the client fails to reestablish a connection after a network interruption. ```csharp var connectionFactory = new ConnectionFactory(); var connection = await connectionFactory.CreateAsync(endpoint); connection.ConnectionRecoveryError += (sender, eventArgs) => { // react accordingly }; ``` -------------------------------- ### Configure Message Credit for a Consumer Source: https://havret.github.io/dotnet-activemq-artemis-client/docs/consumer-credit Set the message credit for a new consumer during its creation. The credit value must be at least 1. This configuration limits the number of messages a consumer can receive before acknowledging them. ```csharp var consumer = await connection.CreateConsumerAsync(new ConsumerConfiguration { Address = address, RoutingType = RoutingType.Multicast, Credit = 2 // Set message credit to 2 }); ``` -------------------------------- ### Configure ASP.NET Core Application with ArtemisNetClient Source: https://havret.github.io/dotnet-activemq-artemis-client/docs/testing This code configures an ASP.NET Core application to use ArtemisNetClient for messaging, including setting up a hosted service, defining endpoints, and configuring a consumer and producer. ```csharp var builder = WebApplication.CreateBuilder(args); builder.Services.AddActiveMqHostedService(); var endpoint = Endpoint.Create( host: "localhost", port: 5672, "artemis", "artemis" ); var activeMqBuilder = builder.Services.AddActiveMq(name: "my-artemis", endpoints: new[] {endpoint}); activeMqBuilder.AddConsumer(address: "foo", routingType: RoutingType.Anycast, handler: async (message, consumer, serviceProvider, cancellationToken) => { var body = message.GetBody(); var bar = body + "-" + "bar"; var producer = serviceProvider.GetRequiredService(); await producer.Publish(bar, cancellationToken); await consumer.AcceptAsync(message); }); activeMqBuilder.AddProducer("bar", RoutingType.Multicast); var app = builder.Build(); app.Run(); // this is required so we can use WebApplicationFactory to run the test server public partial class Program { } ``` -------------------------------- ### Sending a Message with a Producer Source: https://havret.github.io/dotnet-activemq-artemis-client/docs/getting-started Send a message using a pre-configured producer. Messages sent this way are automatically routed based on the producer's configuration. ```csharp await producer.SendAsync(new Message("foo")); ``` -------------------------------- ### Register Typed Request-Reply Client Source: https://havret.github.io/dotnet-activemq-artemis-client/docs/dependency-injection Register a typed wrapper for IRequestReplyClient to simplify sending requests. Ensure the client class has a constructor accepting IRequestReplyClient. ```csharp activeMq.AddRequestReplyClient(); public sealed class BookstoreRequestClient { private readonly IRequestReplyClient _client; public BookstoreRequestClient(IRequestReplyClient client) => _client = client; public Task SendAsync(string address, string payload, CancellationToken cancellationToken) { return _client.SendAsync( address, RoutingType.Anycast, new Message(payload), cancellationToken); } } ``` -------------------------------- ### Register Typed Producer for Order Events Source: https://havret.github.io/dotnet-activemq-artemis-client/docs/dependency-injection Register a typed producer for a specific address and routing type. The wrapper type is transient by default, but can be configured as Singleton or Scoped. ```csharp activeMq.AddProducer("orders.events", RoutingType.Multicast); public sealed class OrderEventsProducer { private readonly IProducer _producer; public OrderEventsProducer(IProducer producer) => _producer = producer; public Task PublishAccepted(string orderId, CancellationToken cancellationToken) { return _producer.SendAsync(new Message($"accepted:{orderId}"), cancellationToken); } } ``` -------------------------------- ### Send and Filter by Custom Application Property Source: https://havret.github.io/dotnet-activemq-artemis-client/docs/message-filtering Send messages with custom application properties and then filter consumers based on these properties. This allows for flexible message routing. ```csharp // Sending a message with custom properties await producer.SendAsync(new Message("order data") { ApplicationProperties = { ["color"] = "red", ["size"] = "large", ["quantity"] = 10 } }); // Filtering by custom property var consumer = await connection.CreateConsumerAsync(new ConsumerConfiguration { Address = address, RoutingType = RoutingType.Anycast, FilterExpression = "color = 'red'" }); ``` -------------------------------- ### Integration Test for ASP.NET Core Application with TestKit Source: https://havret.github.io/dotnet-activemq-artemis-client/docs/testing This integration test uses TestKit to spin up an in-memory broker and Microsoft.AspNetCore.Mvc.Testing to test an ASP.NET Core application. It sends a message, subscribes to an address, and asserts the received message content. ```csharp public class MyTests { [Fact] public async Task Test() { // setup the test kit var endpoint = Endpoint.Create( host: "localhost", port: 5672, "artemis", "artemis" ); using var testKit = new TestKit(endpoint); // setup the application await using var application = new WebApplicationFactory(); // trigger the app to start application.CreateClient(); // subscribe to the bar address using var subscription = testKit.Subscribe("bar"); // send a message to the application await testKit.SendMessageAsync("foo", new Message("my-payload")); // wait for a message sent from the application var message = await subscription.ReceiveAsync(); Assert.Equal("my-payload-bar", message.GetBody()); } } ``` -------------------------------- ### Check if Connection is Open Source: https://havret.github.io/dotnet-activemq-artemis-client/docs/connection-lifecycle Use the IsOpened property to check the current status of the connection to the broker. This helps in determining if the connection is still active. ```csharp var connectionFactory = new ConnectionFactory(); var connection = await connectionFactory.CreateAsync(endpoint); if (connection.IsOpened) { // connection is still opened } else { // connection to the broker has been lost } ``` -------------------------------- ### Accept Message Source: https://havret.github.io/dotnet-activemq-artemis-client/docs/message-acknowledgment Use AcceptAsync to signal successful message processing to the broker. The broker typically removes the message from the queue for destructive queues. ```csharp var message = await consumer.ReceiveAsync(); // process message... await consumer.AcceptAsync(message); ``` -------------------------------- ### Combine Filter Expression and NoLocal Filter Source: https://havret.github.io/dotnet-activemq-artemis-client/docs/message-filtering Use this configuration to create a consumer that receives messages with a 'priority' greater than 5 and originating from a different connection. Ensure the ActiveMQ Artemis client library is imported. ```csharp var consumer = await connection.CreateConsumerAsync(new ConsumerConfiguration { Address = address, RoutingType = RoutingType.Multicast, FilterExpression = "priority > 5", NoLocalFilter = true }); ``` -------------------------------- ### Pattern Matching with LIKE Operator Source: https://havret.github.io/dotnet-activemq-artemis-client/docs/message-filtering Utilize the LIKE operator with wildcard characters ('%' for any sequence of characters, '_' for a single character) for flexible string matching. This is ideal for partial string comparisons. ```csharp // Match departments starting with 'sales' FilterExpression = "department LIKE 'sales%'" ``` ```csharp // Match emails ending with '@example.com' FilterExpression = "email LIKE '%@example.com'" ``` ```csharp // Match code patterns: 'A', any character, then 'B' (e.g., 'AXB', 'A1B') FilterExpression = "code LIKE 'A_B'" ``` -------------------------------- ### Configuring Producer for Nondurable Messages Source: https://havret.github.io/dotnet-activemq-artemis-client/docs/message-durability Configures a producer to send nondurable messages by default. This reduces overhead and prioritizes performance over reliability, offering at-most-once delivery guarantees. ```csharp var producer = await connection.CreateProducerAsync(new ProducerConfiguration { Address = "a1", RoutingType = RoutingType.Anycast, MessageDurabilityMode = DurabilityMode.Nondurable }); ``` -------------------------------- ### Creating an Anonymous Producer Source: https://havret.github.io/dotnet-activemq-artemis-client/docs/getting-started Instantiate an IAnonymousProducer to send messages without pre-defining a target address. This is useful for dynamic routing scenarios. ```csharp var anonymousProducer = await connection.CreateAnonymousProducer(); ``` -------------------------------- ### Register Anonymous Producer for Dynamic Replies Source: https://havret.github.io/dotnet-activemq-artemis-client/docs/dependency-injection Register an anonymous producer when the producer needs to publish to multiple addresses dynamically. The wrapper type is transient by default. ```csharp activeMq.AddAnonymousProducer(); public sealed class ReplyProducer { private readonly IAnonymousProducer _producer; public ReplyProducer(IAnonymousProducer producer) => _producer = producer; public Task SendAsync(string address, Message message, CancellationToken cancellationToken) { return _producer.SendAsync(address, message, cancellationToken); } } ``` -------------------------------- ### Configure TCP Keep-Alive Settings Source: https://havret.github.io/dotnet-activemq-artemis-client/docs/connection-lifecycle Configure TCP Keep-Alive settings on the ConnectionFactory to enhance connection stability. This sends periodic signals to ensure the connection remains active. ```csharp var factory = new ConnectionFactory(); // Configure TCP Keep-Alive settings factory.TCP.KeepAliveTime = 30000; // 30 seconds factory.TCP.KeepAliveInterval = 1000; // 1 second ``` -------------------------------- ### Create Consumer with Filter Expression Source: https://havret.github.io/dotnet-activemq-artemis-client/docs/message-filtering Use this configuration to create a consumer that only receives messages matching a specific property value. ```csharp var consumer = await connection.CreateConsumerAsync(new ConsumerConfiguration { Address = address, RoutingType = RoutingType.Multicast, FilterExpression = "color = 'red'" }); ``` -------------------------------- ### Sending a Durable Message Source: https://havret.github.io/dotnet-activemq-artemis-client/docs/message-durability Demonstrates sending a durable message using the SendAsync method. Durable messages are persisted by the broker before acknowledgment, ensuring at-least-once delivery semantics. ```csharp await producer.SendAsync(new Message("foo")) ``` -------------------------------- ### Sending a Message with an Anonymous Producer Source: https://havret.github.io/dotnet-activemq-artemis-client/docs/getting-started Send a message using an anonymous producer, specifying the address and routing type at the time of sending. This provides flexibility for routing. ```csharp await anonymousProducer.SendAsync("a2", RoutingType.Multicast, new Message("foo")); ``` -------------------------------- ### Add ActiveMQ Consumer with Handler Source: https://havret.github.io/dotnet-activemq-artemis-client/docs/dependency-injection Registers a message consumer for a specified address and routing type. The handler processes incoming messages and acknowledges them. ```csharp activeMq.AddConsumer( address: "orders.incoming", routingType: RoutingType.Anycast, handler: async (message, consumer, serviceProvider, cancellationToken) => { var logger = serviceProvider.GetRequiredService>(); logger.LogInformation("Received order {OrderId}", message.GetBody()); await consumer.AcceptAsync(message); }); ``` -------------------------------- ### Receive a Message Source: https://havret.github.io/dotnet-activemq-artemis-client/docs/getting-started Retrieve a message from the consumer's buffer. If no messages are available, this method will asynchronously wait until a new message arrives. ```csharp var message = await consumer.ReceiveAsync(); ``` -------------------------------- ### Configure NoLocal Filter in Consumer Source: https://havret.github.io/dotnet-activemq-artemis-client/docs/message-filtering Set the 'NoLocalFilter' property to 'true' within the ConsumerConfiguration to enable this feature. This configuration is essential for preventing self-consumption of messages in multicast scenarios. ```csharp var consumer = await connection.CreateConsumerAsync(new ConsumerConfiguration { Address = address, RoutingType = RoutingType.Multicast, NoLocalFilter = true }); ``` -------------------------------- ### Set Default Message Priority on Producer Source: https://havret.github.io/dotnet-activemq-artemis-client/docs/message-priority Configure a message producer to send all messages with a specific priority by default. This is useful for establishing a baseline importance for messages from a particular source. ```csharp var producer = await connection.CreateProducerAsync(new ProducerConfiguration { Address = "a1", RoutingType = RoutingType.Anycast, MessagePriority = 9 }); ``` -------------------------------- ### Sending Multiple Messages Transactionally Source: https://havret.github.io/dotnet-activemq-artemis-client/docs/transactions Use this pattern to send a series of messages as a single atomic unit. All messages will be delivered only after `CommitAsync` is called. If any part of the operation fails, no messages will be delivered. ```csharp var connectionFactory = new ConnectionFactory(); var endpoint = Endpoint.Create("localhost", 5672, "guest", "guest"); var connection = await connectionFactory.CreateAsync(endpoint); await using (var transaction = new Transaction()) { await producer.SendAsync( address: "credit-queue", message: new Message("credit:500,account:a"), transaction: transaction ); await producer.SendAsync( address: "debit-queue", message: new Message("debit:500,account:b"), transaction: transaction); await transaction.CommitAsync(); } ``` -------------------------------- ### Handle Connection Closed Event Source: https://havret.github.io/dotnet-activemq-artemis-client/docs/connection-lifecycle Subscribe to the ConnectionClosed event to be notified when the connection to the broker is lost. This allows your application to react accordingly. ```csharp var connectionFactory = new ConnectionFactory(); var connection = await connectionFactory.CreateAsync(endpoint); connection.ConnectionClosed += (sender, eventArgs) => { // react accordingly }; ``` -------------------------------- ### Receive a Message with Cancellation Source: https://havret.github.io/dotnet-activemq-artemis-client/docs/getting-started Receive a message while allowing for cancellation. This is useful for gracefully shutting down the application by providing a CancellationToken. ```csharp var cts = new CancellationTokenSource(); var message = await consumer.ReceiveAsync(cts.Token); ``` -------------------------------- ### Reject Message Source: https://havret.github.io/dotnet-activemq-artemis-client/docs/message-acknowledgment Use Reject to inform the broker that a message cannot be processed. Rejected messages may be routed to the Dead Letter Queue (DLQ) if configured. ```csharp var message = await consumer.ReceiveAsync(); consumer.Reject(message); ``` -------------------------------- ### Filter with Combined Operators Source: https://havret.github.io/dotnet-activemq-artemis-client/docs/message-filtering Construct sophisticated filters by nesting logical operators like AND and OR within parentheses to control the order of evaluation. This allows for complex filtering logic. ```csharp FilterExpression = "AMQPriority > 5 AND (color = 'red' OR color = 'blue')" ``` ```csharp FilterExpression = "quantity BETWEEN 10 AND 100 AND status = 'pending'" ``` -------------------------------- ### Handle Message Delivery Count Source: https://havret.github.io/dotnet-activemq-artemis-client/docs/message-acknowledgment Check the DeliveryCount property to manage message retries. If the count exceeds a threshold, reject the message; otherwise, retry by modifying it. ```csharp var message = await consumer.ReceiveAsync(); if (message.DeliveryCount >= 3) { // too many retries, reject to DLQ consumer.Reject(message); } else { // retry later consumer.Modify(message, deliveryFailed: true, undeliverableHere: false); } ``` -------------------------------- ### IRecoveryPolicy Interface Definition Source: https://havret.github.io/dotnet-activemq-artemis-client/docs/auto-recovery Defines the interface for configuring automatic recovery behavior, including the maximum number of retry attempts and the delay between attempts. ```csharp public interface IRecoveryPolicy { int RetryCount { get; } TimeSpan GetDelay(int attempt); } ``` -------------------------------- ### Filter by AMQDurable Source: https://havret.github.io/dotnet-activemq-artemis-client/docs/message-filtering Filter messages based on their durability mode. Use 'DURABLE' for persistent messages and 'NON_DURABLE' for transient ones. ```csharp var consumer = await connection.CreateConsumerAsync(new ConsumerConfiguration { Address = address, RoutingType = RoutingType.Anycast, FilterExpression = "AMQDurable = 'DURABLE'" }); ``` -------------------------------- ### Inspect Connection Closed Error Source: https://havret.github.io/dotnet-activemq-artemis-client/docs/connection-lifecycle When the ConnectionClosed event is raised, you can inspect the ConnectionClosedEventArgs to determine the specific error that caused the connection termination. ```csharp connection.ConnectionClosed += (sender, eventArgs) => { // reason the connection was closed string reason = eventArgs.Error; _logger.LogWarning(reason); }; ``` -------------------------------- ### Override Producer Priority on Individual Message Source: https://havret.github.io/dotnet-activemq-artemis-client/docs/message-priority Send a message with a priority that overrides the default priority set on the producer. This allows for specific messages to be prioritized differently, even when sent through a producer with a default priority. ```csharp await producer.SendAsync(new Message("foo") { Priority = 0 // takes precedence over priority specified on producer level }); ``` -------------------------------- ### Transactional Message Acknowledgment and Sending Source: https://havret.github.io/dotnet-activemq-artemis-client/docs/transactions This pattern ensures that a received message is only acknowledged after a new message, generated from its processing, is successfully sent. Both operations are committed together atomically. ```csharp var endpoint = Endpoint.Create("localhost", 5672, "guest", "guest"); var connectionFactory = new ConnectionFactory(); await using var connection = await connectionFactory.CreateAsync(endpoint); await using var producer = await connection.CreateProducerAsync("my-address-2", RoutingType.Anycast); await using var consumer = await connection.CreateConsumerAsync("my-address-1", RoutingType.Anycast); var msg1 = await consumer.ReceiveAsync(); await using (var transaction = new Transaction()) { // transactionally acknowledge message await consumer.AcceptAsync(msg1, transaction); var result = DoSomeProcessing(msg1); var msg2 = new Message(result); // transactionally send another message await producer.SendAsync(msg2, transaction); // commit the two operations await transaction.CommitAsync(); } ``` -------------------------------- ### Filter with AND Operator Source: https://havret.github.io/dotnet-activemq-artemis-client/docs/message-filtering Use the AND operator to combine multiple conditions, ensuring all conditions must be met for a message to be received. This is useful for precise message selection. ```csharp FilterExpression = "color = 'red' AND size = 'large'" ``` -------------------------------- ### Filter by AMQPriority Source: https://havret.github.io/dotnet-activemq-artemis-client/docs/message-filtering Filter messages based on their priority level (0-9). Use this to ensure only high-priority messages are received. ```csharp var consumer = await connection.CreateConsumerAsync(new ConsumerConfiguration { Address = address, RoutingType = RoutingType.Anycast, FilterExpression = "AMQPriority = 9" }); ``` ```csharp FilterExpression = "AMQPriority > 5" // Only high-priority messages ``` -------------------------------- ### Disconnecting from ActiveMQ Artemis Source: https://havret.github.io/dotnet-activemq-artemis-client/docs/getting-started Call DisposeAsync on the connection object to asynchronously close the connection. Connections should be long-lived objects. ```csharp await connection.DisposeAsync(); ``` -------------------------------- ### Disable Automatic Recovery Source: https://havret.github.io/dotnet-activemq-artemis-client/docs/auto-recovery Turn off the automatic recovery feature by setting `ConnectionFactory.AutomaticRecoveryEnabled` to `false`. ```csharp var connectionFactory = new ConnectionFactory(); connectionFactory.AutomaticRecoveryEnabled = false; // connection that will not recover automatically var connection = await connectionFactory.CreateAsync(endpoint); ``` -------------------------------- ### Sending an Individual Nondurable Message Source: https://havret.github.io/dotnet-activemq-artemis-client/docs/message-durability Overrides the producer's default durability setting to send a single message as nondurable. This setting takes precedence over the producer-level configuration. ```csharp await producer.SendAsync(new Message("foo") { DurabilityMode = DurabilityMode.Nondurable // takes precedence over durability // mode specified on the producer level }); ``` -------------------------------- ### Filter with OR Operator Source: https://havret.github.io/dotnet-activemq-artemis-client/docs/message-filtering Employ the OR operator to receive messages that satisfy at least one of the specified conditions. This broadens the selection criteria. ```csharp FilterExpression = "color = 'red' OR color = 'blue'" ``` -------------------------------- ### Modify Message: Redirect to Different Consumer Source: https://havret.github.io/dotnet-activemq-artemis-client/docs/message-acknowledgment Signal that the current consumer cannot handle the message but another might by calling Modify with deliveryFailed: true and undeliverableHere: true. The message is requeued, its delivery count increments, and it won't be redelivered to this consumer. ```csharp var message = await consumer.ReceiveAsync(); consumer.Modify(message, deliveryFailed: true, undeliverableHere: true); ``` -------------------------------- ### Filter by AMQTimestamp Source: https://havret.github.io/dotnet-activemq-artemis-client/docs/message-filtering Filter messages created after a specific timestamp. This is useful for processing messages sent within a certain time frame. ```csharp var timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); var consumer = await connection.CreateConsumerAsync(new ConsumerConfiguration { Address = address, RoutingType = RoutingType.Anycast, FilterExpression = $"AMQTimestamp > {timestamp}" }); ``` -------------------------------- ### Modify Message: Retry on Same Consumer Source: https://havret.github.io/dotnet-activemq-artemis-client/docs/message-acknowledgment Return a message to the queue for the same consumer to receive again by calling Modify with deliveryFailed: true and undeliverableHere: false. This increments the message's delivery count. ```csharp var message = await consumer.ReceiveAsync(); consumer.Modify(message, deliveryFailed: true, undeliverableHere: false); ``` -------------------------------- ### Filter for NULL Values Source: https://havret.github.io/dotnet-activemq-artemis-client/docs/message-filtering Handle messages with missing or explicitly null properties using the IS NULL operator. Conversely, use IS NOT NULL to ensure a property exists. ```csharp var consumer = await connection.CreateConsumerAsync(new ConsumerConfiguration { Address = address, RoutingType = RoutingType.Multicast, FilterExpression = "optionalField IS NULL" }); ``` ```csharp FilterExpression = "requiredField IS NOT NULL" ``` -------------------------------- ### Unacknowledged Messages on Consumer Close Source: https://havret.github.io/dotnet-activemq-artemis-client/docs/message-acknowledgment Messages remain unacknowledged if a consumer is closed or disposed without calling AcceptAsync, Reject, or Modify. These messages become eligible for redelivery to other consumers or will be redelivered upon reconnection for durable consumers. ```csharp { await using var consumer = await connection.CreateConsumerAsync("a1", RoutingType.Anycast); var message = await consumer.ReceiveAsync(); // consumer disposed here without AcceptAsync/Reject/Modify // message is not acknowledged and will be redelivered } ``` -------------------------------- ### Check if Connection Closed by Peer Source: https://havret.github.io/dotnet-activemq-artemis-client/docs/connection-lifecycle Determine if the connection was closed by the remote peer (broker) or by the client itself using the ClosedByPeer property in ConnectionClosedEventArgs. ```csharp connection.ConnectionClosed += (sender, eventArgs) => { bool closedByPeer = eventArgs.ClosedByPeer; if (closedByPeer) { _logger.LogWarning("connection was closed by the broker"); } else { _logger.LogWarning("connection was closed by the client"); } }; ``` -------------------------------- ### Filter by AMQExpiration Source: https://havret.github.io/dotnet-activemq-artemis-client/docs/message-filtering Filter messages that expire after a specified absolute timestamp. This ensures that only non-expired messages are processed. ```csharp var messageExpiryTime = DateTimeOffset.UtcNow.AddMinutes(10).ToUnixTimeMilliseconds(); var consumer = await connection.CreateConsumerAsync(new ConsumerConfiguration { Address = address, RoutingType = RoutingType.Anycast, FilterExpression = $"AMQExpiration > {messageExpiryTime}" }); ``` -------------------------------- ### Modify Message: Requeue Without Incrementing Delivery Count Source: https://havret.github.io/dotnet-activemq-artemis-client/docs/message-acknowledgment Requeue a message without incrementing its delivery count by calling Modify with deliveryFailed: false and undeliverableHere: true. This is useful for handing off messages to other consumers without marking them as failed. ```csharp var message = await consumer.ReceiveAsync(); consumer.Modify(message, deliveryFailed: false, undeliverableHere: true); ``` -------------------------------- ### Filter with IN Operator Source: https://havret.github.io/dotnet-activemq-artemis-client/docs/message-filtering Use the IN operator to filter messages where a property matches any value within a specified list. This simplifies filtering for multiple discrete values. ```csharp FilterExpression = "color IN ('red', 'blue', 'green')" ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.