Give the federation exchange another type of exchange to emulate. This sorta works now (we can federate a message! woo!), but in a couple of cases we need the backing module before we have it. Hmm.
This commit is contained in:
parent
8f4cf84e23
commit
da339a0513
|
|
@ -3,4 +3,11 @@ This is all very experimental.
|
|||
Configuration might look like:
|
||||
|
||||
{rabbit_federation,
|
||||
[ {exchanges, [{"local", "amqp://amqp.example.com/%2f/remote"}] } ]}
|
||||
[ {exchanges, [{ %% local exchange people can bind to
|
||||
"local",
|
||||
%% remote exchange they effectively bind to
|
||||
"amqp://amqp.example.com/%2f/remote",
|
||||
%% type of remote exchange
|
||||
"direct"}]
|
||||
}
|
||||
]}
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ stop(_State) ->
|
|||
|
||||
%%----------------------------------------------------------------------------
|
||||
|
||||
declare_exchange({Local, Remote}) ->
|
||||
declare_exchange({Local, Remote, Type}) ->
|
||||
{ok, Conn} = amqp_connection:start(direct),
|
||||
{ok, Ch} = amqp_connection:open_channel(Conn),
|
||||
%% TODO make durable, recover bindings etc
|
||||
|
|
@ -41,6 +41,7 @@ declare_exchange({Local, Remote}) ->
|
|||
exchange = list_to_binary(Local),
|
||||
type = <<"x-federation">>,
|
||||
arguments =
|
||||
[{<<"remote">>, longstr, list_to_binary(Remote)}]}),
|
||||
[{<<"remote">>, longstr, list_to_binary(Remote)},
|
||||
{<<"type">>, longstr, list_to_binary(Type)}]}),
|
||||
amqp_channel:close(Ch),
|
||||
amqp_connection:close(Conn).
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@
|
|||
-export([validate/1, create/2, recover/2, delete/3,
|
||||
add_binding/3, remove_bindings/3, assert_args_equivalence/2]).
|
||||
|
||||
-export([start_link/2]).
|
||||
-export([start_link/3]).
|
||||
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
|
||||
terminate/2, code_change/3]).
|
||||
|
||||
|
|
@ -46,8 +46,7 @@
|
|||
-define(TX, false).
|
||||
-record(state, { local_connection, local_channel,
|
||||
remote_connection, remote_channel,
|
||||
local, remote,
|
||||
remote_queue }).
|
||||
local, remote, remote_queue }).
|
||||
|
||||
%%----------------------------------------------------------------------------
|
||||
|
||||
|
|
@ -58,39 +57,61 @@ description() ->
|
|||
[{name, <<"x-federation">>},
|
||||
{description, <<"Federation exchange">>}].
|
||||
|
||||
route(_X, _Delivery) ->
|
||||
exit(not_implemented).
|
||||
route(X, Delivery) ->
|
||||
with_module(X, fun (M) -> M:route(X, Delivery) end).
|
||||
|
||||
validate(_X) -> ok.
|
||||
validate(X) ->
|
||||
ok.
|
||||
%%with_module(X, fun (M) -> M:validate(X) end).
|
||||
|
||||
create(?TX, #exchange{ name = Local, arguments = Args }) ->
|
||||
create(?TX, X = #exchange{ name = Local, arguments = Args }) ->
|
||||
{longstr, Remote} = rabbit_misc:table_lookup(Args, <<"remote">>),
|
||||
rabbit_federation_sup:start_child(Local, binary_to_list(Remote));
|
||||
create(_, _) -> ok.
|
||||
{longstr, Type} = rabbit_misc:table_lookup(Args, <<"type">>),
|
||||
{ok, Module} = rabbit_registry:lookup_module(
|
||||
exchange, rabbit_exchange:check_type(Type)),
|
||||
rabbit_federation_sup:start_child(Local, binary_to_list(Remote), Module),
|
||||
with_module(X, fun (M) -> M:create(?TX, X) end);
|
||||
create(Tx, X) ->
|
||||
ok.
|
||||
%%with_module(X, fun (M) -> M:create(Tx, X) end).
|
||||
|
||||
recover(X, Bs) ->
|
||||
with_module(X, fun (M) -> M:recover(X, Bs) end).
|
||||
|
||||
delete(Tx, X, Bs) ->
|
||||
with_module(X, fun (M) -> M:delete(Tx, X, Bs) end).
|
||||
|
||||
recover(_X, _Bs) -> ok.
|
||||
delete(_Tx, _X, _Bs) -> ok.
|
||||
add_binding(?TX, X, B) ->
|
||||
call(X, {add_binding, B});
|
||||
add_binding(_, _, _) -> ok.
|
||||
remove_bindings(_Tx, _X, _Bs) -> ok.
|
||||
call(X, {add_binding, B}),
|
||||
with_module(X, fun (M) -> M:add_binding(?TX, X, B) end);
|
||||
add_binding(Tx, X, B) ->
|
||||
with_module(X, fun (M) -> M:add_binding(Tx, X, B) end).
|
||||
|
||||
remove_bindings(Tx, X, Bs) ->
|
||||
with_module(X, fun (M) -> M:remove_bindings(Tx, X, Bs) end).
|
||||
|
||||
assert_args_equivalence(X, Args) ->
|
||||
rabbit_exchange:assert_args_equivalence(X, Args).
|
||||
with_module(X, fun (M) -> M:assert_args_equivalence(X, Args) end).
|
||||
|
||||
%%----------------------------------------------------------------------------
|
||||
|
||||
call(#exchange{ name = Local }, Msg) ->
|
||||
[{_, Pid}] = ets:lookup(?ETS_NAME, Local),
|
||||
[{_, Pid, _}] = ets:lookup(?ETS_NAME, Local),
|
||||
gen_server:call(Pid, Msg, infinity).
|
||||
|
||||
%%----------------------------------------------------------------------------
|
||||
|
||||
start_link(Local, Remote) ->
|
||||
gen_server:start_link(?MODULE, {Local, Remote}, [{timeout, infinity}]).
|
||||
with_module(#exchange{ name = Local }, Fun) ->
|
||||
[{_, _, Module}] = ets:lookup(?ETS_NAME, Local),
|
||||
Fun(Module).
|
||||
|
||||
%%----------------------------------------------------------------------------
|
||||
|
||||
init({Local, RemoteURI}) ->
|
||||
start_link(Local, Remote, Module) ->
|
||||
gen_server:start_link(?MODULE, {Local, Remote, Module},
|
||||
[{timeout, infinity}]).
|
||||
|
||||
%%----------------------------------------------------------------------------
|
||||
|
||||
init({Local, RemoteURI, Module}) ->
|
||||
Remote0 = uri_parser:parse(RemoteURI, [{host, undefined}, {path, "/"},
|
||||
{port, undefined}, {'query', []}]),
|
||||
[VHostEnc, XEnc] = string:tokens(proplists:get_value(path, Remote0), "/"),
|
||||
|
|
@ -108,7 +129,7 @@ init({Local, RemoteURI}) ->
|
|||
self()),
|
||||
{ok, LConn} = amqp_connection:start(direct),
|
||||
{ok, LCh} = amqp_connection:open_channel(LConn),
|
||||
true = ets:insert(?ETS_NAME, {Local, self()}),
|
||||
true = ets:insert(?ETS_NAME, {Local, self(), Module}),
|
||||
{ok, #state{local_connection = LConn, local_channel = LCh,
|
||||
remote_connection = RConn, remote_channel = RCh,
|
||||
local = Local,
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
|
||||
-behaviour(supervisor).
|
||||
|
||||
-export([start_link/0, start_child/2]).
|
||||
-export([start_link/0, start_child/3]).
|
||||
|
||||
-export([init/1]).
|
||||
|
||||
|
|
@ -27,10 +27,10 @@
|
|||
start_link() ->
|
||||
supervisor:start_link({local, ?SUPERVISOR}, ?MODULE, []).
|
||||
|
||||
start_child(Local, Remote) ->
|
||||
start_child(Local, Remote, Module) ->
|
||||
supervisor:start_child(?SUPERVISOR,
|
||||
{exchange, {rabbit_federation_exchange, start_link,
|
||||
[Local, Remote]},
|
||||
[Local, Remote, Module]},
|
||||
permanent, brutal_kill, worker,
|
||||
[rabbit_federation_exchange]}).
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue