27
27
-export ([has_for_source /1 , remove_for_source /1 ,
28
28
remove_for_destination /2 , remove_transient_for_destination /1 ]).
29
29
30
+ -define (DEFAULT_EXCHANGE (VHostPath ), # resource {virtual_host = VHostPath ,
31
+ kind = exchange ,
32
+ name = <<>>}).
33
+
30
34
% %----------------------------------------------------------------------------
31
35
32
36
-export_type ([key / 0 , deletions / 0 ]).
@@ -156,6 +160,14 @@ recover_semi_durable_route_txn(R = #route{binding = B}, X) ->
156
160
(Serial , false ) -> x_callback (Serial , X , add_binding , B )
157
161
end ).
158
162
163
+ exists (# binding {source = ? DEFAULT_EXCHANGE (_ ),
164
+ destination = # resource {kind = queue , name = QName } = Queue ,
165
+ key = QName ,
166
+ args = []}) ->
167
+ case rabbit_amqqueue :lookup (Queue ) of
168
+ {ok , _ } -> true ;
169
+ {error , not_found } -> false
170
+ end ;
159
171
exists (Binding ) ->
160
172
binding_action (
161
173
Binding , fun (_Src , _Dst , B ) ->
@@ -243,9 +255,17 @@ list(VHostPath) ->
243
255
destination = VHostResource ,
244
256
_ = '_' },
245
257
_ = '_' },
246
- [B || # route {binding = B } <- mnesia :dirty_match_object (rabbit_route ,
247
- Route )].
248
-
258
+ % % if there are any default exchange bindings left after an upgrade
259
+ % % of a pre-3.8 database, filter them out
260
+ AllBindings = [B || # route {binding = B } <- mnesia :dirty_match_object (rabbit_route ,
261
+ Route )],
262
+ Filtered = lists :filter (fun (# binding {source = S }) ->
263
+ S =/= ? DEFAULT_EXCHANGE (VHostPath )
264
+ end , AllBindings ),
265
+ implicit_bindings (VHostPath ) ++ Filtered .
266
+
267
+ list_for_source (? DEFAULT_EXCHANGE (VHostPath )) ->
268
+ implicit_bindings (VHostPath );
249
269
list_for_source (SrcName ) ->
250
270
mnesia :async_dirty (
251
271
fun () ->
@@ -255,16 +275,43 @@ list_for_source(SrcName) ->
255
275
end ).
256
276
257
277
list_for_destination (DstName ) ->
258
- mnesia :async_dirty (
259
- fun () ->
260
- Route = # route {binding = # binding {destination = DstName ,
261
- _ = '_' }},
262
- [reverse_binding (B ) ||
263
- # reverse_route {reverse_binding = B } <-
264
- mnesia :match_object (rabbit_reverse_route ,
265
- reverse_route (Route ), read )]
266
- end ).
267
-
278
+ implicit_for_destination (DstName ) ++
279
+ mnesia :async_dirty (
280
+ fun () ->
281
+ Route = # route {binding = # binding {destination = DstName ,
282
+ _ = '_' }},
283
+ [reverse_binding (B ) ||
284
+ # reverse_route {reverse_binding = B } <-
285
+ mnesia :match_object (rabbit_reverse_route ,
286
+ reverse_route (Route ), read )]
287
+ end ).
288
+
289
+ implicit_bindings (VHostPath ) ->
290
+ DstQueues = rabbit_amqqueue :list_names (VHostPath ),
291
+ [ # binding {source = ? DEFAULT_EXCHANGE (VHostPath ),
292
+ destination = DstQueue ,
293
+ key = QName ,
294
+ args = []}
295
+ || DstQueue = # resource {name = QName } <- DstQueues ].
296
+
297
+ implicit_for_destination (DstQueue = # resource {kind = queue ,
298
+ virtual_host = VHostPath ,
299
+ name = QName }) ->
300
+ [# binding {source = ? DEFAULT_EXCHANGE (VHostPath ),
301
+ destination = DstQueue ,
302
+ key = QName ,
303
+ args = []}];
304
+ implicit_for_destination (_ ) ->
305
+ [].
306
+
307
+ list_for_source_and_destination (? DEFAULT_EXCHANGE (VHostPath ),
308
+ # resource {kind = queue ,
309
+ virtual_host = VHostPath ,
310
+ name = QName } = DstQueue ) ->
311
+ [# binding {source = ? DEFAULT_EXCHANGE (VHostPath ),
312
+ destination = DstQueue ,
313
+ key = QName ,
314
+ args = []}];
268
315
list_for_source_and_destination (SrcName , DstName ) ->
269
316
mnesia :async_dirty (
270
317
fun () ->
0 commit comments