[ 
https://issues.apache.org/jira/browse/QPID-2411?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Andrew English updated QPID-2411:
---------------------------------

    Attachment: qmf-cpp-console-tutorial.html

Attach tutorial as file.

> Created Documentation for Writing a CPP QMF console application
> ---------------------------------------------------------------
>
>                 Key: QPID-2411
>                 URL: https://issues.apache.org/jira/browse/QPID-2411
>             Project: Qpid
>          Issue Type: Improvement
>          Components: Documentation
>            Reporter: Andrew English
>            Priority: Minor
>         Attachments: qmf-cpp-console-tutorial.html
>
>
> I have pasted in my initial draft of the documentation for creating a QMF 
> console application in C++.  If this is still needed, I will complete the 
> sections on calling methods and asynchronous notifications.
> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
> "http://www.w3.org/TR/html4/loose.dtd";>
> <html><head>
>   
>     <link type="text/css" rel="stylesheet" 
> href="qmf-python-console-tutorial_files/space.css">
>     <style type="text/css">
>       .footer {
>         background-image:      
> url('http://cwiki.apache.org/confluence/images/border/border_bottom.gif');
>         background-repeat:     repeat-x;
>         background-position:   left top;
>         padding-top:           4px;
>         color:                 #666;
>         clear:                 both;
>       }
>      .left {
>         padding-top: 5px;
>       float : left;
>         width : 15em;
>       }
>       .pagecontent {
>          float: left;
>          width: 70%;
>       }
>     </style>
>     <script type="text/javascript" language="javascript">
>       var hide = null;
>       var show = null;
>       var children = null;
>       function init() {
>         /* Search form initialization */
>         var form = document.forms['search'];
>         if (form != null) {
>           form.elements['domains'].value = location.hostname;
>           form.elements['sitesearch'].value = location.hostname;
>         }
>         /* Children initialization */
>         hide = document.getElementById('hide');
>         show = document.getElementById('show');
>         children = document.all != null ?
>                    document.all['children'] :
>                    document.getElementById('children');
>         if (children != null) {
>           children.style.display = 'none';
>           show.style.display = 'inline';
>           hide.style.display = 'none';
>         }
>       }
>       function showChildren() {
>         children.style.display = 'block';
>         show.style.display = 'none';
>         hide.style.display = 'inline';
>       }
>       function hideChildren() {
>         children.style.display = 'none';
>         show.style.display = 'inline';
>         hide.style.display = 'none';
>       }
>     </script>
>     <title>Apache Qpid: Open Source AMQP Messaging - QMF Cpp Console 
> Tutorial</title>
>   <meta http-equiv="Content-Type" content="text/html; 
> charset=UTF-8"></head><body
>  onload="init()">
>     <table width="100%" border="0" cellpadding="2" cellspacing="0">
>       <tbody><tr class="topBar">
>         <td class="topBarDiv" valign="middle" align="left" 
> nowrap="nowrap">
>           &nbsp;<a href="http://qpid.apache.org/index.html"; 
> title="Apache Qpid">Apache Qpid</a>&nbsp;&gt;&nbsp;<a 
> href="http://qpid.apache.org/index.html"; 
> title="Index">Index</a>&nbsp;&gt;&nbsp;<a
>  href="http://qpid.apache.org/developer-pages.html"; title="Developer 
> Pages">Developer Pages</a>&nbsp;&gt;&nbsp;<a 
> href="http://qpid.apache.org/qpid-management-framework.html"; title="Qpid
>  Management Framework">Qpid Management Framework</a>&nbsp;&gt;&nbsp;<a 
> href="" title="QMF Cpp Console Tutorial">QMF Cpp Console Tutorial</a>
>         </td>
>         <td valign="middle" align="right" nowrap="nowrap">
>           <form name="search" action="http://www.google.com/search"; 
> method="get">
>             <input name="ie" value="UTF-8" type="hidden">
>             <input name="oe" value="UTF-8" type="hidden">
>             <input name="domains" value="qpid.apache.org" type="hidden">
>             <input name="sitesearch" value="qpid.apache.org" 
> type="hidden">
>             <input name="q" maxlength="255" type="text">        
>             <input name="btnG" value="Google Search" type="submit">
>           </form>
>         </td>
>       </tr> 
>     </tbody></table>
>     <div id="PageContent">
>         <div class="pageheader" style="padding: 6px 0px 0px;">
> <div>
> <table width="90%" border="0">
> <tbody><tr>
> <td align="left">
> <a href="http://qpid.apache.org/";>
> <img src="qmf-python-console-tutorial_files/qpid-logo.png" width="225" 
> border="0" height="69"></a>
> </td>
> <td>
> </td>
> <td align="right">          <a href="http://www.apache.org/";>
>             <img src="qmf-python-console-tutorial_files/asf-logo.png" 
> width="225" border="0" height="69"></a></td>
> </tr>
> </tbody></table>
> </div>
>       </div>
> <!--
>       <div class="pagesubheading" style="margin: 0px 10px 0px 10px;">
>                     Added by <a href="/confluence/display/~tross">Ted 
> Ross</a>, last edited by <a href="/confluence/display/~tross">Ted Ross</a> on 
> Mar 03, 2009
>                       &nbsp;(<a class="noprint" 
> href="/confluence/pages/diffpages.action?pageId=108629&originalId=111632">view
>  change</a>)
>               
>       </div>
> -->
>         <div class="left">
>             
>                                                                         
>                                                                         
>                                                                         
>                                                                         
>                                                                         
>                                                                         
>                                                                         
>                                                                         
>                                                                         
>                                                                         
>                                                                         
>                                     
>                                                 
>             <div class="panel" style="border: 1px solid rgb(32, 32, 
> 128);"><div class="panelContent" style="">
> <h3><a name="Navigation-ApacheQpid"></a>Apache Qpid</h3>
> <p> <a href="http://qpid.apache.org/index.html"; title="Index">Home</a><br>
>  <a href="http://qpid.apache.org/download.html"; 
> title="Download">Download</a><br>
>  <a href="http://qpid.apache.org/getting-started.html"; title="Getting 
> Started">Getting Started</a> <br>
>  <a href="http://qpid.apache.org/documentation.html"; 
> title="Documentation">Documentation</a><br>
>  <a href="http://qpid.apache.org/mailing-lists.html"; title="Mailing 
> Lists">Mailing Lists</a><br>
>  <a href="http://issues.apache.org/jira/browse/qpid"; rel="nofollow">Issue
>  Reporting</a><br>
>  <a href="http://qpid.apache.org/faq.html"; title="FAQ">FAQ/How to</a></p>
> <h3><a name="Navigation-Resources"></a>Resources</h3>
> <p> <a href="http://qpid.apache.org/getting-involved.html"; 
> title="Getting Involved">Getting Involved</a><br>
>  <a href="http://qpid.apache.org/qpid-integrations.html"; title="Qpid 
> Integrations">Qpid Integrated with..</a><br>
>  <a href="http://qpid.apache.org/source-repository.html"; title="Source 
> Repository">Source Repository</a><br>
>  <a href="http://qpid.apache.org/building.html"; title="Building">Building
>  Qpid</a><br>
>  <a href="http://qpid.apache.org/developer-pages.html"; title="Developer 
> Pages">Developer Pages</a><br>
>  <a href="http://qpid.apache.org/qpid-management-framework.html"; 
> title="Qpid Management Framework">QMF</a></p>
> <h3><a name="Navigation-AboutQpid"></a>About Qpid</h3>
> <p> <a href="http://qpid.apache.org/people.html"; title="People">People</a><br>
>  <a href="http://qpid.apache.org/license.html"; title="License">License</a><br>
>  <a href="http://qpid.apache.org/project-status.html"; title="Project 
> Status">Project Status</a><br>
>  <a href="http://qpid.apache.org/acknowledgments.html"; 
> title="Acknowledgments">Acknowledgments</a></p>
> <h3><a name="Navigation-AboutAMQP"></a>About AMQP</h3>
> <p> <a 
> href="http://qpid.apache.org/amqp-advanced-message-queueing-protocol.html";
>  title="AMQP (Advanced Message Queueing Protocol)">What is AMQP ?</a><br>
>  <a 
> href="http://qpid.apache.org/amqp-advanced-message-queueing-protocol.html";
>  title="AMQP (Advanced Message Queueing Protocol)">AMQP Specification 
> Download</a></p>
> <p><img src="qmf-python-console-tutorial_files/AMQP_logo_71px-small.jpg"
>  align="absmiddle" border="0"></p>
> </div></div>
>                                                                         
>                                                                         
>                                                                         
>                                                                         
>                                                                         
>                                                                         
>                                                                         
>                                                                         
>                                                                         
>                                                                         
>                                                                         
>                                                                         
>                                                                         
>                                                                         
>                                                                         
>                                                                         
>                                                                         
>                                                                         
>                                                                         
>                                                                         
>                                                                         
>                                                                         
>                                                                         
>                                                                         
>                                                                         
>                                                                         
>                                                                         
>                                                                         
>                                                                         
>                                                                         
>                                                                         
>                                                                         
>                                                                         
>                                                                         
>                                                                         
>                                                                         
>                                                                         
>                                                                         
>                         </div>
>       <div class="pagecontent">
>         <div class="wiki-content">
>           <div>
> <ul>
>     <li><a 
> href="#QMFCPPConsoleTutorial-PrerequisiteInstallQpidMessaging">Prerequisite
>  - Install Qpid Messaging</a></li>
>     <li><a 
> href="#QMFCPPConsoleTutorial-SynchronousConsoleOperations">Synchronous
>  Console Operations</a></li>
> <ul>
>     <li><a 
> href="#QMFCPPConsoleTutorial-CreatingaQMFConsoleSessionandAttachingtoaBroker">Creating
>  a QMF Console Session and Attaching to a Broker</a></li>
>     <li><a href="#QMFCPPConsoleTutorial-AccessingManagedObjects">Accessing
>  Managed Objects</a></li>
> <ul>
>     <li><a 
> href="#QMFCPPConsoleTutorial-ViewingPropertiesandStatisticsofanObject">Viewing
>  Properties and Statistics of an Object</a></li>
>     <li><a href="#QMFCPPConsoleTutorial-InvokingMethodsonanObject">Invoking
>  Methods on an Object</a></li>
> </ul>
> </ul>
>     <li><a 
> href="#QMFPythonConsoleTutorial-AsynchronousConsoleOperations">Asynchronous
>  Console Operations</a></li>
> <ul>
>     <li><a 
> href="#QMFPythonConsoleTutorial-CreatingaConsoleClasstoReceiveAsynchronousData">Creating
>  a Console Class to Receive Asynchronous Data</a></li>
>     <li><a href="#QMFPythonConsoleTutorial-ReceivingEvents">Receiving 
> Events</a></li>
>     <li><a href="#QMFPythonConsoleTutorial-ReceivingObjects">Receiving 
> Objects</a></li>
>     <li><a 
> href="#QMFPythonConsoleTutorial-AsynchronousMethodCallsandMethodTimeouts">Asynchronous
>  Method Calls and Method Timeouts</a></li>
> </ul>
>     <li><a 
> href="#QMFPythonConsoleTutorial-DiscoveringwhatKindsofObjectsareAvailable">Discovering
>  what Kinds of Objects are Available</a></li>
> </ul></div>
> <h1><a 
> name="QMFPythonConsoleTutorial-PrerequisiteInstallQpidMessaging"></a>Prerequisite
>  - Install Qpid Messaging</h1>
> <p>QMF uses AMQP Messaging (QPid) as its means of communication.  To use
>  QMF, Qpid messaging must be installed somewhere in the network.  Qpid 
> can be downloaded as source from Apache, is packaged with a number of 
> Linux distributions, and can be purchased from commercial vendors that 
> use Qpid.  Please see <a href="http://qpid.apache.org/download.html"; 
> title="Download">Download</a> for information as to where to get Qpid 
> Messaging.</p>
> <p>Qpid Messaging includes a message broker (qpidd) which typically runs
>  as a daemon on a system.  It also includes client bindings in various 
> programming languages.  The C++-language client library includes the source 
> for the
> QMF console libraries needed for this tutorial.</p>
> <p>Please note that Qpid Messaging has two broker implementations.  One 
> is implemented in C++ and the other in Java.  At press time, QMF is 
> supported only by the C++ broker.</p>
> <p>If the goal is to get the tutorial examples up and running as quickly
>  as possible, all of the Qpid components can be installed on a single 
> system (even a laptop).  For more realistic deployments, the broker can 
> be deployed on a server and the client/QMF libraries installed on other 
> systems.</p>
> <h1><a 
> name="QMFCPPConsoleTutorial-SynchronousConsoleOperations"></a>Synchronous
>  Console Operations</h1>
> <p>The C++ console API for QMF can be used in a synchronous style, an
>  asynchronous style, or a combination of both.  Synchronous operations 
> are conceptually simple and are well suited for user-interactive tasks. 
>  All operations are performed in the context of a C++ function call. 
>  If communication over the message bus is required to complete an 
> operation, the function call blocks and waits for the expected result 
> (or timeout failure) before returning control to the caller.</p>
> <h2><a 
> name="QMFCPPConsoleTutorial-CreatingaQMFConsoleSessionandAttachingtoaBroker"></a>Creating
>  a QMF Console Session and Attaching to a Broker</h2>
> <p>For the purposes of this tutorial, code examples will be shown in snippets 
> revelant to the current task.</p>
> <p>We will begin by including the required libraries.  If the QMF libraries 
> are installed in the lib directory, they 
> can be referenced when building and linking the application:</p>
> <div class="preformatted panel" style="border-width: 1px;"><div 
> class="preformattedContent panelContent">
> <pre>
> g++ -c -I/usr/include/qpid-boost qmfagent.cpp -o qmfagent.o
> g++ -lqpidclient -lqmfconsole ./qmfagent.o  -o qmfagent
> </pre>
> </div></div>
> In the source, they should be included as follows:
> <div class="preformatted panel" style="border-width: 1px;"><div 
> class="preformattedContent panelContent">
> <pre>#include &lt;qpid/console/SessionManager.h&gt;
>       
> namespace qmf = qpid::console;
> </pre>
> </div></div>
> <p>We must now create a <em>Session</em> object to manage this QMF 
> console session.</p>
> <div class="preformatted panel" style="border-width: 1px;"><div 
> class="preformattedContent panelContent">
> <pre>qmf::SessionManager sessMgr;
> </pre>
> </div></div>
> <p>If no arguments are supplied to the creation of <em>Session</em>, it 
> defaults to synchronous-only operation.  It also defaults to 
> user-management of connections.  More on this in a moment.</p>
> <p>We will now establish a connection to the messaging broker.  If the 
> broker daemon is running on the local host, simply use the following:</p>
> <div class="preformatted panel" style="border-width: 1px;"><div 
> class="preformattedContent panelContent">
> <pre>qmf::Broker* broker = sessMgr.addBroker();
> </pre>
> </div></div>
> <p>If the messaging broker is on a remote host, supply the URL to the 
> broker in the <em>addBroker</em> function call.  Here's how to connect 
> to a local broker using the URL.</p>
> <div class="preformatted panel" style="border-width: 1px;"><div 
> class="preformattedContent panelContent">
> <pre>qmf::Broker* broker = sessMgr.addBroker("amqp://localhost");
> </pre>
> </div></div>
> <p>A <em>ConnectionSettings</em> object can also be passed to the 
> <em>addBroker</em> function call.</p>
> <div class="preformatted panel" style="border-width: 1px;"><div 
> class="preformattedContent panelContent">
> <pre>qmf_::SessionManager sessMgr;
> qc::ConnectionSettings settings;
> settings.host = host;
> settings.port = port;
> qmf::Broker* broker = sessMgr.addBroker(settings);
> </pre>
> </div></div>
> <p>The call to <em>addBroker</em> is synchronous and will return only 
> after the connection has been successfully established or has failed.  
> If a failure occurs, <em>addBroker</em> will raise an exception.</p>
> <div class="preformatted panel" style="border-width: 1px;"><div 
> class="preformattedContent panelContent">
> <pre>try
> {
>       qmf::Broker* broker = sessMgr.addBroker("amqp://localhost:1000");
> }
> catch(const std::exception& error) 
> {
>       std::cout &lt;&lt; "Failed to connect: " &lt;&lt; error.what() &lt;&lt; 
> std::endl;
> }
> </pre>
> </div></div>
> <p>This operation fails because there is no Qpid Messaging broker 
> listening on port 1000 (the default port for qpidd is 5672).</p>
> <p>If preferred, the QMF session can manage the connection for you.  In 
> this case, <em>addBroker</em> returns immediately and the session 
> attempts to establish the connection in the background.  This will be 
> covered in detail in the section on asynchronous operations.</p>
> <h2><a name="QMFCPPConsoleTutorial-AccessingManagedObjects"></a>Accessing
>  Managed Objects</h2>
> <p>The C++ console API provides access to remotely managed objects 
> via a <em>proxy</em> model.  The API gives the client an object that 
> serves as a proxy representing the "real" object being managed on the 
> agent application.  Operations performed on the proxy result in the same
>  operations on the real object.</p>
> <p>The following examples assume prior knowledge of the kinds of objects
>  that are actually available to be managed.  There is a section later in
>  this tutorial that describes how to discover what is manageable on the 
> QMF bus.</p>
> <p>Proxy objects are obtained by calling the <em>Session.getObjects</em>
>  function.</p>
> <p>To illustrate, we'll get a list of objects representing queues in the
>  message broker itself.</p>
> <div class="preformatted panel" style="border-width: 1px;"><div 
> class="preformattedContent panelContent">
> <pre>qmf::Object::Vector objects;
> sessMgr.getObjects(objects, "queue");
> </pre>
> </div></div>
> <p>We can also specify a specific broker when querying.</p>
> <div class="preformatted panel" style="border-width: 1px;"><div 
> class="preformattedContent panelContent">
> <pre>qmf::Broker* broker = sessMgr.addBroker("amqp://localhost:5672");
> qmf::Object::Vector objects;
> sessMgr.getObjects(objects, "queue", broker);
> </pre>
> </div></div>
> <p><em>queues</em> is an array of proxy objects representing real queues
>  on the message broker.  A proxy object can be printed to display a 
> description of the object.</p>
> <div class="preformatted panel" style="border-width: 1px;"><div 
> class="preformattedContent panelContent">
> <pre>for(unsigned int i = 0; i &lt; objects.size(); i++)
> {
>       std::string queueName = objects[i].attrString("name");
>       std::cout &lt;&lt; "name: " &lt;&lt; queueName &lt;&lt; std::endl;
>       
>       qmf::Object obj = objects[i];
>       std::cout &lt;&lt; "tostring: " &lt;&lt; obj &lt;&lt; std::endl;
> }
> name: qmfc-a3159ef6-17c5-461f-a27d-7c79fcc132fc
> tostring: org.apache.qpid.broker:queue[0-21-1-0-179] 
> 0-0-1-0-1152921504606846979:qmfc-a3159ef6-17c5-461f-a27d-7c79fcc132fc
> </pre>
> </div></div>
> <h3><a 
> name="QMFPythonConsoleTutorial-ViewingPropertiesandStatisticsofanObject"></a>Viewing
>  Attributes of an Object</h3>
> <p>Let us now focus our attention on one of the queue objects.</p>
> <div class="preformatted panel" style="border-width: 1px;"><div 
> class="preformattedContent panelContent">
> <pre>qmf::Object obj = objects[i];
> </pre>
> </div></div>
> <p>The attributes of an object are stored in a map.</p>
> <p>We can iterate through the attributes of an object:</p>
> <div class="preformatted panel" style="border-width: 1px;"><div 
> class="preformattedContent panelContent">
> <pre>qmf::Object::AttributeMap attributes = obj.getAttributes();
> for(qmf::Object::AttributeMap::const_iterator vIter = attributes.begin(); 
> vIter != attributes.end(); vIter++)
> {
>       std::cout &lt;&lt; "Attribute: " &lt;&lt; vIter->first &lt;&lt; " 
> Value: " &lt;&lt; vIter->second->str() &lt;&lt; std::endl;
> }
> Attribute: arguments Value: {}
> Attribute: autoDelete Value: T
> Attribute: bindingCount Value: 4
> Attribute: bindingCountHigh Value: 4
> Attribute: bindingCountLow Value: 4
> Attribute: byteDepth Value: 912
> Attribute: bytePersistDequeues Value: 0
> Attribute: bytePersistEnqueues Value: 0
> Attribute: byteTotalDequeues Value: 30371
> Attribute: byteTotalEnqueues Value: 31283
> Attribute: byteTxnDequeues Value: 0
> Attribute: byteTxnEnqueues Value: 0
> Attribute: consumerCount Value: 1
> Attribute: consumerCountHigh Value: 1
> Attribute: consumerCountLow Value: 1
> Attribute: durable Value: F
> Attribute: exclusive Value: T
> Attribute: messageLatencyAverage Value: 0
> Attribute: messageLatencyMax Value: 0
> Attribute: messageLatencyMin Value: 0
> Attribute: messageLatencySamples Value: 0
> Attribute: msgDepth Value: 3
> Attribute: msgPersistDequeues Value: 0
> Attribute: msgPersistEnqueues Value: 0
> Attribute: msgTotalDequeues Value: 72
> Attribute: msgTotalEnqueues Value: 75
> Attribute: msgTxnDequeues Value: 0
> Attribute: msgTxnEnqueues Value: 0
> Attribute: name Value: qmfc-bfd3ec18-8222-488f-8c3d-221029145106
> Attribute: unackedMessages Value: 0
> Attribute: unackedMessagesHigh Value: 0
> Attribute: unackedMessagesLow Value: 0
> Attribute: vhostRef Value: 0-0-1-0-1152921504606846979
> </pre>
> </div></div>
> <p>A more convenient way to access attributes is by using the attribute 
> of the proxy object directly:</p>
> <div class="preformatted panel" style="border-width: 1px;"><div 
> class="preformattedContent panelContent">
> <pre>std::string name;
> name = obj.attrString("name");
> std::cout &lt;&lt; "Name: " &lt;&lt; name &lt;&lt; std::endl;
> bool autoDelete;
> autoDelete = obj.attrBool("autoDelete");
> std::cout &lt;&lt; "autoDelete: " &lt;&lt; autoDelete &lt;&lt; std::endl;
> Name: qmfc-e9d8f830-ac50-4377-b38c-7b0ffa1d86d2
> autoDelete: 1
> </pre>
> </div></div>
> <p>Statistics are accessed in the same way:</p>
> <div class="preformatted panel" style="border-width: 1px;"><div 
> class="preformattedContent panelContent">
> <pre>int msgDepth;
> msgDepth = obj.attrInt("msgDepth");
> std::cout &lt;&lt; "msgDepth: " &lt;&lt; msgDepth &lt;&lt; std::endl;
> msgDepth: 0
> </pre>
> </div></div>
> <p>The proxy objects do not automatically track changes that occur on 
> the real objects.  For example, if the real queue enqueues more bytes, 
> viewing the <em>byteTotalEnqueues</em> statistic will show the same 
> number as it did the first time.  To get updated data on a proxy object,
>  query the <em>SessionManager</em> again.</p>
>         </div>
> <!--
>         -->
>       </div>
>     <div class="footer">
>       Apache Qpid, Enterprise AMQP Messaging    
>       &nbsp;
>       © 2004-2008 The Apache Software Foundation.
>       &nbsp;
>         (<a 
> href="http://cwiki.apache.org/confluence/pages/editpage.action?pageId=108629";>edit
>  this page</a>)
>     </div>
>   </div></body></html>

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


---------------------------------------------------------------------
Apache Qpid - AMQP Messaging Implementation
Project:      http://qpid.apache.org
Use/Interact: mailto:[email protected]

Reply via email to