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 () ->
@@ -254,17 +274,47 @@ list_for_source(SrcName) ->
254
274
<- mnesia :match_object (rabbit_route , Route , read )]
255
275
end ).
256
276
257
- 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
-
277
+ list_for_destination (DstName = # resource {virtual_host = VHostPath }) ->
278
+ AllBindings = mnesia :async_dirty (
279
+ fun () ->
280
+ Route = # route {binding = # binding {destination = DstName ,
281
+ _ = '_' }},
282
+ [reverse_binding (B ) ||
283
+ # reverse_route {reverse_binding = B } <-
284
+ mnesia :match_object (rabbit_reverse_route ,
285
+ reverse_route (Route ), read )]
286
+ end ),
287
+ Filtered = lists :filter (fun (# binding {source = S }) ->
288
+ S =/= ? DEFAULT_EXCHANGE (VHostPath )
289
+ end , AllBindings ),
290
+ implicit_for_destination (DstName ) ++ Filtered .
291
+
292
+ implicit_bindings (VHostPath ) ->
293
+ DstQueues = rabbit_amqqueue :list_names (VHostPath ),
294
+ [ # binding {source = ? DEFAULT_EXCHANGE (VHostPath ),
295
+ destination = DstQueue ,
296
+ key = QName ,
297
+ args = []}
298
+ || DstQueue = # resource {name = QName } <- DstQueues ].
299
+
300
+ implicit_for_destination (DstQueue = # resource {kind = queue ,
301
+ virtual_host = VHostPath ,
302
+ name = QName }) ->
303
+ [# binding {source = ? DEFAULT_EXCHANGE (VHostPath ),
304
+ destination = DstQueue ,
305
+ key = QName ,
306
+ args = []}];
307
+ implicit_for_destination (_ ) ->
308
+ [].
309
+
310
+ list_for_source_and_destination (? DEFAULT_EXCHANGE (VHostPath ),
311
+ # resource {kind = queue ,
312
+ virtual_host = VHostPath ,
313
+ name = QName } = DstQueue ) ->
314
+ [# binding {source = ? DEFAULT_EXCHANGE (VHostPath ),
315
+ destination = DstQueue ,
316
+ key = QName ,
317
+ args = []}];
268
318
list_for_source_and_destination (SrcName , DstName ) ->
269
319
mnesia :async_dirty (
270
320
fun () ->
0 commit comments