I agree, this is a bug. I've raised a JIRA and will get that fixed:
https://issues.apache.org/jira/browse/QPID-3492
Hi all,
For everyone who's been following this thread and have been bitten by
this issue, in lieu of a patch to the AddressParser itself the following
code just might help you out. It's a basic "client side" code block
that, in essence, "repairs" an Address created by the broken
AddressParser by working its way through the various Address blocks
until it gets to the x-bindings arguments block it then iterates through
each argument explicitly setting the encoding of VAR_STRING valued
arguments to utf8.
My C++ is somewhat rusty so there might well be more elegant/succinct
ways to find the arguments block, feel free to post back something
nicer, but the code below seems a fair starter for ten. I've tried it
with a basic Java producer and the "repaired" bindings match nicely.
Hope this is some use,
Frase.
/*
// Example Usage:
string address = "testqueue; {create: receiver, node: {x-declare:
{arguments: {'qpid.policy_type': ring, 'qpid.max_size': 500000000}},
x-bindings: [{exchange: 'amq.match', queue: 'testqueue', key: 'data1',
arguments: {x-match: all, data-service: amqp-delivery, item-owner:
fadams}}]}}";
Address addr(address);
addr = utf8EncodeAddress(addr);
Connection connection(broker, connectionOptions);
try {
connection.open();
Session session = connection.createSession();
Receiver receiver = session.createReceiver(addr);
receiver.setCapacity(100); // Enable receiver prefetch
......etc.....
*/
/*
There is a bug in the Qpid C++ AddressParser code up to at least
version 0.12 whereby strings values get encoded
as raw binary values as opposed to UTF8. In many circumstances this
doesn't cause significant problems, however
for the case of bindings to the headers exchange it has the
potential to create a serious interoperability problem
as Java producers in particular will certainly set header strings as
UTF8 Java Strings.
These methods "repair" an Address by re-encoding x-bindings argument
values as UTF8 strings so that they work
in an interoperable way with the Headers exchange. Note well the use
of references as we're changing the
underlying Address passed to the method.
*/
/*
This method looks for the "x-bindings" Map within a "node" or "link"
block and if one is found it then
iterates through the bindings. For each binding that is found the
"arguments" Map is looked up and if
an "arguments" Map is found the method iterates though each argument
explicitly setting the encoding
of VAR_STRING valued arguments to utf8.
*/
void utf8EncodeBlock(Variant::Map& block) {
Variant::Map::iterator i = block.find("x-bindings");
if (i != block.end()) {
Variant::List& bindings = i->second.asList();
for (Variant::List::iterator li = bindings.begin(); li !=
bindings.end(); li++) {
Variant::Map& binding = li->asMap();
i = binding.find("arguments");
if (i != binding.end()) {
Variant::Map& arguments = i->second.asMap();
for (i = arguments.begin(); i != arguments.end(); i++) {
if (i->second.getType() == VAR_STRING) {
i->second.setEncoding("utf8");
}
}
}
}
}
}
/*
This method extracts the "node" and "link" Maps from the options
part of the Address and passes references
to them to the utf8EncodeBlock method in order to repair the
contents of the block.
*/
Address& utf8EncodeAddress(Address& addr) {
Variant::Map& options = addr.getOptions();
Variant::Map::iterator i = options.find("node");
if (i != options.end()) {
utf8EncodeBlock(i->second.asMap());
}
i = options.find("link");
if (i != options.end()) {
utf8EncodeBlock(i->second.asMap());
}
return addr;
}
---------------------------------------------------------------------
Apache Qpid - AMQP Messaging Implementation
Project: http://qpid.apache.org
Use/Interact: mailto:users-subscr...@qpid.apache.org