Skip to content

Commit

Permalink
Ensure RabbitMQ WithDataVolume/WithDataBindMount methods actually ena…
Browse files Browse the repository at this point in the history
…ble persistent storage (#3152) (#3186)

* Use stable node name for RabbitMQ resources
* Update TestShop to use durable messages

Co-authored-by: Eric Erhardt <eric.erhardt@microsoft.com>
  • Loading branch information
DamianEdwards and eerhardt authored Mar 26, 2024
1 parent 60dcf90 commit 2f885ce
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 6 deletions.
5 changes: 4 additions & 1 deletion playground/TestShop/AppHost/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@
.WithReference(catalogDb)
.WithReplicas(2);

var messaging = builder.AddRabbitMQ("messaging").PublishAsContainer();
var rabbitMqPassword = builder.AddParameter("rabbitmq-password", secret: true);
var messaging = builder.AddRabbitMQ("messaging", password: rabbitMqPassword)
.WithDataVolume()
.PublishAsContainer();

var basketService = builder.AddProject("basketservice", @"..\BasketService\BasketService.csproj")
.WithReference(basketCache)
Expand Down
7 changes: 5 additions & 2 deletions playground/TestShop/BasketService/BasketService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -76,11 +76,14 @@ public override async Task<CheckoutCustomerBasketResponse> CheckoutBasket(Checko
}

using var channel = _messageConnection.CreateModel();
channel.QueueDeclare(queueName, exclusive: false);
channel.QueueDeclare(queueName, durable: true, exclusive: false);

var props = channel.CreateBasicProperties();
props.Persistent = true; // or props.DeliveryMode = 2;
channel.BasicPublish(
exchange: "",
routingKey: queueName,
basicProperties: null,
basicProperties: props,
body: JsonSerializer.SerializeToUtf8Bytes(order));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ protected override Task ExecuteAsync(CancellationToken stoppingToken)
_messageConnection = _serviceProvider.GetRequiredService<IConnection>();

_messageChannel = _messageConnection.CreateModel();
_messageChannel.QueueDeclare(queueName, exclusive: false);
_messageChannel.QueueDeclare(queueName, durable: true, exclusive: false);

var consumer = new EventingBasicConsumer(_messageChannel);
consumer.Received += ProcessMessageAsync;
Expand Down
22 changes: 20 additions & 2 deletions src/Aspire.Hosting.RabbitMQ/RabbitMQBuilderExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,9 @@ public static IResourceBuilder<RabbitMQServerResource> AddRabbitMQ(this IDistrib
/// <param name="isReadOnly">A flag that indicates if this is a read-only volume.</param>
/// <returns>The <see cref="IResourceBuilder{T}"/>.</returns>
public static IResourceBuilder<RabbitMQServerResource> WithDataVolume(this IResourceBuilder<RabbitMQServerResource> builder, string? name = null, bool isReadOnly = false)
=> builder.WithVolume(name ?? VolumeNameGenerator.CreateVolumeName(builder, "data"), "/var/lib/rabbitmq", isReadOnly);
=> builder
.WithVolume(name ?? VolumeNameGenerator.CreateVolumeName(builder, "data"), "/var/lib/rabbitmq", isReadOnly)
.RunWithStableNodeName();

/// <summary>
/// Adds a bind mount for the data folder to a RabbitMQ container resource.
Expand All @@ -58,5 +60,21 @@ public static IResourceBuilder<RabbitMQServerResource> WithDataVolume(this IReso
/// <param name="isReadOnly">A flag that indicates if this is a read-only mount.</param>
/// <returns>The <see cref="IResourceBuilder{T}"/>.</returns>
public static IResourceBuilder<RabbitMQServerResource> WithDataBindMount(this IResourceBuilder<RabbitMQServerResource> builder, string source, bool isReadOnly = false)
=> builder.WithBindMount(source, "/var/lib/rabbitmq", isReadOnly);
=> builder.WithBindMount(source, "/var/lib/rabbitmq", isReadOnly)
.RunWithStableNodeName();

private static IResourceBuilder<RabbitMQServerResource> RunWithStableNodeName(this IResourceBuilder<RabbitMQServerResource> builder)
{
if (builder.ApplicationBuilder.ExecutionContext.IsRunMode)
{
builder.WithEnvironment(context =>
{
// Set a stable node name so queue storage is consistent between sessions
var nodeName = $"{builder.Resource.Name}@localhost";
context.EnvironmentVariables["RABBITMQ_NODENAME"] = nodeName;
});
}

return builder;
}
}

0 comments on commit 2f885ce

Please sign in to comment.