Using Amazon SQS
Wolverine supports Amazon SQS as a messaging transport through the WolverineFx.AmazonSqs package.
Connecting to the Broker
First, if you are using the shared AWS config and credentials files, the SQS connection is just this:
var host = await Host.CreateDefaultBuilder()
.UseWolverine(opts =>
{
// This does depend on the server having an AWS credentials file
// See https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html for more information
opts.UseAmazonSqsTransport()
// Let Wolverine create missing queues as necessary
.AutoProvision()
// Optionally purge all queues on application startup.
// Warning though, this is potentially slow
.AutoPurgeOnStartup();
}).StartAsync();var builder = Host.CreateApplicationBuilder();
builder.UseWolverine(opts =>
{
var config = builder.Configuration;
opts.UseAmazonSqsTransport(sqsConfig =>
{
sqsConfig.ServiceURL = config["AwsUrl"];
// And any other elements of the SQS AmazonSQSConfig
// that you may need to configure
})
// Let Wolverine create missing queues as necessary
.AutoProvision()
// Optionally purge all queues on application startup.
// Warning though, this is potentially slow
.AutoPurgeOnStartup();
});
using var host = builder.Build();
await host.StartAsync();If you'd just like to connect to Amazon SQS running from within LocalStack on your development box, there's this helper:
var host = await Host.CreateDefaultBuilder()
.UseWolverine(opts =>
{
// Connect to an SQS broker running locally
// through LocalStack
opts.UseAmazonSqsTransportLocally();
}).StartAsync();And lastly, if you want to explicitly supply an access and secret key for your credentials to SQS, you can use this syntax:
var builder = Host.CreateApplicationBuilder();
builder.UseWolverine(opts =>
{
var config = builder.Configuration;
opts.UseAmazonSqsTransport(sqsConfig =>
{
sqsConfig.ServiceURL = config["AwsUrl"];
// And any other elements of the SQS AmazonSQSConfig
// that you may need to configure
})
// And you can also add explicit AWS credentials
.Credentials(new BasicAWSCredentials(config["AwsAccessKey"], config["AwsSecretKey"]))
// Let Wolverine create missing queues as necessary
.AutoProvision()
// Optionally purge all queues on application startup.
// Warning though, this is potentially slow
.AutoPurgeOnStartup();
});
using var host = builder.Build();
await host.StartAsync();Connecting to Multiple Brokers 4.7
Wolverine supports interacting with multiple Amazon SQS brokers within one application like this:
using var host = await Host.CreateDefaultBuilder()
.UseWolverine(opts =>
{
opts.UseAmazonSqsTransport(config =>
{
// Add configuration for connectivity
});
opts.AddNamedAmazonSqsBroker(new BrokerName("americas"), config =>
{
// Add configuration for connectivity
});
opts.AddNamedAmazonSqsBroker(new BrokerName("emea"), config =>
{
// Add configuration for connectivity
});
// Or explicitly make subscription rules
opts.PublishMessage<SenderConfigurationTests.ColorMessage>()
.ToSqsQueueOnNamedBroker(new BrokerName("emea"), "colors");
// Listen to topics
opts.ListenToSqsQueueOnNamedBroker(new BrokerName("americas"), "red");
// Other configuration
}).StartAsync();Note that the Uri scheme within Wolverine for any endpoints from a "named" Amazon SQS broker is the name that you supply for the broker. So in the example above, you might see Uri values for emea://colors or americas://red.
Identifier Prefixing for Shared Brokers
When sharing a single AWS account or SQS namespace between multiple developers or development environments, you can use PrefixIdentifiers() to automatically prepend a prefix to every queue name created by Wolverine. This helps isolate cloud resources for each developer or environment:
using var host = await Host.CreateDefaultBuilder()
.UseWolverine(opts =>
{
opts.UseAmazonSqsTransport()
.AutoProvision()
// Prefix all queue names with "dev-john-"
.PrefixIdentifiers("dev-john");
// A queue named "orders" becomes "dev-john-orders"
opts.ListenToSqsQueue("orders");
}).StartAsync();You can also use PrefixIdentifiersWithMachineName() as a convenience to use the current machine name as the prefix:
opts.UseAmazonSqsTransport()
.AutoProvision()
.PrefixIdentifiersWithMachineName();The default delimiter between the prefix and the original name is - for Amazon SQS (e.g., dev-john-orders).
Request/Reply 5.14
Request/reply mechanics (IMessageBus.InvokeAsync<T>()) are supported with the Amazon SQS transport when system queues are enabled. Wolverine creates a dedicated per-node response queue named like wolverine-response-[service name]-[node id] that is used to receive replies.
To enable request/reply support, call EnableSystemQueues() on the SQS transport configuration:
using var host = await Host.CreateDefaultBuilder()
.UseWolverine(opts =>
{
opts.UseAmazonSqsTransport()
.AutoProvision()
// Enable system queues for request/reply support
.EnableSystemQueues();
}).StartAsync();TIP
Unlike Azure Service Bus and RabbitMQ where system queues are enabled by default, SQS system queues require explicit opt-in via EnableSystemQueues(). This is because creating SQS queues requires IAM permissions that your application may not have.
System queues are automatically cleaned up when your application shuts down. Wolverine also tags each system queue with a wolverine:last-active timestamp and runs a background keep-alive timer. On startup, Wolverine scans for orphaned system queues (from crashed nodes) with the wolverine-response- or wolverine-control- prefix and deletes any that have been inactive for more than 5 minutes.
Wolverine Control Queues 5.14
You can opt into using SQS queues for intra-node communication that Wolverine needs for leader election and background worker distribution. Using SQS for this feature is more efficient than the built-in database control queues that Wolverine uses otherwise, and is necessary for message storage options like RavenDb that do not have a built-in control queue mechanism.
using var host = await Host.CreateDefaultBuilder()
.UseWolverine(opts =>
{
opts.UseAmazonSqsTransport()
.AutoProvision()
// This enables Wolverine to use SQS queues
// created at runtime for communication between
// Wolverine nodes
.EnableWolverineControlQueues();
}).StartAsync();Calling EnableWolverineControlQueues() implicitly enables system queues and request/reply support as well.
Disabling System Queues 5.14
If your application does not have IAM permissions to create or delete queues, you can explicitly disable system queues:
using var host = await Host.CreateDefaultBuilder()
.UseWolverine(opts =>
{
opts.UseAmazonSqsTransport()
.AutoProvision()
.SystemQueuesAreEnabled(false);
opts.ListenToSqsQueue("send-and-receive");
opts.PublishAllMessages().ToSqsQueue("send-and-receive");
}).StartAsync();
