Skip to content

Commit 603555e

Browse files
authored
Adds rabbitmq auto provisioning (#9327)
1 parent aa50347 commit 603555e

14 files changed

Lines changed: 769 additions & 22 deletions

File tree

src/Mocha/src/Mocha.Transport.RabbitMQ/Configurations/RabbitMQTransportConfiguration.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,13 @@ public RabbitMQTransportConfiguration()
5151
/// </summary>
5252
public List<RabbitMQBindingConfiguration> Bindings { get; set; } = [];
5353

54+
/// <summary>
55+
/// Gets or sets a value indicating whether topology resources (queues, exchanges, bindings)
56+
/// should be automatically provisioned on the broker. When <c>null</c>, defaults to <c>true</c>.
57+
/// Individual resources can override this setting.
58+
/// </summary>
59+
public bool? AutoProvision { get; set; }
60+
5461
/// <summary>
5562
/// Gets or sets the bus-level defaults applied to all auto-provisioned queues and exchanges.
5663
/// </summary>

src/Mocha/src/Mocha.Transport.RabbitMQ/Conventions/RabbitMQReceiveEndpointTopologyConvention.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ public void DiscoverTopology(
3232
new RabbitMQQueueConfiguration
3333
{
3434
Name = configuration.QueueName,
35-
AutoDelete = endpoint.Kind == ReceiveEndpointKind.Reply
35+
AutoDelete = endpoint.Kind == ReceiveEndpointKind.Reply,
36+
AutoProvision = configuration.AutoProvision
3637
});
3738
}
3839

src/Mocha/src/Mocha.Transport.RabbitMQ/Descriptors/IRabbitMQMessagingTransportDescriptor.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,17 @@ IRabbitMQMessagingTransportDescriptor ConnectionProvider(
7070
/// <returns>A binding descriptor for further configuration.</returns>
7171
IRabbitMQBindingDescriptor DeclareBinding(string exchange, string queue);
7272

73+
/// <summary>
74+
/// Sets whether topology resources should be automatically provisioned on the broker.
75+
/// When disabled, queues, exchanges, and bindings must exist before the transport starts.
76+
/// Individual resources can override this setting via their own <c>AutoProvision</c> method.
77+
/// </summary>
78+
/// <param name="autoProvision">
79+
/// <c>true</c> to enable auto-provisioning (default); <c>false</c> to disable it globally.
80+
/// </param>
81+
/// <returns>The descriptor for method chaining.</returns>
82+
IRabbitMQMessagingTransportDescriptor AutoProvision(bool autoProvision = true);
83+
7384
/// <inheritdoc cref="IMessagingTransportDescriptor.Name" />
7485
new IRabbitMQMessagingTransportDescriptor Name(string name);
7586

src/Mocha/src/Mocha.Transport.RabbitMQ/Descriptors/RabbitMQMessagingTransportDescriptor.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,13 @@ public RabbitMQMessagingTransportDescriptor(IMessagingSetupContext discoveryCont
136136
return this;
137137
}
138138

139+
/// <inheritdoc />
140+
public IRabbitMQMessagingTransportDescriptor AutoProvision(bool autoProvision = true)
141+
{
142+
Configuration.AutoProvision = autoProvision;
143+
return this;
144+
}
145+
139146
/// <inheritdoc />
140147
public IRabbitMQMessagingTransportDescriptor ConnectionProvider(
141148
Func<IServiceProvider, IRabbitMQConnectionProvider> connectionProvider)

src/Mocha/src/Mocha.Transport.RabbitMQ/RabbitMQDispatchEndpoint.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,12 +145,14 @@ private async ValueTask EnsureProvisionedAsync(IChannel channel, CancellationTok
145145
return;
146146
}
147147

148-
if (Queue is not null)
148+
var autoProvision = ((RabbitMQMessagingTopology)transport.Topology).AutoProvision;
149+
150+
if (Queue is not null && (Queue.AutoProvision ?? autoProvision))
149151
{
150152
await Queue.ProvisionAsync(channel, cancellationToken);
151153
}
152154

153-
if (Exchange is not null)
155+
if (Exchange is not null && (Exchange.AutoProvision ?? autoProvision))
154156
{
155157
await Exchange.ProvisionAsync(channel, cancellationToken);
156158
}

src/Mocha/src/Mocha.Transport.RabbitMQ/RabbitMQMessagingTransport.cs

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,11 @@ protected override void OnAfterInitialized(IMessagingSetupContext context)
7272
Port = Connection.Port,
7373
Path = Connection.VirtualHost
7474
};
75-
76-
_topology = new RabbitMQMessagingTopology(this, builder.Uri, configuration.Defaults);
75+
_topology = new RabbitMQMessagingTopology(
76+
this,
77+
builder.Uri,
78+
configuration.Defaults,
79+
configuration.AutoProvision ?? true);
7780

7881
foreach (var exchange in configuration.Exchanges)
7982
{
@@ -110,20 +113,30 @@ private RabbitMQDispatcher CreateDispatcher(IMessagingSetupContext context)
110113
async Task ProvisionTopologyAsync(IConnection connection, CancellationToken ct)
111114
{
112115
await using var channel = await connection.CreateChannelAsync(cancellationToken: ct);
116+
var autoProvision = _topology.AutoProvision;
113117

114-
foreach (var queue in _topology.Queues)
118+
foreach (var exchange in _topology.Exchanges)
115119
{
116-
await queue.ProvisionAsync(channel, ct);
120+
if (exchange.AutoProvision ?? autoProvision)
121+
{
122+
await exchange.ProvisionAsync(channel, ct);
123+
}
117124
}
118125

119-
foreach (var exchange in _topology.Exchanges)
126+
foreach (var queue in _topology.Queues)
120127
{
121-
await exchange.ProvisionAsync(channel, ct);
128+
if (queue.AutoProvision ?? autoProvision)
129+
{
130+
await queue.ProvisionAsync(channel, ct);
131+
}
122132
}
123133

124134
foreach (var binding in _topology.Bindings)
125135
{
126-
await binding.ProvisionAsync(channel, ct);
136+
if (binding.AutoProvision ?? autoProvision)
137+
{
138+
await binding.ProvisionAsync(channel, ct);
139+
}
127140
}
128141
}
129142
}
@@ -137,6 +150,7 @@ public override TransportDescription Describe()
137150

138151
var entities = new List<TopologyEntityDescription>();
139152
var links = new List<TopologyLinkDescription>();
153+
var autoProvision = _topology.AutoProvision;
140154

141155
foreach (var exchange in _topology.Exchanges)
142156
{
@@ -151,7 +165,7 @@ public override TransportDescription Describe()
151165
["type"] = exchange.Type,
152166
["durable"] = exchange.Durable,
153167
["autoDelete"] = exchange.AutoDelete,
154-
["autoProvision"] = exchange.AutoProvision
168+
["autoProvision"] = exchange.AutoProvision ?? autoProvision
155169
}));
156170
}
157171

@@ -168,7 +182,7 @@ public override TransportDescription Describe()
168182
["durable"] = queue.Durable,
169183
["exclusive"] = queue.Exclusive,
170184
["autoDelete"] = queue.AutoDelete,
171-
["autoProvision"] = queue.AutoProvision
185+
["autoProvision"] = queue.AutoProvision ?? autoProvision
172186
}));
173187
}
174188

@@ -189,7 +203,7 @@ public override TransportDescription Describe()
189203
new Dictionary<string, object?>
190204
{
191205
["routingKey"] = string.IsNullOrEmpty(binding.RoutingKey) ? null : binding.RoutingKey,
192-
["autoProvision"] = binding.AutoProvision
206+
["autoProvision"] = binding.AutoProvision ?? autoProvision
193207
}));
194208
}
195209

src/Mocha/src/Mocha.Transport.RabbitMQ/Topology/RabbitMQBinding.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,9 @@ public abstract class RabbitMQBinding : TopologyResource<RabbitMQBindingConfigur
1515

1616
/// <summary>
1717
/// Gets a value indicating whether this binding is automatically provisioned during topology setup.
18+
/// When <c>null</c>, the transport-level default is used.
1819
/// </summary>
19-
public bool AutoProvision { get; protected set; }
20+
public bool? AutoProvision { get; protected set; }
2021

2122
/// <summary>
2223
/// Gets the routing key pattern used to filter messages passing through this binding.
@@ -55,7 +56,7 @@ protected override void OnInitialize(RabbitMQBindingConfiguration configuration)
5556
{
5657
RoutingKey = configuration.RoutingKey ?? string.Empty;
5758
Arguments = configuration.Arguments?.ToImmutableDictionary(kv => kv.Key, kv => (object?)kv.Value) ?? ImmutableDictionary<string, object?>.Empty;
58-
AutoProvision = configuration.AutoProvision ?? true;
59+
AutoProvision = configuration.AutoProvision;
5960
}
6061

6162
protected override void OnComplete(RabbitMQBindingConfiguration configuration)
@@ -96,7 +97,7 @@ protected override void OnInitialize(RabbitMQBindingConfiguration configuration)
9697
{
9798
RoutingKey = configuration.RoutingKey ?? string.Empty;
9899
Arguments = configuration.Arguments?.ToImmutableDictionary(kv => kv.Key, kv => (object?)kv.Value) ?? ImmutableDictionary<string, object?>.Empty;
99-
AutoProvision = configuration.AutoProvision ?? true;
100+
AutoProvision = configuration.AutoProvision;
100101
}
101102

102103
protected override void OnComplete(RabbitMQBindingConfiguration configuration)

src/Mocha/src/Mocha.Transport.RabbitMQ/Topology/RabbitMQExchange.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,9 @@ public sealed class RabbitMQExchange : TopologyResource<RabbitMQExchangeConfigur
2222

2323
/// <summary>
2424
/// Gets a value indicating whether this exchange is automatically provisioned during topology setup.
25+
/// When <c>null</c>, the transport-level default is used.
2526
/// </summary>
26-
public bool AutoProvision { get; private set; }
27+
public bool? AutoProvision { get; private set; }
2728

2829
/// <summary>
2930
/// Gets the exchange type (e.g., "direct", "fanout", "topic", "headers").
@@ -58,7 +59,7 @@ protected override void OnInitialize(RabbitMQExchangeConfiguration configuration
5859
Type = configuration.Type ?? "fanout";
5960
AutoDelete = configuration.AutoDelete ?? false;
6061
Arguments = configuration.Arguments?.ToImmutableDictionary(kv => kv.Key, kv => (object?)kv.Value) ?? ImmutableDictionary<string, object?>.Empty;
61-
AutoProvision = configuration.AutoProvision ?? true;
62+
AutoProvision = configuration.AutoProvision;
6263
}
6364

6465
protected override void OnComplete(RabbitMQExchangeConfiguration configuration)

src/Mocha/src/Mocha.Transport.RabbitMQ/Topology/RabbitMQMessagingTopology.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,21 @@ namespace Mocha.Transport.RabbitMQ;
77
public sealed class RabbitMQMessagingTopology(
88
RabbitMQMessagingTransport transport,
99
Uri baseAddress,
10-
RabbitMQBusDefaults defaults)
10+
RabbitMQBusDefaults defaults,
11+
bool autoProvision)
1112
: MessagingTopology<RabbitMQMessagingTransport>(transport, baseAddress)
1213
{
1314
private readonly object _lock = new();
1415
private readonly List<RabbitMQExchange> _exchanges = [];
1516
private readonly List<RabbitMQQueue> _queues = [];
1617
private readonly List<RabbitMQBinding> _bindings = [];
1718

19+
/// <summary>
20+
/// Gets a value indicating whether topology resources should be auto-provisioned by default.
21+
/// Individual resources may override this setting via their own <c>AutoProvision</c> property.
22+
/// </summary>
23+
public bool AutoProvision => autoProvision;
24+
1825
/// <summary>
1926
/// Gets the list of exchanges registered in this topology.
2027
/// </summary>

src/Mocha/src/Mocha.Transport.RabbitMQ/Topology/RabbitMQQueue.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,9 @@ public sealed class RabbitMQQueue : TopologyResource<RabbitMQQueueConfiguration>
2727

2828
/// <summary>
2929
/// Gets a value indicating whether this queue is automatically provisioned during topology setup.
30+
/// When <c>null</c>, the transport-level default is used.
3031
/// </summary>
31-
public bool AutoProvision { get; private set; }
32+
public bool? AutoProvision { get; private set; }
3233

3334
/// <summary>
3435
/// Gets a value indicating whether this queue survives broker restarts.
@@ -58,7 +59,7 @@ protected override void OnInitialize(RabbitMQQueueConfiguration configuration)
5859
Exclusive = configuration.Exclusive ?? false;
5960
AutoDelete = configuration.AutoDelete ?? false;
6061
Arguments = configuration.Arguments?.ToImmutableDictionary(kv => kv.Key, kv => (object?)kv.Value) ?? ImmutableDictionary<string, object?>.Empty;
61-
AutoProvision = configuration.AutoProvision ?? true;
62+
AutoProvision = configuration.AutoProvision;
6263
}
6364

6465
protected override void OnComplete(RabbitMQQueueConfiguration configuration)

0 commit comments

Comments
 (0)