On 06/11/2013 08:06 PM, CLIVE wrote:
Thanks for the advice on the address strings, tried it today and all
worked as expected. Looking at your mechanism for undertaking bindings I
am going to re-design my application any way so that I create a single
receiver and apply the required bindings. Just one question, is there a
qmf command I could send to get the current list of bindings?

Yes, in qmf you send a 'query request' (the qmf.opcode is _query_request rather than _method_request) where the body is a map describing the class (or alternatively the specific object) that you want to query. The messy part is pulling the relevant data out the response which is a list of maps representing objects of that class. Each map contains a nested _values map containing the properties/statistics of the object. One further quirk is that the queue and exchange for a binding are included as 'object references', so you may need to pull out the visible name for that as well.

Attached is another example. Its rather a quick hack so you'd want a bit more error checking in the real thing but hopefully it helps illustrate the basic approach.

With regard to my use case. The reason for using a single queue with
multiple bindings is that the order of the messages hitting the queue is
important.

Make sense.

/*
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
 */


#include <qpid/messaging/Address.h>
#include <qpid/messaging/Connection.h>
#include <qpid/messaging/Message.h>
#include <qpid/messaging/Receiver.h>
#include <qpid/messaging/Sender.h>
#include <qpid/messaging/Session.h>
#include <qpid/types/Variant.h>
#include <iostream>

using namespace qpid::messaging;
using namespace qpid::types;

std::string getName(const std::string& id)
{
    //object id consists of a package, class and name triple, separated by ':'
    //note: would probably want some checking in a real program!
    return id.substr(id.find_last_of(":")+1);
}

int main(int argc, char** argv)
{
    Connection c(argc > 1 ? argv[1] : "localhost");
    try {
        c.open();
        Session session = c.createSession();
        Address responses("#; {create: always, node: {x-declare: {auto-delete:True}}}");
        Receiver r = session.createReceiver(responses);
        Sender s = session.createSender("qmf.default.direct/broker");

    	Message request;
        request.setReplyTo(responses);
        request.setContentType("amqp/map");
        request.setProperty("x-amqp-0-10.app-id", "qmf2");
        request.setProperty("qmf.opcode", "_query_request");
        Variant::Map schemaId;
        schemaId["_class_name"] = "binding";
        Variant::Map content;
        content["_what"] = "OBJECT";
        content["_schema_id"] = schemaId;

        encode(content, request);
        s.send(request);
        Message response = r.fetch();
        Variant::List contentIn;
        decode(response, contentIn);
        for (Variant::List::const_iterator i = contentIn.begin(); i != contentIn.end(); ++i) {
            Variant::Map item = i->asMap();
            Variant::Map values = item["_values"].asMap();
            std::string queue = getName(values["queueRef"].asMap()["_object_name"]);
            std::string exchange = getName(values["exchangeRef"].asMap()["_object_name"]);
            std::string key = values["bindingKey"];

            std::cout << exchange << " " << queue << " " << key << std::endl;
        }
        session.acknowledge();
    } catch(const std::exception& error) {
        std::cout << "ERROR: " << error.what() << std::endl;
    }
    c.close();
    return 0;
}



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

Reply via email to