You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@qpid.apache.org by Gordon Sim <gs...@redhat.com> on 2013/08/06 19:24:40 UTC
qpid::messaging and map- and list- message over AMQP 1.0
In AMQP 0-10 message content was essentially always treated as raw
data, with the content-type indicating how those bytes were to be
interpreted. For map- and list- messages we used a content-type of
amqp/map and amqp/list respectively.
In AMQP 1.0, though you can of course still send raw data (as a Data
section) with a content-type specified in the properties, the preferred
method of sending maps and lists is through an AmqpValue section with
the type encoded in the bytes making up that section.
I've been working on support for map- and list- messages over 1.0
through the c++ qpid::messaging API and have an approach ready for some
feedback[1].
Over 0-10, the approach used was to have encode/decode functions that
work with a Variant::Map or Variant::List. The application was
responsible for encoding outgoing messages before sending them and
checking the content-type on received messages and decoding them if
appropriate.
Now that the content-type cannot be relied on to indicate the type of
the message (indeed the specification encourages it *not* to be used,
relying only on the type encoding in the AmqpValue section), a different
approach is necessary.
I've added a method to Message to get the content as a Variant. This can
be used for a whole range of different types of data including binary or
maps and lists. All the existing methods for accessing content remain of
course and in the case of structured data, they will return the raw bytes.
With this approach, the application doesn't directly encode or decode
the data itself, but simply reads or manipulates the Variant typed
content. E.g instead of:
Message message;
Variant::Map content;
content["a"] = "bcd";
encode(content, message);
sender.send(message);
a map message would be sent like this:
Message message;
message.content() = Variant::Map();
message.content()["a"] = "bcd";
sender.send(message);
and instead of:
Message message = receiver.receive();
if (message.getContentType() == "amqp/map") {
Variant::Map content;
decode(message, content);
//process content:
std::string x = content["a"];
} else {
//handle unexpected format
}
receiving a map message would look like this:
Message message = receiver.receive();
if (message.content().getType() == VAR_MAP) {
//process content:
std::string x = message.content().asMap()["a"];
} else {
//handle unexpected format
}
The old approach will of course continue to work for 0-10 without
modification, but in order to support the same pattern over both
protocols I have modified the 0-10 path also. For sending, if you don't
touch Message::content() then it will behave just like it did before.
For receiving, map- and list- messages will by default be decoded
automatically when fetched (and made available via Message::content()).
This can if desired be disabled via a connection option; it doesn't
break anything but if your application already explicitly tests the
content type and decodes then its doing redundant work.
For 1.0 you can also of course continue to send raw bytes with an
associated content-type if desired as well. I haven't actually exposed
1.0 based encode and decode routines for this purpose though.
Any feedback on this as an approach is welcome. I'd be especially
excited to hear from anyone who thinks they might want to send AMQP 1.0
encoded structured content. A patch is available for those who want to
see the gory details[1].
--Gordon.
[1] https://reviews.apache.org/r/13328/
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@qpid.apache.org
For additional commands, e-mail: users-help@qpid.apache.org