2

I am writing custom exchange for RabbitMQ which must take arguments from exchange and put them to message headers. I am not very familiar with Erlang.

-module(rabbit_exchange_type_arguments_to_headers).


-include_lib("rabbit/include/rabbit.hrl").
-include_lib("rabbit/include/rabbit_framing.hrl").

-behaviour(rabbit_exchange_type).

%% API
-export([
  description/0,
  serialise_events/0,
  route/2,
  validate/1,
  validate_binding/2,
  create/2,
  delete/3,
  policy_changed/2,
  add_binding/3,
  remove_bindings/3,
  assert_args_equivalence/2
]).

-rabbit_boot_step(
  {?MODULE,
    [{description, "exchange type argument-to-header"},
      {mfa,         {rabbit_registry, register, [exchange, <<"argument">>, ?MODULE]}},
      {cleanup, {rabbit_registry, unregister, [exchange, <<"argumente">>]}},
      {requires,    rabbit_registry},
      {enables,     kernel_ready}]
  }
).


description() ->
  [{name, <<"argument">>},
   {description, <<"Adds exchange argumets to message headers">>}].


serialise_events() -> false.

% This is classic fanout routing
route(#exchange{name = Name, arguments = Arguments},
    #delivery{message = #basic_message{content = #content{properties = #'P_basic'{headers = MessageHeaders}}}} = Delivery) ->

  Headers = make_headers(MessageHeaders, Arguments),

  NewDelivery = Delivery#delivery{message = #basic_message{content = #content{properties = #'P_basic'{headers = Headers}}}},

  % Do some thing here to send NewDelivery instead of old one

  rabbit_router:match_routing_key(Name, ['_']).


make_headers(undefined, undefined) -> [];
make_headers(undefined, Arguments) -> Arguments;
make_headers(Headers, undefined) -> Headers;
make_headers(Headers, Arguments) -> lists:append(Headers, Arguments).

validate_binding(_X, _B) -> ok.


validate(_Exchange) -> ok.
create(_Tx, _X) -> ok.
deladd_binding(_Tx, _X, _B) -> ok.
remove_bindings(_Tx, _X, _Bs) -> ok.
assert_args_equivalence(Exchange, Args) ->
  rabbit_exchange:assert_args_equivalence(Exchange, Args).
ete(_Tx, _X, _Bs) -> ok.
policy_changed(_X1, _X2) -> ok.

I made new Delivery inside of rout method, but as I know I can't modify original variable in Erlang so Rabbit proceed with original one.

Is there some way to modify message inside exchange or say to rabbit proceed with new one.

2 Answers2

0

You can modify the source code, everything is possible.

Chen Yu
  • 3,955
  • 1
  • 24
  • 51
0

I have solved the problem. If someone interesting see my repository https://github.com/thecederick/rabbitmq-arguments-to-headers-exchange . There are source code and artifact ready for usage.