On 03/15/2018 05:23 PM, Andrew Stitcher wrote:
On Thu, 2018-03-15 at 15:54 -0400, Kim van der Riet wrote:
When creating an AMQP map body, using

std::map<proton::value, proton::value> map;

to represent the map, and once its values have been set,

proton::message msg;
msg.body(map);

is a convenient way to set the message body. However, in practice, I
am
finding this approach has one problem - I cannot guarantee the
key/value
ordering within the map.

Why do want to do this?
This is a part of the AMQP client interoperability testing. Part of the test must ensure that the map is not re-ordered in any way by the clients or broker.


On the receiving end, if I don't know the map keys in advance, I need
to
use a similar approach:

std::map<proton::value, proton::value> map;
proton::get(msg.body(), map);

which puts the map into a std::map where I can iterate through keys,
etc. But as soon as I do this, I have lost the ordering guarantees
of
the original message, as the map will iterate through the keys in an
internal order unrelated to the message ordering.

What is the correct way to both set a proton::value as a map in such
a
way that the ordering is preserved when I both set the values and
read
them afterward without knowledge of the keys?

I'm not sure what you are trying to accomplish, perhaps you can explain
  and that would make this easier to answer.

For interoperability test purposes, I need to create and send an AMQP message containing an AMQP map type. The map needs to have a well-defined sequence of keys/values. On receipt, the map must be retrieved in such a way that the order as sent on the wire is not lost, and once retrieved, compared with the original map.

On message creation, I assume that using the proton::map::put(k,v) will ensure that the elements will be inserted into the map in the order this function is called. However, retrieving the map from a message in a way that guarantees the order of the map eludes me. There is a proton::map::get(k) method, but that assumes you know the keys. The receivers have no knowledge of the map contents or keys, so it must somehow get an ordered list of keys. I cannot see how to do that. It seems to me that the API needs something like

std::vector<proton::value> proton::map::get_keys();

which would provide an ordered key list. Then using proton::map::get(k) makes sense.

Without this, there is no way to test the ordering guarantees required by the AMQP 1.0 spec.


Essentially though the AMQP concept of a map and language binding
concepts of maps differ.

They are just the closest most convenient things that allow users to
accomplish what they most likely want to accomplish: That is to send an
application level map/dictionary and receive it in a perhaps different
language environment with the same meaning (more-or-less).

As it happens std::map actually does have a well defined order (it is
always ordered by the "less-than" relation on its keys) and I believe
that the Qpid C++ binding coder will transcribe that into the AMQP map
- this is not one of our tests though so it is entirely possible the
iterator used goes backwards instead!

How is the "less-than" relation set for proton::value objects? If there were a method to set the order through calling a setter function, that would make life a lot easier.


However the map binding in other languages is much more likely to use
the hash of the keys in the data structure and so there will be no well
defined order for them.

There are other "features" of AMQP maps that just aren't directly
transcribeable to language features - especially if there are repeated
identical keys in an AMQP map.

Hope that helps

Andrew


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


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

Reply via email to