.. 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.

Basic Usage and Examples
========================

Standalone and Interior Modes
-----------------------------

The router can operate stand-alone or as a node in a network of routers.
The mode is configured in the *router* section of the configuration
file. In stand-alone mode, the router does not attempt to collaborate
with any other routers and only routes messages among directly connected
endpoints.

If your router is running in stand-alone mode, *qdstat -a* will look
like the following:

::

    $ qdstat -a
    Router Addresses
      class   addr                   phs  distrib  in-proc  local  remote  cntnr  in  out  thru  to-proc  from-proc
      ===============================================================================================================
      local   $_management_internal       closest  1        0      0       0      0   0    0     0        0
      local   $displayname                closest  1        0      0       0      0   0    0     0        0
      mobile  $management            0    closest  1        0      0       0      1   0    0     1        0
      local   $management                 closest  1        0      0       0      0   0    0     0        0
      local   temp.1GThUllfR7N+BDP        closest  0        1      0       0      0   0    0     0        0


Note that there are a number of known addresses. *$management* is the address of
the router's embedded management agent. *temp.1GThUllfR7N+BDP* is the temporary
reply-to address of the *qdstat* client making requests to the agent.

If you change the mode to interior and restart the processs, the same
command will yield additional addresses which are used for
inter-router communication:

::

    $ qdstat -a
    Router Addresses
      class   addr                   phs  distrib    in-proc  local  remote  cntnr  in  out  thru  to-proc  from-proc
      =================================================================================================================
      local   $_management_internal       closest    1        0      0       0      0   0    0     0        0
      local   $displayname                closest    1        0      0       0      0   0    0     0        0
      mobile  $management            0    closest    1        0      0       0      1   0    0     1        0
      local   $management                 closest    1        0      0       0      0   0    0     0        0
      local   qdhello                     flood      1        0      0       0      0   0    0     0        10
      local   qdrouter                    flood      1        0      0       0      0   0    0     0        0
      topo    qdrouter                    flood      1        0      0       0      0   0    0     0        1
      local   qdrouter.ma                 multicast  1        0      0       0      0   0    0     0        0
      topo    qdrouter.ma                 multicast  1        0      0       0      0   0    0     0        0
      local   temp.wfx54+zf+YWQF3T        closest    0        1      0       0      0   0    0     0        0


Mobile Subscribers
------------------

The term "mobile subscriber" simply refers to the fact that a client may
connect to the router and subscribe to an address to receive messages
sent to that address. No matter where in the network the subscriber
attaches, the messages will be routed to the appropriate destination.

To illustrate a subscription on a stand-alone router, you can use the
examples that are provided with Qpid Proton. Using the *simple_recv.py* example
receiver:

::

    $ python ./simple_recv.py -a 127.0.0.1/my-address

This command creates a receiving link subscribed to the specified
address. To verify the subscription:

::

    $ qdstat -a
    Router Addresses
      class   addr                   phs  distrib  in-proc  local  remote  cntnr  in  out  thru  to-proc  from-proc
      ===============================================================================================================
      local   $_management_internal       closest  1        0      0       0      0   0    0     0        0
      local   $displayname                closest  1        0      0       0      0   0    0     0        0
      mobile  $management            0    closest  1        0      0       0      2   0    0     2        0
      local   $management                 closest  1        0      0       0      0   0    0     0        0
      mobile  my-address             0    closest  0        1      0       0      0   0    0     0        0
      local   temp.75_d2X23x_KOT51        closest  0        1      0       0      0   0    0     0        0


You can then, in a separate command window, run a sender to produce
messages to that address:

::

    $ python ./simple_send.py -a 127.0.0.1/my-address

Dynamic Reply-To
----------------

Dynamic reply-to can be used to obtain a reply-to address that routes
back to a client's receiving link regardless of how many hops it has to
take to get there. To illustrate this feature, see below a simple
program (written in C++ against the qpid::messaging API) that queries
the management agent of the attached router for a list of other known
routers' management addresses.

::

    #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>

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

    using std::stringstream;
    using std::string;

    int main() {
        const char* url = "amqp:tcp:127.0.0.1:5672";
        std::string connectionOptions = "{protocol:amqp1.0}";

        Connection connection(url, connectionOptions);
        connection.open();
        Session session = connection.createSession();
        Sender sender = session.createSender("mgmt");

        // create reply receiver and get the reply-to address
        Receiver receiver = session.createReceiver("#");
        Address responseAddress = receiver.getAddress();

        Message request;
        request.setReplyTo(responseAddress);
        request.setProperty("x-amqp-to", "amqp:/_local/$management");
        request.setProperty("operation", "DISCOVER-MGMT-NODES");
        request.setProperty("type", "org.amqp.management");
        request.setProperty("name, "self");

        sender.send(request);
        Message response = receiver.fetch();
        Variant content(response.getContentObject());
        std::cout << "Response: " << content << std::endl << std::endl;

        connection.close();
    }

The equivalent program written in Python against the Proton Messenger
API:

::

    from proton import Messenger, Message

    def main():
        host = "0.0.0.0:5672"

        messenger = Messenger()
        messenger.start()
        messenger.route("amqp:/*", "amqp://%s/$1" % host)
        reply_subscription = messenger.subscribe("amqp:/#")
        reply_address = reply_subscription.address

        request  = Message()
        response = Message()

        request.address = "amqp:/_local/$management"
        request.reply_to = reply_address
        request.properties = {u'operation' : u'DISCOVER-MGMT-NODES',
                              u'type'      : u'org.amqp.management',
                              u'name'      : u'self'}

        messenger.put(request)
        messenger.send()
        messenger.recv()
        messenger.get(response)

        print "Response: %r" % response.body

        messenger.stop()

    main()

