17
17
-module(rabbit_exchange_decorator).
19
-include("rabbit.hrl").
21
-export([select/2, set/1]).
19
23
%% This is like an exchange type except that:
21
25
%% 1) It applies to all exchanges as soon as it is installed, therefore
22
26
%% 2) It is not allowed to affect validation, so no validate/1 or
23
27
%% assert_args_equivalence/2
24
%% 3) It also can't affect routing
26
%% It's possible in the future we might relax 3), or even make these
29
%% It's possible in the future we might make decorators
27
30
%% able to manipulate messages as they are published.
46
49
-callback delete(tx(), rabbit_types:exchange(), [rabbit_types:binding()]) ->
52
%% called when the policy attached to this exchange changes.
53
-callback policy_changed(rabbit_types:exchange(), rabbit_types:exchange()) ->
49
56
%% called after a binding has been added or recovered
50
57
-callback add_binding(serial(), rabbit_types:exchange(),
51
58
rabbit_types:binding()) -> 'ok'.
54
61
-callback remove_bindings(serial(), rabbit_types:exchange(),
55
62
[rabbit_types:binding()]) -> 'ok'.
57
%% called when the policy attached to this exchange changes.
58
-callback policy_changed (
59
serial(), rabbit_types:exchange(), rabbit_types:exchange()) -> 'ok'.
64
%% Allows additional destinations to be added to the routing decision.
65
-callback route(rabbit_types:exchange(), rabbit_types:delivery()) ->
66
[rabbit_amqqueue:name() | rabbit_exchange:name()].
68
%% Whether the decorator wishes to receive callbacks for the exchange
69
%% none:no callbacks, noroute:all callbacks except route, all:all callbacks
70
-callback active_for(rabbit_types:exchange()) -> 'none' | 'noroute' | 'all'.
65
76
behaviour_info(callbacks) ->
66
77
[{description, 0}, {serialise_events, 1}, {create, 2}, {delete, 3},
67
{add_binding, 3}, {remove_bindings, 3}, {policy_changed, 3}];
78
{policy_changed, 2}, {add_binding, 3}, {remove_bindings, 3},
79
{route, 2}, {active_for, 1}];
68
80
behaviour_info(_Other) ->
85
%%----------------------------------------------------------------------------
87
%% select a subset of active decorators
88
select(all, {Route, NoRoute}) -> filter(Route ++ NoRoute);
89
select(route, {Route, _NoRoute}) -> filter(Route);
90
select(raw, {Route, NoRoute}) -> Route ++ NoRoute.
93
[M || M <- Modules, code:which(M) =/= non_existing].
96
Decs = lists:foldl(fun (D, {Route, NoRoute}) ->
97
ActiveFor = D:active_for(X),
98
{cons_if_eq(all, ActiveFor, D, Route),
99
cons_if_eq(noroute, ActiveFor, D, NoRoute)}
100
end, {[], []}, list()),
101
X#exchange{decorators = Decs}.
103
list() -> [M || {_, M} <- rabbit_registry:lookup_all(exchange_decorator)].
105
cons_if_eq(Select, Select, Item, List) -> [Item | List];
106
cons_if_eq(_Select, _Other, _Item, List) -> List.