Hi all,

I've recently been working on some projects involving qpid-proton (C++
and Python variants) and rabbitmq servers and there are a couple of
issues I've observed, could anybody comment on these?

Environment
-----------

I'm running Debian jessie / stable with the qpid-proton packages from
the Debian backports repository[1], currently version 0.14.0-4~bpo8+1
and rabbitmq[2] version 3.3.5-1.1+deb8u1

When I install the rabbitmq-server package on a host, I run these
commands to enable AMQP 1.0 support:

   apt-get install rabbitmq-server
   rabbitmq-plugins enable rabbitmq_amqp1_0
   systemctl restart rabbitmq-server


I've also tried installing a config file /etc/rabbitmq/rabbitmq.config
although if I understand correctly, it is not needed and in fact the
package doesn't install it there by default.


Sending to RabbitMQ with qpid-proton python
-------------------------------------------

I started with the simple_send.py[3] example and trimmed it down to send
a single string and then stop:

    def on_sendable(self, event):
        if self.msg_body is not None:
            print("on_sendable !")
            print ("sending : %s" % (self.msg_body,))
            msg = Message(body=self.msg_body)
            event.sender.send(msg)
            self.msg_body = None

I found that the connection to RabbitMQ would be dropped and an error
would appear in the RabbitMQ log.  I tried changing the body type to a
dict containing a string, e.g. {'my_body':'foo'} and then it would
successfully pass the message to RabbitMQ but then the receiver would
complain that it was a map and not a string.

I found that the problem could be fixed by adding "inferred=True" to the
Message constructor:

            msg = Message(body=self.msg_body, inferred=True)

Below is a complete example of the error from the RabbitMQ log when
inferred=True is not present, the body in this case was the string "foo"


Receiving from RabbitMQ with qpid-proton C++
--------------------------------------------

I looked at the receive example simple_recv.cpp[4] and other examples
and noticed code like this being used to access the message body as
std::string:

proton::get<std::string>(m.body())

However, that didn't work for me, it threw a conversion_error exception
"unexpected type, want: string got: binary" complaining that the body
was binary.  I had to use something like this to convert my message body
to a std::string:

   proton::binary __b = proton::get<proton::binary>(m.body());
   std::string _s = (std::string)__b;

If I send a string from Python, should it appear as binary in the
receiver?  What is the suggested way to write a receiver that can handle
any arbitrary message that started as a string and may arrive in some
other format, especially if the message broker or client is changed at
some arbitrary time in the future?

I also observed similar issues receiving messages that had been sent
into RabbitMQ by Kamailio's kazoo module[5], it is linked with the
librabbitmq client library.

Regards,

Daniel





1. https://packages.qa.debian.org/q/qpid-proton.html
2. https://packages.qa.debian.org/r/rabbitmq-server.html
3.
https://qpid.apache.org/releases/qpid-proton-0.17.0/proton/python/examples/simple_send.py.html
4.
https://qpid.apache.org/releases/qpid-proton-0.17.0/proton/cpp/examples/simple_recv.cpp.html
5. http://www.kamailio.org/docs/modules/4.4.x/modules/kazoo.html


Error from RabbitMQ log:

=INFO REPORT====
accepting AMQP connection <0.891.0> (127.0.0.1:48410 -> 127.0.0.1:5672)

=ERROR REPORT====
** Generic server <0.897.0> terminating
** Last message in was {'$gen_cast',
                           {frame,
                               {{'v1_0.transfer',
                                    {uint,0},
                                    {uint,0},
                                    {binary,<<"1">>},
                                    {uint,0},

false,false,undefined,undefined,undefined,
                                    undefined,undefined},

<<0,83,112,208,0,0,0,11,0,0,0,5,66,80,4,64,66,
                                  82,0,0,83,115,208,0,0,0,34,0,0,0,13,64,64,

64,64,64,64,64,64,131,0,0,0,0,0,0,0,0,131,0,

0,0,0,0,0,0,0,64,82,0,64,0,83,119,160,3,102,
                                  111,111>>},
                               <0.891.0>}}
** When Server state == {state,<0.900.0>,<0.906.0>,unlimited,<0.891.0>,
                            <0.896.0>,
                            {[],[]},

{session,0,2147483647,2147483647,0,65535,65535,0,
                                65535,65535,1,0,
                                {0,nil},
                                {0,nil}}}
** Reason for termination ==
** {function_clause,
       [{rabbit_amqp1_0_framing,fill_from_binary,
            [{'v1_0.amqp_value',undefined},<<"foo">>],
            [{file,"rabbitmq-amqp1.0/src/rabbit_amqp1_0_framing.erl"},
             {line,56}]},
        {rabbit_amqp1_0_message,decode_section,1,
            [{file,"rabbitmq-amqp1.0/src/rabbit_amqp1_0_message.erl"},
             {line,122}]},
        {rabbit_amqp1_0_message,assemble,4,
            [{file,"rabbitmq-amqp1.0/src/rabbit_amqp1_0_message.erl"},
             {line,62}]},
        {rabbit_amqp1_0_message,assemble,1,
            [{file,"rabbitmq-amqp1.0/src/rabbit_amqp1_0_message.erl"},
             {line,30}]},
        {rabbit_amqp1_0_incoming_link,transfer,4,
            [{file,"rabbitmq-amqp1.0/src/rabbit_amqp1_0_incoming_link.erl"},
             {line,148}]},
        {rabbit_amqp1_0_session_process,handle_control,2,

[{file,"rabbitmq-amqp1.0/src/rabbit_amqp1_0_session_process.erl"},
             {line,214}]},
        {rabbit_amqp1_0_session_process,handle_cast,2,

[{file,"rabbitmq-amqp1.0/src/rabbit_amqp1_0_session_process.erl"},
             {line,134}]},
        {gen_server2,handle_msg,2,
            [{file,"src/gen_server2.erl"},{line,1022}]}]}

=ERROR REPORT====
closing AMQP connection <0.891.0> (127.0.0.1:48410 -> 127.0.0.1:5672):
{handshake_error,running,<0.897.0>,
    {{symbol,"amqp:internal-error"},
     "Session error: ~p~n~p~n",
     [function_clause,
      [{rabbit_amqp1_0_framing,fill_from_binary,
           [{'v1_0.amqp_value',undefined},<<"foo">>],
           [{file,"rabbitmq-amqp1.0/src/rabbit_amqp1_0_framing.erl"},
            {line,56}]},
       {rabbit_amqp1_0_message,decode_section,1,
           [{file,"rabbitmq-amqp1.0/src/rabbit_amqp1_0_message.erl"},
            {line,122}]},
       {rabbit_amqp1_0_message,assemble,4,
           [{file,"rabbitmq-amqp1.0/src/rabbit_amqp1_0_message.erl"},
            {line,62}]},
       {rabbit_amqp1_0_message,assemble,1,
           [{file,"rabbitmq-amqp1.0/src/rabbit_amqp1_0_message.erl"},
            {line,30}]},
       {rabbit_amqp1_0_incoming_link,transfer,4,
           [{file,"rabbitmq-amqp1.0/src/rabbit_amqp1_0_incoming_link.erl"},
            {line,148}]},
       {rabbit_amqp1_0_session_process,handle_control,2,

[{file,"rabbitmq-amqp1.0/src/rabbit_amqp1_0_session_process.erl"},
            {line,214}]},
       {rabbit_amqp1_0_session_process,handle_cast,2,

[{file,"rabbitmq-amqp1.0/src/rabbit_amqp1_0_session_process.erl"},
            {line,134}]},
       {gen_server2,handle_msg,2,
           [{file,"src/gen_server2.erl"},{line,1022}]}]]}}



---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to