summaryrefslogtreecommitdiff
path: root/qpid/doc/book/src
diff options
context:
space:
mode:
Diffstat (limited to 'qpid/doc/book/src')
-rw-r--r--qpid/doc/book/src/ACL.xml800
-rw-r--r--qpid/doc/book/src/AMQP-.NET-Messaging-Client.xml108
-rw-r--r--qpid/doc/book/src/AMQP-C++-Messaging-Client.xml61
-rw-r--r--qpid/doc/book/src/AMQP-Compatibility.xml713
-rw-r--r--qpid/doc/book/src/AMQP-Java-JMS-Messaging-Client.xml94
-rw-r--r--qpid/doc/book/src/AMQP-Messaging-Broker-CPP-Book.xml75
-rw-r--r--qpid/doc/book/src/AMQP-Messaging-Broker-CPP.xml69
-rw-r--r--qpid/doc/book/src/AMQP-Messaging-Broker-Java-Book.xml25
-rw-r--r--qpid/doc/book/src/AMQP-Messaging-Broker-Java.xml72
-rw-r--r--qpid/doc/book/src/AMQP-Python-Messaging-Client.xml62
-rw-r--r--qpid/doc/book/src/AMQP-Ruby-Messaging-Client.xml40
-rw-r--r--qpid/doc/book/src/AMQP.xml98
-rw-r--r--qpid/doc/book/src/Add-New-Users.xml237
-rw-r--r--qpid/doc/book/src/Binding-URL-Format.xml174
-rw-r--r--qpid/doc/book/src/Book-Info.xml68
-rw-r--r--qpid/doc/book/src/Book.xml93
-rw-r--r--qpid/doc/book/src/Broker-CPP.xml40
-rw-r--r--qpid/doc/book/src/Broker-Configuration-Guide.xml28
-rw-r--r--qpid/doc/book/src/Broker-Java.xml45
-rw-r--r--qpid/doc/book/src/Cheat-Sheet-for-configuring-Exchange-Options.xml144
-rw-r--r--qpid/doc/book/src/Cheat-Sheet-for-configuring-Queue-Options.xml259
-rw-r--r--qpid/doc/book/src/Clients.xml25
-rw-r--r--qpid/doc/book/src/Configure-ACLs.xml78
-rw-r--r--qpid/doc/book/src/Configure-Java-Qpid-to-use-a-SSL-connection.xml84
-rw-r--r--qpid/doc/book/src/Configure-Log4j-CompositeRolling-Appender.xml150
-rw-r--r--qpid/doc/book/src/Configure-the-Broker-via-config.xml.xml71
-rw-r--r--qpid/doc/book/src/Configure-the-Virtual-Hosts-via-virtualhosts.xml.xml131
-rw-r--r--qpid/doc/book/src/Configuring-Management-Users.xml117
-rw-r--r--qpid/doc/book/src/Configuring-Qpid-JMX-Management-Console.xml181
-rw-r--r--qpid/doc/book/src/Connection-URL-Format.xml387
-rw-r--r--qpid/doc/book/src/Debug-using-log4j.xml298
-rw-r--r--qpid/doc/book/src/Download.xml174
-rw-r--r--qpid/doc/book/src/Excel-AddIn.xml169
-rw-r--r--qpid/doc/book/src/FAQ.xml524
-rw-r--r--qpid/doc/book/src/Getting-Started.xml90
-rw-r--r--qpid/doc/book/src/How-to-Tune-M3-Java-Broker-Performance.xml172
-rw-r--r--qpid/doc/book/src/How-to-Use-JNDI.xml175
-rw-r--r--qpid/doc/book/src/How-to-Use-SlowConsumerDisconnect.xml280
-rw-r--r--qpid/doc/book/src/InfoPlugin.xml261
-rw-r--r--qpid/doc/book/src/Introduction.xml106
-rw-r--r--qpid/doc/book/src/Java-Broker-Feature-Guide.xml84
-rw-r--r--qpid/doc/book/src/Java-Broker-StatusLogMessages.xml294
-rw-r--r--qpid/doc/book/src/Java-Environment-Variables.xml84
-rw-r--r--qpid/doc/book/src/Java-JMS-Selector-Syntax.xml96
-rw-r--r--qpid/doc/book/src/LVQ.xml362
-rw-r--r--qpid/doc/book/src/Management-Console-Security.xml252
-rw-r--r--qpid/doc/book/src/Management-Design-notes.xml2136
-rw-r--r--qpid/doc/book/src/Managing-CPP-Broker.xml462
-rw-r--r--qpid/doc/book/src/MessageStore-Tool.xml150
-rw-r--r--qpid/doc/book/src/NET-User-Guide.xml1383
-rw-r--r--qpid/doc/book/src/Programming-In-Apache-Qpid.xml6330
-rw-r--r--qpid/doc/book/src/PythonBrokerTest.xml98
-rw-r--r--qpid/doc/book/src/QMF-Python-Console-Tutorial.xml894
-rw-r--r--qpid/doc/book/src/QMan-Qpid-Management-bridge.xml166
-rw-r--r--qpid/doc/book/src/QmfBook.xml101
-rw-r--r--qpid/doc/book/src/QmfIntroduction.xml45
-rw-r--r--qpid/doc/book/src/Qpid-ACLs.xml49
-rw-r--r--qpid/doc/book/src/Qpid-Book.xml93
-rw-r--r--qpid/doc/book/src/Qpid-Compatibility-And-Interoperability-Book.xml36
-rw-r--r--qpid/doc/book/src/Qpid-Interoperability-Documentation.xml377
-rw-r--r--qpid/doc/book/src/Qpid-JMX-Management-Console-FAQ.xml96
-rw-r--r--qpid/doc/book/src/Qpid-JMX-Management-Console-User-Guide.xml793
-rw-r--r--qpid/doc/book/src/Qpid-JMX-Management-Console.xml53
-rw-r--r--qpid/doc/book/src/Qpid-Java-Broker-Management-CLI.xml159
-rw-r--r--qpid/doc/book/src/Qpid-Java-Build-How-To.xml365
-rw-r--r--qpid/doc/book/src/Qpid-Java-FAQ.xml949
-rw-r--r--qpid/doc/book/src/Qpid-Management-Features.xml185
-rw-r--r--qpid/doc/book/src/Qpid-Management-Framework.xml944
-rw-r--r--qpid/doc/book/src/Qpid-Troubleshooting-Guide.xml156
-rw-r--r--qpid/doc/book/src/Running-CPP-Broker.xml317
-rw-r--r--qpid/doc/book/src/SASL-Compatibility.xml70
-rw-r--r--qpid/doc/book/src/SSL.xml180
-rw-r--r--qpid/doc/book/src/Security-Plugins.xml624
-rw-r--r--qpid/doc/book/src/Security.xml1217
-rw-r--r--qpid/doc/book/src/Starting-a-cluster.xml561
-rw-r--r--qpid/doc/book/src/System-Properties.xml417
-rw-r--r--qpid/doc/book/src/Use-Priority-Queues.xml138
-rw-r--r--qpid/doc/book/src/Using-Broker-Federation.xml661
-rw-r--r--qpid/doc/book/src/Using-Qpid-with-other-JNDI-Providers.xml215
-rw-r--r--qpid/doc/book/src/WCF.xml137
-rw-r--r--qpid/doc/book/src/amqp-advanced-message-queueing-protocol.html237
-rw-r--r--qpid/doc/book/src/images/jmx_console/3113098.pngbin0 -> 9805 bytes
-rw-r--r--qpid/doc/book/src/images/jmx_console/3113099.pngbin0 -> 12882 bytes
-rw-r--r--qpid/doc/book/src/images/jmx_console/3113100.pngbin0 -> 38529 bytes
-rw-r--r--qpid/doc/book/src/images/jmx_console/3113101.pngbin0 -> 45933 bytes
-rw-r--r--qpid/doc/book/src/images/jmx_console/3113102.pngbin0 -> 7126 bytes
-rw-r--r--qpid/doc/book/src/images/jmx_console/3113103.pngbin0 -> 34693 bytes
-rw-r--r--qpid/doc/book/src/images/jmx_console/3113104.pngbin0 -> 61810 bytes
-rw-r--r--qpid/doc/book/src/images/jmx_console/3113105.pngbin0 -> 26365 bytes
-rw-r--r--qpid/doc/book/src/images/jmx_console/3113106.pngbin0 -> 45911 bytes
-rw-r--r--qpid/doc/book/src/images/jmx_console/3113107.pngbin0 -> 31789 bytes
-rw-r--r--qpid/doc/book/src/images/jmx_console/3113108.pngbin0 -> 39198 bytes
-rw-r--r--qpid/doc/book/src/images/jmx_console/3113109.pngbin0 -> 13295 bytes
-rw-r--r--qpid/doc/book/src/images/jmx_console/3113110.pngbin0 -> 38715 bytes
-rw-r--r--qpid/doc/book/src/images/jmx_console/3113111.pngbin0 -> 52694 bytes
-rw-r--r--qpid/doc/book/src/images/jmx_console/3113112.pngbin0 -> 39276 bytes
-rw-r--r--qpid/doc/book/src/images/jmx_console/3113113.pngbin0 -> 46459 bytes
-rw-r--r--qpid/doc/book/src/images/jmx_console/3113114.pngbin0 -> 64661 bytes
-rw-r--r--qpid/doc/book/src/images/jmx_console/3113115.pngbin0 -> 38902 bytes
-rw-r--r--qpid/doc/book/src/images/jmx_console/3113116.pngbin0 -> 9252 bytes
-rw-r--r--qpid/doc/book/src/images/jmx_console/3113117.pngbin0 -> 40855 bytes
-rw-r--r--qpid/doc/book/src/images/jmx_console/3113118.pngbin0 -> 13796 bytes
-rw-r--r--qpid/doc/book/src/images/jmx_console/3113119.pngbin0 -> 39115 bytes
-rw-r--r--qpid/doc/book/src/images/qpid-logo.pngbin0 -> 39056 bytes
-rw-r--r--qpid/doc/book/src/java/broker/configuration/Topic-Configuration.xml107
-rw-r--r--qpid/doc/book/src/producer-flow-control.xml351
-rw-r--r--qpid/doc/book/src/queue-state-replication.xml333
-rw-r--r--qpid/doc/book/src/schemas.xml101
108 files changed, 29636 insertions, 0 deletions
diff --git a/qpid/doc/book/src/ACL.xml b/qpid/doc/book/src/ACL.xml
new file mode 100644
index 0000000000..ceb7cecb23
--- /dev/null
+++ b/qpid/doc/book/src/ACL.xml
@@ -0,0 +1,800 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+
+ 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.
+
+-->
+
+<section id="qpid_ACL">
+ <title>
+ ACL
+ </title>
+
+ <section role="h2" id="ACL-v2ACLfileformatforbrokers">
+ <title>
+ v2 ACL file format for brokers
+ </title>
+ <para>
+ This new ACL implementation has been designed for implementation
+ and interoperability on all Qpid brokers. It is currently
+ supported in the following brokers:
+ </para>
+
+ <table><title>ACL Support in Qpid Broker Versions</title>
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>
+ Broker
+ </entry>
+ <entry>
+ Version
+ </entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>
+ C++
+ </entry>
+ <entry>
+ M4 onward
+ </entry>
+ </row>
+ <row>
+ <entry>
+ Java
+ </entry>
+ <entry>
+ M5 anticipated
+ </entry>
+ </row>
+ </tbody>
+ </tgroup></table>
+
+ <para>
+ Contents
+ </para>
+ <itemizedlist>
+ <listitem><para>
+ <xref linkend="ACL-v2ACLfileformatforbrokers"/>
+ </para></listitem>
+ <listitem><para>
+ <itemizedlist>
+ <listitem><para>
+ <xref linkend="ACL-Specification"/>
+ </para></listitem>
+ <listitem><para>
+ <xref linkend="ACL-Validation"/>
+ </para></listitem>
+ <listitem><para>
+ <xref linkend="ACL-Examplefile-3A"/>
+ </para></listitem>
+ </itemizedlist>
+ </para></listitem>
+ <listitem><para>
+ <xref linkend="ACL-DesignDocumentation"/>
+ </para></listitem>
+ <listitem><para>
+ <itemizedlist>
+ <listitem><para>
+ <xref linkend="ACL-MappingofACLtrapstoactionandtype"/>
+ </para></listitem>
+ </itemizedlist>
+ </para></listitem>
+ <listitem><para>
+ <xref linkend="ACL-v2ACLUserGuide"/>
+ </para></listitem>
+ <listitem><para>
+ <itemizedlist>
+ <listitem><para>
+ <xref linkend="ACL-WritingGood-2FFastACL"/>
+ </para></listitem>
+ <listitem><para>
+ <xref linkend="ACL-GettingACLtoLog"/>
+ </para></listitem>
+ <listitem><para>
+ <xref linkend="ACL-UserId-2FdomainsrunningwithCbroker"/>
+ </para></listitem>
+ </itemizedlist>
+ </para></listitem>
+ </itemizedlist>
+ <para>
+
+ </para><section role="h3" id="ACL-Specification"><title>
+ Specification
+ </title>
+ <para>
+  Notes on file formats
+ </para><itemizedlist>
+ <listitem><para>A line starting with the character '#' will be considered a
+ comment, and are ignored.
+ </para></listitem>
+ <listitem><para>Since the '#' char (and others that are commonly used for
+ comments) are commonly found in routing keys and other AMQP
+ literals, it is simpler (for now) to hold off on allowing
+ trailing comments (ie comments in which everything following a
+ '#' is considered a comment). This could be reviewed later once
+ the rest of the format is finalized.
+ </para></listitem>
+ <listitem><para>Empty lines ("") and lines that contain only whitespace (any
+ combination of ' ', '\f', '\n', '\r', '\t', '\v') are ignored.
+ </para></listitem>
+ <listitem><para>All tokens are case sensitive. "name1" != "Name1" and
+ "create" != "CREATE".
+ </para></listitem>
+ <listitem><para>Group lists may be extended to the following line by
+ terminating the line with the '\' character. However, this may
+ only occur after the group name or any of the names following the
+ group name. Empty extension lines (ie just a '\' character) are
+ not permitted.
+
+ <programlisting>
+# Examples of extending group lists using a trailing '\' character
+
+group group1 name1 name2 \
+ name3 name4 \
+ name5
+
+group group2 \
+ group1 \
+ name6
+
+# The following are illegal:
+
+# '\' must be after group name
+group \
+ group3 name7 name8
+
+# No empty extension lines
+group group4 name9 \
+ \
+ name10
+</programlisting>
+
+ </para></listitem>
+ <listitem><para>Additional whitespace (ie more than one whitespace char)
+ between and after tokens is ignored. However group and acl
+ definitions must start with "group" or "acl" respectively and
+ with no preceding whitespace.
+ </para></listitem>
+ <listitem><para>All acl rules are limited to a single line.
+ </para></listitem>
+ <listitem><para>Rules are interpreted from the top of the file down until the
+ name match is obtained; at which point processing stops.
+ </para></listitem>
+ <listitem><para>The keyword "all" is reserved, and matches all individuals,
+ groups and actions. It may be used in place of a group or
+ individual name and/or an action - eg "acl allow all all", "acl
+ deny all all" or "acl deny user1 all".
+ </para></listitem>
+ <listitem><para>The last line of the file (whether present or not) will be
+ assumed to be "acl deny all all". If present in the file, any
+ lines below this one are ignored.
+ </para></listitem>
+ <listitem><para>Names and group names may contain only a-z, A-Z, 0-9,
+ '-','_'.
+ </para></listitem>
+ <listitem><para>Rules must be preceded by any group definitions they may use;
+ any name not previously defined as a group will be assumed to be
+ that of an individual.
+ </para></listitem>
+ <listitem><para>ACL rules must have the following tokens in order on a single
+ line:
+ <itemizedlist>
+ <listitem><para>The string literal "acl";
+ </para></listitem>
+ <listitem><para>The permission;
+ </para></listitem>
+ <listitem><para>The name of a single group or individual or the keyword
+ "all";
+ </para></listitem>
+ <listitem><para>The name of an action or the keyword "all";
+ </para></listitem>
+ <listitem><para>Optionally, a single object name or the keyword "all";
+ </para></listitem>
+ <listitem><para>If the object is present, then optionally one or more
+ property name-value pair(s) (in the form property=value).
+ </para></listitem>
+ </itemizedlist>
+ </para></listitem>
+ </itemizedlist>
+ <programlisting>
+user = username[@domain[/realm]]
+user-list = user1 user2 user3 ...
+group-name-list = group1 group2 group3 ...
+
+group &lt;group-name&gt; = [user-list] [group-name-list]
+
+
+permission = [allow|allow-log|deny|deny-log]
+action = [consume|publish|create|access|bind|unbind|delete|purge|update]
+object = [virtualhost|queue|exchange|broker|link|route|method]
+property = [name|durable|owner|routingkey|passive|autodelete|exclusive|type|alternate|queuename|schemapackage|schemaclass]
+
+acl permission {&lt;group-name&gt;|&lt;user-name&gt;|"all"} {action|"all"} [object|"all"] [property=&lt;property-value&gt;]
+</programlisting>
+<!--h3--></section>
+ <section role="h3" id="ACL-Validation"><title>
+ Validation
+ </title>
+ <para>
+ The new ACL file format needs to perform validation on the acl
+ rules. The validation should be performed depending on the set
+ value:
+ </para><para>
+ strict-acl-validation=none
+ The default setting should be 'warn'
+ </para><para>
+ On validation of this acl the following checks would be expected:
+ </para>
+ <programlisting>
+acl allow client publish routingkey=exampleQueue exchange=amq.direct
+</programlisting>
+ <orderedlist>
+ <listitem><para>The If the user 'client' cannot be found, if the
+ authentication mechanism cannot be queried then a 'user' value
+ should be added to the file.
+ </para></listitem>
+ <listitem><para>There is an exchange called 'amq.direct'
+ </para></listitem>
+ <listitem><para>There is a queue bound to 'exampleQueue' on 'amq.direct'
+ </para></listitem>
+ </orderedlist><para>
+ Each of these checks that fail will result in a log statement
+ being generated.
+ </para><para>
+ In the case of a fatal logging the full file will be validated
+ before the broker shuts down.
+ </para>
+<!--h3--></section>
+
+
+ <section role="h3" id="ACL-Examplefile-3A"><title>
+ Example file:
+ </title>
+
+ <programlisting>
+
+# Some groups
+group admin ted@QPID martin@QPID
+group user-consume martin@QPID ted@QPID
+group group2 kim@QPID user-consume rob@QPID
+group publisher group2 \
+ tom@QPID andrew@QPID debbie@QPID
+
+# Some rules
+acl allow carlt@QPID create exchange name=carl.*
+acl deny rob@QPID create queue
+acl allow guest@QPID bind exchange name=amq.topic routingkey=stocks.ibm.# owner=self
+acl allow user-consume create queue name=tmp.*
+
+acl allow publisher publish all durable=false
+acl allow publisher create queue name=RequestQueue
+acl allow consumer consume queue durable=true
+acl allow fred@QPID create all
+acl allow bob@QPID all queue
+acl allow admin all
+acl deny kim@QPID all
+acl allow all consume queue owner=self
+acl allow all bind exchange owner=self
+
+# Last (default) rule
+acl deny all all
+</programlisting>
+
+<!--h3--></section>
+ <!--h2--></section>
+
+
+ <section role="h2" id="ACL-DesignDocumentation"><title>
+ Design Documentation
+ </title>
+ <section role="h3" id="ACL-MappingofACLtrapstoactionandtype"><title>
+ Mapping of ACL
+ traps to action and type
+ </title>
+ <para>
+ The C++ broker maps the ACL traps in the follow way for AMQP
+ 0-10:
+ The Java broker currently only performs ACLs on the AMQP
+ connection not on management functions:
+ </para>
+
+ <table>
+ <title>Mapping ACL Traps</title>
+ <tgroup cols="5">
+ <thead>
+ <row>
+ <entry>
+ Object
+ </entry>
+ <entry>
+ Action
+ </entry>
+ <entry>
+ Properties
+ </entry>
+ <entry>
+ Trap C++
+ </entry>
+ <entry>
+ Trap Java
+ </entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>
+ Exchange
+ </entry>
+ <entry>
+ Create
+ </entry>
+ <entry>
+ name type alternate passive durable
+ </entry>
+ <entry>
+ ExchangeHandlerImpl::declare
+ </entry>
+ <entry>
+ ExchangeDeclareHandler
+ </entry>
+ </row>
+ <row>
+ <entry>
+ Exchange
+ </entry>
+ <entry>
+ Delete
+ </entry>
+ <entry>
+ name
+ </entry>
+ <entry>
+ ExchangeHandlerImpl::delete
+ </entry>
+ <entry>
+ ExchangeDeleteHandler
+ </entry>
+ </row>
+ <row>
+ <entry>
+ Exchange
+ </entry>
+ <entry>
+ Access
+ </entry>
+ <entry>
+ name
+ </entry>
+ <entry>
+ ExchangeHandlerImpl::query
+ </entry>
+ <entry>
+
+ </entry>
+ </row>
+ <row>
+ <entry>
+ Exchange
+ </entry>
+ <entry>
+ Bind
+ </entry>
+ <entry>
+ name routingkey queuename owner
+ </entry>
+ <entry>
+ ExchangeHandlerImpl::bind
+ </entry>
+ <entry>
+ QueueBindHandler
+ </entry>
+ </row>
+ <row>
+ <entry>
+ Exchange
+ </entry>
+ <entry>
+ Unbind
+ </entry>
+ <entry>
+ name routingkey
+ </entry>
+ <entry>
+ ExchangeHandlerImpl::unbind
+ </entry>
+ <entry>
+ ExchangeUnbindHandler
+ </entry>
+ </row>
+ <row>
+ <entry>
+ Exchange
+ </entry>
+ <entry>
+ Access
+ </entry>
+ <entry>
+ name queuename routingkey
+ </entry>
+ <entry>
+ ExchangeHandlerImpl::bound
+ </entry>
+ <entry>
+
+ </entry>
+ </row>
+ <row>
+ <entry>
+ Exchange
+ </entry>
+ <entry>
+ Publish
+ </entry>
+ <entry>
+ name routingKey
+ </entry>
+ <entry>
+ SemanticState::route
+ </entry>
+ <entry>
+ BasicPublishMethodHandler
+ </entry>
+ </row>
+ <row>
+ <entry>
+ Queue
+ </entry>
+ <entry>
+ Access
+ </entry>
+ <entry>
+ name
+ </entry>
+ <entry>
+ QueueHandlerImpl::query
+ </entry>
+ <entry>
+
+ </entry>
+ </row>
+ <row>
+ <entry>
+ Queue
+ </entry>
+ <entry>
+ Create
+ </entry>
+ <entry>
+ name alternate passive durable exclusive autodelete
+ </entry>
+ <entry>
+ QueueHandlerImpl::declare
+ </entry>
+ <entry>
+ QueueDeclareHandler
+ </entry>
+ </row>
+ <row>
+ <entry>
+ Queue
+ </entry>
+ <entry>
+ Purge
+ </entry>
+ <entry>
+ name
+ </entry>
+ <entry>
+ QueueHandlerImpl::purge
+ </entry>
+ <entry>
+ QueuePurgeHandler
+ </entry>
+ </row>
+ <row>
+ <entry>
+ Queue
+ </entry>
+ <entry>
+ Purge
+ </entry>
+ <entry>
+ name
+ </entry>
+ <entry>
+ Management::Queue::purge
+ </entry>
+ <entry>
+
+ </entry>
+ </row>
+ <row>
+ <entry>
+ Queue
+ </entry>
+ <entry>
+ Delete
+ </entry>
+ <entry>
+ name
+ </entry>
+ <entry>
+ QueueHandlerImpl::delete
+ </entry>
+ <entry>
+ QueueDeleteHandler
+ </entry>
+ </row>
+ <row>
+ <entry>
+ Queue
+ </entry>
+ <entry>
+ Consume
+ </entry>
+ <entry>
+ name (possibly add in future?)
+ </entry>
+ <entry>
+ MessageHandlerImpl::subscribe
+ </entry>
+ <entry>
+ BasicConsumeMethodHandler
+ BasicGetMethodHandler
+ </entry>
+ </row>
+ <row>
+ <entry>
+ &lt;Object&gt;
+ </entry>
+ <entry>
+ Update
+ </entry>
+ <entry>
+  
+ </entry>
+ <entry>
+ ManagementProperty::set
+ </entry>
+ <entry>
+
+ </entry>
+ </row>
+ <row>
+ <entry>
+ &lt;Object&gt;
+ </entry>
+ <entry>
+ Access
+ </entry>
+ <entry>
+  
+ </entry>
+ <entry>
+ ManagementProperty::read
+ </entry>
+ <entry>
+
+ </entry>
+ </row>
+ <row>
+ <entry>
+ Link
+ </entry>
+ <entry>
+ Create
+ </entry>
+ <entry>
+  
+ </entry>
+ <entry>
+ Management::connect
+ </entry>
+ <entry>
+
+ </entry>
+ </row>
+ <row>
+ <entry>
+ Route
+ </entry>
+ <entry>
+ Create
+ </entry>
+ <entry>
+  
+ </entry>
+ <entry>
+ Management:: -createFederationRoute-
+ </entry>
+ <entry>
+
+ </entry>
+ </row>
+ <row>
+ <entry>
+ Route
+ </entry>
+ <entry>
+ Delete
+ </entry>
+ <entry>
+  
+ </entry>
+ <entry>
+ Management:: -deleteFederationRoute-
+ </entry>
+ <entry>
+
+ </entry>
+ </row>
+ <row>
+ <entry>
+ Virtualhost
+ </entry>
+ <entry>
+ Access
+ </entry>
+ <entry>
+ name
+ </entry>
+ <entry>
+ TBD
+ </entry>
+ <entry>
+ ConnectionOpenMethodHandler
+ </entry>
+ </row>
+ </tbody>
+ </tgroup></table><para>
+ Management actions that are not explicitly given a name property
+ it will default the name property to management method name, if
+ the action is 'W' Action will be 'Update', if 'R' Action will be
+ 'Access'.
+ </para><para>
+ for example, if the mgnt method 'joinCluster' was not mapped in
+ schema it will be mapped in ACL file as follows
+ </para>
+
+ <table>
+ <title>Mapping Management Actions to ACL</title>
+ <tgroup cols="3">
+ <thead>
+ <row>
+ <entry>
+ Object
+ </entry>
+ <entry>
+ Action
+ </entry>
+ <entry>
+ Property
+ </entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>
+ Broker
+ </entry>
+ <entry>
+ Update
+ </entry>
+ <entry>
+ name=joinCluster
+ </entry>
+ </row>
+ </tbody>
+ </tgroup></table>
+
+ <!--h3--></section>
+ <!--h2--></section>
+
+
+ <section role="h2" id="ACL-v2ACLUserGuide"><title>
+ v2 ACL User Guide
+ </title>
+ <section role="h3" id="ACL-WritingGood-2FFastACL"><title>
+ Writing Good/Fast ACL
+ </title>
+ <para>
+ The file gets read top down and rule get passed based on the
+ first match. In the following example the first rule is a dead
+ rule. I.e. the second rule is wider than the first rule. DON'T do
+ this, it will force extra analysis, worst case if the parser does
+ not kill the dead rule you might get a false deny.
+ </para>
+ <programlisting>
+allow peter@QPID create queue name=tmp &lt;-- dead rule!!
+allow peter@QPID create queue
+deny all all
+</programlisting>
+ <para>
+ By default files end with
+ </para>
+ <programlisting>
+deny all all
+</programlisting>
+ <para>
+ the mode of the ACL engine can be swapped to be allow based by
+ putting the following at the end of the file
+ </para>
+ <programlisting>
+allow all all
+</programlisting>
+ <para>
+ Note that 'allow' based file will be a LOT faster for message
+ transfer. This is because the AMQP specification does not allow
+ for creating subscribes on publish, so the ACL is executed on
+ every message transfer. Also, ACL's rules using less properties
+ on publish will in general be faster.
+ </para>
+ <!--h3--></section>
+
+ <section role="h3" id="ACL-GettingACLtoLog"><title>
+ Getting ACL to Log
+ </title>
+ <para>
+ In order to get log messages from ACL actions use allow-log and
+ deny-log for example
+ </para>
+ <programlisting>
+allow-log john@QPID all all
+deny-log guest@QPID all all
+</programlisting>
+ <!--h3--></section>
+
+ <section role="h3" id="ACL-UserId-2FdomainsrunningwithCbroker"><title>
+ User Id /
+ domains running with C++ broker
+ </title>
+ <para>
+ The user-id used for ACL is taken from the connection user-id.
+ Thus in order to use ACL the broker authentication has to be
+ setup. i.e. (if --auth no is used in combination with ACL the
+ broker will deny everything)
+ </para><para>
+ The user id in the ACL file is of the form
+ &lt;user-id&gt;@&lt;domain&gt; The Domain is configured via the
+ SASL configuration for the broker, and the domain/realm for qpidd
+ is set using --realm and default to 'QPID'.
+ </para><para>
+ To load the ACL module use, load the acl module cmd line or via
+ the config file
+ </para>
+ <programlisting>
+./src/qpidd --load-module src/.libs/acl.so
+</programlisting>
+ <para>
+ The ACL plugin provides the following option '--acl-file'. If do
+ ACL file is supplied the broker will not enforce ACL. If an ACL
+ file name is supplied, and the file does not exist or is invalid
+ the broker will not start.
+ </para>
+ <programlisting>
+ACL Options:
+ --acl-file FILE The policy file to load from, loaded from data dir
+</programlisting>
+
+ <!--h3--></section>
+ <!--h2--></section>
+
+</section>
diff --git a/qpid/doc/book/src/AMQP-.NET-Messaging-Client.xml b/qpid/doc/book/src/AMQP-.NET-Messaging-Client.xml
new file mode 100644
index 0000000000..1d4001942b
--- /dev/null
+++ b/qpid/doc/book/src/AMQP-.NET-Messaging-Client.xml
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+
+ 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.
+
+-->
+
+<chapter>
+ <title>
+ AMQP .NET Messaging Client
+ </title>
+ <para>
+ Currently the .NET code base provides two client libraries that
+ are compatible respectively with AMQP 0.8 and 0.10. The 0.8 client
+ is located in <filename>qpid\dotnet</filename> and the 0.10 client
+ in: <filename>qpid\dotnet\client-010</filename>.
+ </para>
+ <para>
+ You will need an AMQP broker to fully use those client libraries.
+ Use M4 or later C++ broker for AMQP 0.10 or Java broker for AMQP
+ 0.8/0.9.
+ </para>
+ <section role="h3" id="AMQP.NETMessagingClient-UserGuides">
+ <title>
+ User Guides
+ </title>
+
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="NET-User-Guide.xml"/>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="Excel-AddIn.xml"/>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="WCF.xml"/>
+ </section>
+
+ <section role="h3" id="AMQP.NETMessagingClient-Examples">
+ <title>
+ Examples
+ </title>
+ <itemizedlist>
+ <listitem>
+ <para>
+ <ulink url="http://svn.apache.org/viewvc/qpid/trunk/qpid/dotnet/client-010/examples/"/>
+ </para>
+ </listitem>
+ </itemizedlist>
+ <!--h3-->
+ </section>
+
+<!--
+
+ <section role="h3" id="AMQP.NETMessagingClient-DeveloperGuidelines">
+ <title>
+ Developer Guidelines
+ </title>
+ <itemizedlist>
+ <listitem>
+ <para>
+ <xref linkend="qpid_Developer-Pages"/>
+ </para>
+ </listitem>
+ <listitem>
+ <para>Coding Standards </para>
+ </listitem>
+ <listitem>
+ <para>How Tos
+ <itemizedlist>
+ <listitem>
+ <para>
+ <xref linkend="qpid_Build-.NET-Client"/>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <xref linkend="qpid_Releasing"/>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <xref linkend="qpid_Run-tests"/>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <xref linkend="qpid_Setup-.Net-Client-on-Windows"/>
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ </listitem>
+ </itemizedlist>
+ </section>
+ -->
+
+
+</chapter>
diff --git a/qpid/doc/book/src/AMQP-C++-Messaging-Client.xml b/qpid/doc/book/src/AMQP-C++-Messaging-Client.xml
new file mode 100644
index 0000000000..73a2cd6c0b
--- /dev/null
+++ b/qpid/doc/book/src/AMQP-C++-Messaging-Client.xml
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+
+ 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.
+
+-->
+
+<chapter >
+ <title>
+ AMQP C++ Messaging Client
+ </title>
+ <section role="h3" id="AMQPCPPMessagingClient-UserGuides">
+ <title>
+ User Guides
+ </title>
+ <itemizedlist>
+ <listitem>
+ <para>
+ <ulink url="http://qpid.apache.org/docs/api/cpp/html/index.html">C++ Client API (AMQP 0-10)</ulink>
+ </para>
+ </listitem>
+ </itemizedlist>
+ <!--h3-->
+ </section>
+
+ <section role="h3" id="AMQPCPPMessagingClient-Examples">
+ <title>
+ Examples
+ </title>
+ <itemizedlist>
+ <listitem>
+ <para>
+ <ulink url="https://svn.apache.org/repos/asf/qpid/trunk/qpid/cpp/examples/">AMQP C++ Client Examples </ulink>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <ulink url="https://svn.apache.org/repos/asf/qpid/trunk/qpid/cpp/examples/README.txt">Running the AMQP C++ Client Examples </ulink>
+ </para>
+ </listitem>
+ </itemizedlist>
+ <!--h3-->
+ </section>
+
+
+</chapter>
diff --git a/qpid/doc/book/src/AMQP-Compatibility.xml b/qpid/doc/book/src/AMQP-Compatibility.xml
new file mode 100644
index 0000000000..e5aa98cf96
--- /dev/null
+++ b/qpid/doc/book/src/AMQP-Compatibility.xml
@@ -0,0 +1,713 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+
+ 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.
+
+-->
+
+<section id="AMQP-Compatibility">
+ <title>
+ AMQP compatibility
+ </title>
+ <para>
+ Qpid provides the most complete and compatible implementation
+ of AMQP. And is the most aggressive in implementing the latest
+ version of the specification.
+ </para>
+ <para>
+ There are two brokers:
+ </para>
+
+ <itemizedlist>
+ <listitem><para>C++ with support for AMQP 0-10</para></listitem>
+ <listitem><para>Java with support for AMQP 0-8 and 0-9 (0-10 planned)</para></listitem>
+ </itemizedlist>
+ <para>
+ There are client libraries for C++, Java (JMS), .Net (written in
+ C#), python and ruby.
+ </para>
+ <itemizedlist>
+ <listitem><para>All clients support 0-10 and interoperate with the C++
+ broker.
+ </para></listitem>
+ </itemizedlist>
+ <itemizedlist>
+ <listitem><para>The JMS client supports 0-8, 0-9 and 0-10 and interoperates
+ with both brokers.
+ </para></listitem>
+ </itemizedlist>
+ <itemizedlist>
+ <listitem><para>The python and ruby clients will also support all versions,
+ but the API is dynamically driven by the specification used and
+ so differs between versions. To work with the Java broker you
+ must use 0-8 or 0-9, to work with the C++ broker you must use
+ 0-10.
+ </para></listitem>
+ </itemizedlist>
+ <itemizedlist>
+ <listitem><para>There are two separate C# clients, one for 0-8 that
+ interoperates with the Java broker, one for 0-10 that
+ inteoperates with the C++ broker.
+ </para></listitem>
+ </itemizedlist>
+ <para>
+ QMF Management is supported in Ruby, Python, C++, and via QMan
+ for Java JMX &amp; WS-DM.
+ </para>
+ <section role="h3" id="AMQPcompatibility-AMQPCompatibilityofQpidreleases-3A">
+ <title>
+ AMQP
+ Compatibility of Qpid releases:
+ </title>
+ <para>
+ Qpid implements the AMQP Specification, and as the specification
+ has progressed Qpid is keeping up with the updates. This means
+ that different Qpid versions support different versions of AMQP.
+ Here is a simple guide on what use.
+ </para>
+ <para>
+ Here is a matrix that describes the different versions supported
+ by each release. The status symbols are interpreted as follows:
+ </para>
+
+ <variablelist>
+ <varlistentry>
+ <term>Y</term>
+ <listitem><para>supported</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>N</term>
+ <listitem><para>unsupported</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>IP</term>
+ <listitem><para>in progress</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>P</term>
+ <listitem><para>planned</para></listitem>
+ </varlistentry>
+ </variablelist>
+
+ <table>
+ <title>AMQP Version Support by Qpid Release</title>
+ <tgroup cols="6">
+ <tbody>
+ <row>
+ <entry>
+ Component
+ </entry>
+ <entry>
+ Spec
+ </entry>
+ <entry>
+  
+ </entry>
+ <entry>
+  
+ </entry>
+ <entry>
+  
+ </entry>
+ <entry>
+  
+ </entry>
+ </row>
+ <row>
+ <entry>
+  
+ </entry>
+ <entry>
+  
+ </entry>
+ <entry>
+ M2.1
+ </entry>
+ <entry>
+ M3
+ </entry>
+ <entry>
+ M4
+ </entry>
+ <entry>
+ 0.5
+ </entry>
+ </row>
+ <row>
+ <entry>
+ java client
+ </entry>
+ <entry>
+ 0-10
+ </entry>
+ <entry>
+  
+ </entry>
+ <entry>
+ Y
+ </entry>
+ <entry>
+ Y
+ </entry>
+ <entry>
+ Y
+ </entry>
+ </row>
+ <row>
+ <entry>
+  
+ </entry>
+ <entry>
+ 0-9
+ </entry>
+ <entry>
+ Y
+ </entry>
+ <entry>
+ Y
+ </entry>
+ <entry>
+ Y
+ </entry>
+ <entry>
+ Y
+ </entry>
+ </row>
+ <row>
+ <entry>
+  
+ </entry>
+ <entry>
+ 0-8
+ </entry>
+ <entry>
+ Y
+ </entry>
+ <entry>
+ Y
+ </entry>
+ <entry>
+ Y
+ </entry>
+ <entry>
+ Y
+ </entry>
+ </row>
+ <row>
+ <entry>
+ java broker
+ </entry>
+ <entry>
+ 0-10
+ </entry>
+ <entry>
+  
+ </entry>
+ <entry>
+  
+ </entry>
+ <entry>
+  
+ </entry>
+ <entry>
+ P
+ </entry>
+ </row>
+ <row>
+ <entry>
+  
+ </entry>
+ <entry>
+ 0-9
+ </entry>
+ <entry>
+ Y
+ </entry>
+ <entry>
+ Y
+ </entry>
+ <entry>
+ Y
+ </entry>
+ <entry>
+ Y
+ </entry>
+ </row>
+ <row>
+ <entry>
+  
+ </entry>
+ <entry>
+ 0-8
+ </entry>
+ <entry>
+ Y
+ </entry>
+ <entry>
+ Y
+ </entry>
+ <entry>
+ Y
+ </entry>
+ <entry>
+ Y
+ </entry>
+ </row>
+ <row>
+ <entry>
+ c++ client/broker
+ </entry>
+ <entry>
+ 0-10
+ </entry>
+ <entry>
+  
+ </entry>
+ <entry>
+ Y
+ </entry>
+ <entry>
+ Y
+ </entry>
+ <entry>
+ Y
+ </entry>
+ </row>
+ <row>
+ <entry>
+  
+ </entry>
+ <entry>
+ 0-9
+ </entry>
+ <entry>
+ Y
+ </entry>
+ <entry>
+  
+ </entry>
+ <entry>
+  
+ </entry>
+ <entry>
+  
+ </entry>
+ </row>
+ <row>
+ <entry>
+ python client
+ </entry>
+ <entry>
+ 0-10
+ </entry>
+ <entry>
+  
+ </entry>
+ <entry>
+ Y
+ </entry>
+ <entry>
+ Y
+ </entry>
+ <entry>
+ Y
+ </entry>
+ </row>
+ <row>
+ <entry>
+  
+ </entry>
+ <entry>
+ 0-9
+ </entry>
+ <entry>
+ Y
+ </entry>
+ <entry>
+ Y
+ </entry>
+ <entry>
+ Y
+ </entry>
+ <entry>
+ Y
+ </entry>
+ </row>
+ <row>
+ <entry>
+  
+ </entry>
+ <entry>
+ 0-8
+ </entry>
+ <entry>
+ Y
+ </entry>
+ <entry>
+ Y
+ </entry>
+ <entry>
+ Y
+ </entry>
+ <entry>
+ Y
+ </entry>
+ </row>
+ <row>
+ <entry>
+ ruby client
+ </entry>
+ <entry>
+ 0-10
+ </entry>
+ <entry>
+  
+ </entry>
+ <entry>
+  
+ </entry>
+ <entry>
+ Y
+ </entry>
+ <entry>
+ Y
+ </entry>
+ </row>
+ <row>
+ <entry>
+  
+ </entry>
+ <entry>
+ 0-8
+ </entry>
+ <entry>
+ Y
+ </entry>
+ <entry>
+ Y
+ </entry>
+ <entry>
+ Y
+ </entry>
+ <entry>
+ Y
+ </entry>
+ </row>
+ <row>
+ <entry>
+ C# client
+ </entry>
+ <entry>
+ 0-10
+ </entry>
+ <entry>
+  
+ </entry>
+ <entry>
+  
+ </entry>
+ <entry>
+ Y
+ </entry>
+ <entry>
+ Y
+ </entry>
+ </row>
+ <row>
+ <entry>
+  
+ </entry>
+ <entry>
+ 0-8
+ </entry>
+ <entry>
+ Y
+ </entry>
+ <entry>
+ Y
+ </entry>
+ <entry>
+ Y
+ </entry>
+ <entry>
+ Y
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ <!--h3-->
+ </section>
+
+ <section role="h3" id="AMQPcompatibility-InteroptablebyAMQPspecificationversion">
+ <title>
+ Interop
+ table by AMQP specification version
+ </title>
+ <para>
+ Above table represented in another format.
+ </para>
+ <table>
+ <title>AMQP Version Support - alternate format</title>
+ <tgroup cols="5">
+ <tbody>
+ <row>
+ <entry>
+  
+ </entry>
+ <entry>
+ release
+ </entry>
+ <entry>
+ 0-8
+ </entry>
+ <entry>
+ 0-9
+ </entry>
+ <entry>
+ 0-10
+ </entry>
+ </row>
+ <row>
+ <entry>
+ java client
+ </entry>
+ <entry>
+ M3 M4 0.5
+ </entry>
+ <entry>
+ Y
+ </entry>
+ <entry>
+ Y
+ </entry>
+ <entry>
+ Y
+ </entry>
+ </row>
+ <row>
+ <entry>
+ java client
+ </entry>
+ <entry>
+ M2.1
+ </entry>
+ <entry>
+ Y
+ </entry>
+ <entry>
+ Y
+ </entry>
+ <entry>
+ N
+ </entry>
+ </row>
+ <row>
+ <entry>
+ java broker
+ </entry>
+ <entry>
+ M3 M4 0.5
+ </entry>
+ <entry>
+ Y
+ </entry>
+ <entry>
+ Y
+ </entry>
+ <entry>
+ N
+ </entry>
+ </row>
+ <row>
+ <entry>
+ java broker
+ </entry>
+ <entry>
+ trunk
+ </entry>
+ <entry>
+ Y
+ </entry>
+ <entry>
+ Y
+ </entry>
+ <entry>
+ P
+ </entry>
+ </row>
+ <row>
+ <entry>
+ java broker
+ </entry>
+ <entry>
+ M2.1
+ </entry>
+ <entry>
+ Y
+ </entry>
+ <entry>
+ Y
+ </entry>
+ <entry>
+ N
+ </entry>
+ </row>
+ <row>
+ <entry>
+ c++ client/broker
+ </entry>
+ <entry>
+ M3 M4 0.5
+ </entry>
+ <entry>
+ N
+ </entry>
+ <entry>
+ N
+ </entry>
+ <entry>
+ Y
+ </entry>
+ </row>
+ <row>
+ <entry>
+ c++ client/broker
+ </entry>
+ <entry>
+ M2.1
+ </entry>
+ <entry>
+ N
+ </entry>
+ <entry>
+ Y
+ </entry>
+ <entry>
+ N
+ </entry>
+ </row>
+ <row>
+ <entry>
+ python client
+ </entry>
+ <entry>
+ M3 M4 0.5
+ </entry>
+ <entry>
+ Y
+ </entry>
+ <entry>
+ Y
+ </entry>
+ <entry>
+ Y
+ </entry>
+ </row>
+ <row>
+ <entry>
+ python client
+ </entry>
+ <entry>
+ M2.1
+ </entry>
+ <entry>
+ Y
+ </entry>
+ <entry>
+ Y
+ </entry>
+ <entry>
+ N
+ </entry>
+ </row>
+ <row>
+ <entry>
+ ruby client
+ </entry>
+ <entry>
+ M3 M4 0.5
+ </entry>
+ <entry>
+ Y
+ </entry>
+ <entry>
+ Y
+ </entry>
+ <entry>
+ N
+ </entry>
+ </row>
+ <row>
+ <entry>
+ ruby client
+ </entry>
+ <entry>
+ trunk
+ </entry>
+ <entry>
+ Y
+ </entry>
+ <entry>
+ Y
+ </entry>
+ <entry>
+ P
+ </entry>
+ </row>
+ <row>
+ <entry>
+ C# client
+ </entry>
+ <entry>
+ M3 M4 0.5
+ </entry>
+ <entry>
+ Y
+ </entry>
+ <entry>
+ N
+ </entry>
+ <entry>
+ N
+ </entry>
+ </row>
+ <row>
+ <entry>
+ C# client
+ </entry>
+ <entry>
+ trunk
+ </entry>
+ <entry>
+ Y
+ </entry>
+ <entry>
+ N
+ </entry>
+ <entry>
+ Y
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ <!--h3-->
+ </section>
+
+</section>
diff --git a/qpid/doc/book/src/AMQP-Java-JMS-Messaging-Client.xml b/qpid/doc/book/src/AMQP-Java-JMS-Messaging-Client.xml
new file mode 100644
index 0000000000..8c14d67e14
--- /dev/null
+++ b/qpid/doc/book/src/AMQP-Java-JMS-Messaging-Client.xml
@@ -0,0 +1,94 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+
+ 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.
+
+-->
+
+<chapter>
+
+ <title>
+ AMQP Java JMS Messaging Client
+ </title>
+
+ <para>The Java Client supported by Qpid implements the <ulink
+ url="http://java.sun.com/products/jms/docs.html">Java JMS 1.1
+ Specification</ulink>. </para>
+
+
+ <section role="h3"
+ id="AMQPJavaJMSMessagingClient-GeneralUserGuides">
+ <title>General User Guides</title>
+
+
+<!--
+Does not seem to exist!
+
+ <listitem><para>AMQP Java JMS Client Feature Guide
+ </para></listitem>
+
+http://cwiki.apache.org/confluence/pages/createpage.action?spaceKey=qpid&title=JMS-Client-Feature-Guide&linkCreation=true&fromPageId=4589057
+-->
+
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="System-Properties.xml"/>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="Connection-URL-Format.xml"/>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="Binding-URL-Format.xml"/>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="Java-JMS-Selector-Syntax.xml"/>
+
+<!--
+ <listitem><para>How to Use JNDI to configure the AMQP Java JMS Client
+ </para></listitem>
+ <listitem><para>Using the AMQP Java JMS Client with RT Java
+ </para></listitem>
+ <listitem><para>AMQP Java JMS Client Tuning Guide
+ </para></listitem>
+-->
+
+<!--h3--></section>
+
+ <section role="h3" id="AMQPJavaJMSMessagingClient-AMQPJavaJMSExamples">
+
+ <title>AMQP Java JMS Examples </title>
+
+ <itemizedlist>
+ <listitem><para>
+ <ulink url="https://svn.apache.org/repos/asf/qpid/trunk/qpid/java/client/example/">Examples Directory</ulink>
+ </para></listitem>
+
+ <listitem><para>
+ <ulink url="https://svn.apache.org/repos/asf/qpid/trunk/qpid/java/client/example/src/main/java/runSample.sh">Script for running examples</ulink>
+ </para></listitem>
+ <listitem><para>
+ <ulink url="https://svn.apache.org/repos/asf/qpid/trunk/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/direct/">Direct Example</ulink>
+ </para></listitem>
+ <listitem><para>
+ <ulink url="https://svn.apache.org/repos/asf/qpid/trunk/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/fanout/">Fanout Example</ulink>
+ </para></listitem>
+ <listitem><para>
+ <ulink url="https://svn.apache.org/repos/asf/qpid/trunk/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/pubsub">Pub-Sub Example</ulink>
+ </para></listitem>
+ <listitem><para>
+ <ulink url="https://svn.apache.org/repos/asf/qpid/trunk/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/requestResponse/">Request/Response Example</ulink>
+ </para></listitem>
+ <listitem><para>
+ <ulink url="https://svn.apache.org/repos/asf/qpid/trunk/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/transacted/">Transacted Example</ulink></para></listitem>
+ </itemizedlist>
+
+<!--h3--></section>
+
+</chapter>
diff --git a/qpid/doc/book/src/AMQP-Messaging-Broker-CPP-Book.xml b/qpid/doc/book/src/AMQP-Messaging-Broker-CPP-Book.xml
new file mode 100644
index 0000000000..6c27d7c668
--- /dev/null
+++ b/qpid/doc/book/src/AMQP-Messaging-Broker-CPP-Book.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0"?>
+<!--
+
+ 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.
+
+-->
+
+<book>
+ <title>AMQP Messaging Broker (Implemented in C++)</title>
+ <preface>
+ <title>Introduction</title>
+
+ <para>Qpid provides two AMQP messaging brokers:</para>
+
+ <itemizedlist>
+ <listitem><para>Implemented in C++ - high performance, low latency, and RDMA support.</para></listitem>
+ <listitem><para>Implemented in Java - Fully JMS compliant, runs on any Java platform.</para></listitem>
+ </itemizedlist>
+
+ <para>Both AMQP messaging brokers support clients in multiple
+ languages, as long as the messaging client and the messaging
+ broker use the same version of AMQP. See <link
+ linkend="AMQP-Compatibility">AMQP Compatibility</link> to see
+ which messaging clients work with each broker.</para>
+
+ <para>This manual contains information specific to the broker that is implemented in C++.</para>
+ </preface>
+
+<chapter>
+ <title>
+ Running the AMQP Messaging Broker
+ </title>
+
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="Running-CPP-Broker.xml"/>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="Cheat-Sheet-for-configuring-Queue-Options.xml"/>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="Cheat-Sheet-for-configuring-Exchange-Options.xml"/>
+
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="Using-Broker-Federation.xml"/>
+
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="Security.xml"/>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="LVQ.xml"/>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="queue-state-replication.xml"/>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="Starting-a-cluster.xml"/>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="producer-flow-control.xml"/>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="AMQP-Compatibility.xml"/>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="Qpid-Interoperability-Documentation.xml"/>
+
+</chapter>
+
+
+<chapter id="chapter-Managing-CPP-Broker">
+ <title>
+ Managing the AMQP Messaging Broker
+ </title>
+
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="Managing-CPP-Broker.xml"/>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="Qpid-Management-Framework.xml"/>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="QMF-Python-Console-Tutorial.xml"/>
+</chapter>
+</book>
diff --git a/qpid/doc/book/src/AMQP-Messaging-Broker-CPP.xml b/qpid/doc/book/src/AMQP-Messaging-Broker-CPP.xml
new file mode 100644
index 0000000000..15f5660455
--- /dev/null
+++ b/qpid/doc/book/src/AMQP-Messaging-Broker-CPP.xml
@@ -0,0 +1,69 @@
+<?xml version="1.0"?>
+<!--
+
+ 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.
+
+-->
+
+<part>
+ <title>AMQP Messaging Broker (Implemented in C++)</title>
+ <partintro>
+ <para>Qpid provides two AMQP messaging brokers:</para>
+
+ <itemizedlist>
+ <listitem><para>Implemented in C++ - high performance, low latency, and RDMA support.</para></listitem>
+ <listitem><para>Implemented in Java - Fully JMS compliant, runs on any Java platform.</para></listitem>
+ </itemizedlist>
+
+ <para>Both AMQP messaging brokers support clients in multiple languages, as long as the messaging client and the messaging broker use the same version of AMQP. See <link linkend="AMQP-Compatibility"/> to see which messaging clients work with each broker.</para>
+
+ <para>This section contains information specific to the broker that is implemented in C++.</para>
+ </partintro>
+
+<chapter>
+ <title>
+ Running the AMQP Messaging Broker
+ </title>
+
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="Running-CPP-Broker.xml"/>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="Cheat-Sheet-for-configuring-Queue-Options.xml"/>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="Cheat-Sheet-for-configuring-Exchange-Options.xml"/>
+
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="Using-Broker-Federation.xml"/>
+
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="SSL.xml"/>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="LVQ.xml"/>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="queue-state-replication.xml"/>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="Starting-a-cluster.xml"/>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="ACL.xml"/>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="producer-flow-control.xml"/>
+</chapter>
+
+
+<chapter id="chapter-Managing-CPP-Broker">
+ <title>
+ Managing the AMQP Messaging Broker
+ </title>
+
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="Managing-CPP-Broker.xml"/>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="QMan-Qpid-Management-bridge.xml"/>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="Qpid-Management-Framework.xml"/>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="Management-Design-notes.xml"/>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="QMF-Python-Console-Tutorial.xml"/>
+</chapter>
+</part>
diff --git a/qpid/doc/book/src/AMQP-Messaging-Broker-Java-Book.xml b/qpid/doc/book/src/AMQP-Messaging-Broker-Java-Book.xml
new file mode 100644
index 0000000000..8d2e2218ff
--- /dev/null
+++ b/qpid/doc/book/src/AMQP-Messaging-Broker-Java-Book.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0"?>
+<!--
+
+ 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.
+
+-->
+
+<book>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="AMQP-Messaging-Broker-Java.xml"/>
+</book>
diff --git a/qpid/doc/book/src/AMQP-Messaging-Broker-Java.xml b/qpid/doc/book/src/AMQP-Messaging-Broker-Java.xml
new file mode 100644
index 0000000000..d2a3427674
--- /dev/null
+++ b/qpid/doc/book/src/AMQP-Messaging-Broker-Java.xml
@@ -0,0 +1,72 @@
+<?xml version="1.0"?>
+<!--
+
+ 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.
+
+-->
+
+<part>
+ <title>AMQP Messaging Broker (Implemented in Java)</title>
+ <partintro>
+ <para>Qpid provides two AMQP messaging brokers:</para>
+
+ <itemizedlist>
+ <listitem><para>Implemented in C++ - high performance, low latency, and RDMA support.</para></listitem>
+ <listitem><para>Implemented in Java - Fully JMS compliant, runs on any Java platform.</para></listitem>
+ </itemizedlist>
+
+ <para>Both AMQP messaging brokers support clients in multiple languages, as long as the messaging client and the messaging broker use the same version of AMQP. See <link linkend="AMQP-Compatibility"/> to see which messaging clients work with each broker.</para>
+
+ <para>This section contains information specific to the broker that is implemented in Java.</para>
+ </partintro>
+
+<chapter>
+ <title>General User Guides</title>
+
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="Java-Broker-Feature-Guide.xml"/>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="Qpid-Java-FAQ.xml"/>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="Java-Environment-Variables.xml"/>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="Qpid-Troubleshooting-Guide.xml"/>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="Broker-Configuration-Guide.xml"/>
+</chapter>
+
+<chapter id="Qpid-Java-Broker-HowTos">
+<title>How Tos</title>
+
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="Add-New-Users.xml"/>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="Configure-ACLs.xml"/>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="Configure-Java-Qpid-to-use-a-SSL-connection.xml"/>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="Configure-Log4j-CompositeRolling-Appender.xml"/>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="Configure-the-Broker-via-config.xml.xml"/>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="Configure-the-Virtual-Hosts-via-virtualhosts.xml.xml"/>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="Debug-using-log4j.xml"/>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="How-to-Tune-M3-Java-Broker-Performance.xml"/>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="Qpid-Java-Build-How-To.xml"/>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="Use-Priority-Queues.xml"/>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="How-to-Use-SlowConsumerDisconnect.xml"/>
+</chapter>
+
+
+<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="Qpid-JMX-Management-Console.xml"/>
+
+<chapter id="QpidJavaBroker-ManagementTools">
+<title>Management Tools</title>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="MessageStore-Tool.xml"/>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="Qpid-Java-Broker-Management-CLI.xml"/>
+</chapter>
+</part>
diff --git a/qpid/doc/book/src/AMQP-Python-Messaging-Client.xml b/qpid/doc/book/src/AMQP-Python-Messaging-Client.xml
new file mode 100644
index 0000000000..15baf214ec
--- /dev/null
+++ b/qpid/doc/book/src/AMQP-Python-Messaging-Client.xml
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+
+ 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.
+
+-->
+
+<chapter>
+ <title>
+ AMQP Python Messaging Client
+ </title>
+ <section role="h3" id="AMQPPythonMessagingClient-UserGuides">
+ <title>
+ User Guides
+ </title>
+ <itemizedlist>
+ <listitem>
+ <para>
+ <ulink url="http://qpid.apache.org/docs/api/python/html/index.html">Python Client API Guide</ulink>
+ </para>
+ </listitem>
+ </itemizedlist>
+ <!--h3-->
+ </section>
+
+ <section role="h3" id="AMQPPythonMessagingClient-Examples">
+ <title>
+ Examples
+ </title>
+ <itemizedlist>
+ <listitem>
+ <para>
+ <ulink url="https://svn.apache.org/repos/asf/qpid/trunk/qpid/python/examples/">AMQP Python Client Examples </ulink>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <ulink url="https://svn.apache.org/repos/asf/qpid/trunk/qpid/python/examples/README">Running the AMQP Python Client Examples </ulink>
+ </para>
+ </listitem>
+ </itemizedlist>
+ <!--h3-->
+ </section>
+
+ <xi:include href="PythonBrokerTest.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+</chapter>
diff --git a/qpid/doc/book/src/AMQP-Ruby-Messaging-Client.xml b/qpid/doc/book/src/AMQP-Ruby-Messaging-Client.xml
new file mode 100644
index 0000000000..45318c0beb
--- /dev/null
+++ b/qpid/doc/book/src/AMQP-Ruby-Messaging-Client.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+
+ 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.
+
+-->
+
+<chapter>
+ <title>
+ AMQP Ruby Messaging Client
+ </title>
+ <para>
+ The Ruby Messaging Client currently has little documentation and
+ few examples.
+ </para>
+ <section role="h3" id="AMQPRubyMessagingClient-Examples">
+ <title>
+ Examples
+ </title>
+ <para>
+ <ulink url="https://svn.apache.org/repos/asf/qpid/trunk/qpid/ruby/examples">AMQP Ruby Messaging Client Examples</ulink>
+ </para>
+ <!--h3-->
+ </section>
+</chapter>
diff --git a/qpid/doc/book/src/AMQP.xml b/qpid/doc/book/src/AMQP.xml
new file mode 100644
index 0000000000..1a609649bb
--- /dev/null
+++ b/qpid/doc/book/src/AMQP.xml
@@ -0,0 +1,98 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+
+ 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.
+
+-->
+
+<chapter>
+
+<title>AMQP (Advanced Message Queueing Protocol</title>
+
+
+<para>AMQP <ulink url="http://www.amqp.org/" >Advanced
+Message Queuing Protocol</ulink> is an open standard designed to
+support reliable, high-performance messaging over the Internet.
+AMQP can be used for any distributed or business application, and
+supports common messaging paradigms like point-to-point, fanout,
+publish-subscribe, and request-response.</para>
+<para>Apache Qpid implements AMQP, including transaction management,
+queuing, clustering, federation, security, management and
+multi-platform support.</para>
+<para>Apache Qpid implements the latest AMQP specification, providing
+transaction management, queuing, distribution, security,
+management, clustering, federation and heterogeneous multi-platform
+support and a lot more.</para>
+<para>Apache Qpid is highly optimized, and <ulink url=
+"amqp-compatibility.html">aims to be 100% AMQP Compliant</ulink>.</para>
+
+<section>
+<title>Download the AMQP Specifications</title>
+
+<itemizedlist>
+<title>AMQP version 0-10</title>
+<listitem><para><ulink url="https://jira.amqp.org/confluence/download/attachments/720900/amqp.0-10.pdf?version=1"
+>AMQP 0-10 Specification (PDF)</ulink></para></listitem>
+<listitem><para><ulink url="https://jira.amqp.org/confluence/download/attachments/720900/amqp.0-10.xml?version=1"
+>AMQP 0-10 Protocol Definition XML</ulink></para></listitem>
+<listitem><para><ulink url="https://jira.amqp.org/confluence/download/attachments/720900/amqp.0-10.dfd?version=1"
+>AMQP 0-10 Protocol Definition DTD</ulink></para></listitem>
+</itemizedlist>
+
+
+<itemizedlist>
+<title>AMQP version 0-9-1</title>
+<listitem><para><ulink url=
+"https://jira.amqp.org/confluence/download/attachments/720900/amqp0-9-1.pdf?version=1"
+>AMQP 0-9-1 Specification (PDF)</ulink></para></listitem>
+<listitem><para><ulink url=
+"https://jira.amqp.org/confluence/download/attachments/720900/amqp0-9-1.xml?version=1"
+>AMQP 0-9-1 Protocol Documentation (PDF)</ulink></para></listitem>
+<listitem><para><ulink url=
+"https://jira.amqp.org/confluence/download/attachments/720900/amqp0-9-1.dtd?version=1"
+>AMQP 0-9-1 Protocol Definitions (XML)</ulink></para></listitem>
+</itemizedlist>
+
+
+<itemizedlist>
+<title>AMQP version 0-9</title>
+<listitem><para><ulink url=
+"https://jira.amqp.org/confluence/download/attachments/720900/amqp0-9.pdf?version=1"
+>AMQP 0-9 Specification (PDF)</ulink></para></listitem>
+<listitem><para><ulink url=
+"https://jira.amqp.org/confluence/download/attachments/720900/amqp0-9.xml?version=1"
+>AMQP 0-9 Protocol Documentation (PDF)</ulink></para></listitem>
+<listitem><para><ulink url=
+"https://jira.amqp.org/confluence/download/attachments/720900/amqp0-9.dtd?version=1"
+>AMQP 0-9 Protocol Definitions (XML)</ulink></para></listitem>
+</itemizedlist>
+
+
+<itemizedlist>
+<title>AMQP version 0-8</title>
+<listitem><para><ulink url=
+"https://jira.amqp.org/confluence/download/attachments/720900/amqp0-8.pdf?version=1"
+>AMQP 0-8 Specification (PDF)</ulink></para></listitem>
+<listitem><para><ulink url="https://jira.amqp.org/confluence/download/attachments/720900/amqp0-8.dtd?version=1"
+>AMQP 0-8 Protocol Documentation (PDF)</ulink></para></listitem>
+<listitem><para><ulink url="https://jira.amqp.org/confluence/download/attachments/720900/amqp0-8.xml?version=1"
+>AMQP 0-8 Protocol Definitions (XML)</ulink></para></listitem>
+</itemizedlist>
+</section>
+
+</chapter>
diff --git a/qpid/doc/book/src/Add-New-Users.xml b/qpid/doc/book/src/Add-New-Users.xml
new file mode 100644
index 0000000000..dc34bcc5c9
--- /dev/null
+++ b/qpid/doc/book/src/Add-New-Users.xml
@@ -0,0 +1,237 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+
+ 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.
+
+-->
+
+<section><title>
+ Add New Users
+ </title><para>
+ The Qpid Java Broker has a single reference source (<xref linkend="qpid_PrincipalDatabase"/>) that
+ defines all the users in the system.
+ </para><para>
+ To add a new user to the broker the password file must be
+ updated. The details about adding entries and when these updates
+ take effect are dependent on the file format each of which are
+ described below.
+ </para>
+
+ <section role="h2" id="AddNewUsers-AvailablePasswordfileformats"><title>
+ Available
+ Password file formats
+ </title>
+ <para>
+ There are currently two different file formats available for use
+ depending on the PrincipalDatabase that is desired. In all cases
+ the clients need not be aware of the type of PrincipalDatabase in
+ use they only need support the SASL mechanisms they provide.
+ </para><itemizedlist>
+ <listitem><para>
+ <xref linkend="AddNewUsers-Plain"/>
+ </para></listitem>
+ <listitem><para>
+ <xref linkend="AddNewUsers-Base64MD5PasswordFileFormat"/>
+ </para></listitem>
+ </itemizedlist><para>
+
+ </para>
+
+ <section role="h3" id="AddNewUsers-Plain"><title>
+ Plain
+ </title>
+ <para>
+ The plain file has the following format:
+ </para>
+ <programlisting>
+# Plain password authentication file.
+# default name : passwd
+# Format &lt;username&gt;:&lt;password&gt;
+#e.g.
+martin:password
+</programlisting>
+ <para>
+ As the contents of the file are plain text and the password is
+ taken to be everything to the right of the ':'(colon). The
+ password, therefore, cannot contain a ':' colon, but this can be
+ used to delimit the password.
+ </para><para>
+ Lines starting with a '#' are treated as comments.
+ </para>
+<!--h3--></section>
+
+ <section role="h3" id="AddNewUsers-Whereisthepasswordfileformybroker-3F"><title>
+ Where is
+ the password file for my broker ?
+ </title>
+ <para>
+ The location of the password file in use for your broker is as
+ configured in your config.xml file.
+ </para>
+ <programlisting>
+&lt;principal-databases&gt;
+ &lt;principal-database&gt;
+ &lt;name&gt;passwordfile&lt;/name&gt;
+ &lt;class&gt;org.apache.qpid.server.security.auth.database.PlainPasswordFilePrincipalDatabase&lt;/class&gt;
+ &lt;attributes&gt;
+ &lt;attribute&gt;
+ &lt;name&gt;passwordFile&lt;/name&gt;
+ &lt;value&gt;${conf}/passwd&lt;/value&gt;
+ &lt;/attribute&gt;
+ &lt;/attributes&gt;
+ &lt;/principal-database&gt;
+ &lt;/principal-databases&gt;
+</programlisting>
+ <para>
+ So in the example config.xml file this password file lives in the
+ directory specified as the conf directory (at the top of your
+ config.xml file).
+ </para><para>
+ If you wish to use Base64 encoding for your password file, then
+ in the &lt;class&gt; element above you should specify
+ org.apache.qpid.server.security.auth.database.Base64MD5PasswordFilePrincipalDatabase
+ </para><para>
+ The default is:
+ </para>
+ <programlisting>
+ &lt;conf&gt;${prefix}/etc&lt;/conf&gt;
+</programlisting>
+<!--h3--></section>
+
+
+ <section role="h3" id="AddNewUsers-Base64MD5PasswordFileFormat"><title>
+ Base64MD5
+ Password File Format
+ </title>
+ <para>
+ This format can be used to ensure that SAs cannot read the plain
+ text password values from your password file on disk.
+ </para><para>
+ The Base64MD5 file uses the following format:
+ </para>
+ <programlisting>
+# Base64MD5 password authentication file
+# default name : qpid.passwd
+# Format &lt;username&gt;:&lt;Base64 Encoded MD5 hash of the users password&gt;
+#e.g.
+martin:X03MO1qnZdYdgyfeuILPmQ==
+</programlisting>
+ <para>
+ As with the Plain format the line is delimited by a ':'(colon).
+ The password field contains the MD5 Hash of the users password
+ encoded in Base64.
+ </para><para>
+ This file is read on broker start-up and is not re-read.
+ </para>
+<!--h3--></section>
+
+ <section role="h3" id="AddNewUsers-HowcanIupdateaBase64MD5passwordfile-3F"><title>
+ How can
+ I update a Base64MD5 password file ?
+ </title>
+ <para>
+ To update the file there are two options:
+ </para><orderedlist>
+ <listitem><para>Edit the file by hand using the <emphasis>qpid-passwd</emphasis> tool
+ that will generate the required lines. The output from the tool
+ is the text that needs to be copied in to your active password
+ file. This tool is located in the broker bin directory.
+ Eventually it is planned for this tool to emulate the
+ functionality of <xref linkend="qpid_htpasswd"/>
+ for qpid passwd files.
+ <emphasis>NOTE:</emphasis> For the changes to be seen by the broker you must
+ either restart the broker or reload the data with the
+ management tools (see <xref linkend="Qpid-JMX-Management-Console-User-Guide"/>)
+ </para></listitem>
+ <listitem><para>Use the management tools to create a new user. The changes
+ will be made by the broker to the password file and the new user
+ will be immediately available to the system (see <xref linkend="Qpid-JMX-Management-Console-User-Guide"/>).
+ </para></listitem>
+ </orderedlist>
+<!--h3--></section>
+<!--h2--></section>
+
+
+ <section role="h2" id="AddNewUsers-Dynamicchangestopasswordfiles."><title>
+ Dynamic
+ changes to password files.
+ </title>
+ <para>
+ The Plain password file and the Base64MD5 format file are both
+ only read once on start up.
+ </para><para>
+ To make changes dynamically there are two options, both require
+ administrator access via the Management Console (see <xref linkend="Qpid-JMX-Management-Console-User-Guide"/>)
+ </para><orderedlist>
+ <listitem><para>You can replace the file and use the console to reload its
+ contents.
+ </para></listitem>
+ <listitem><para>The management console provides an interface to create,
+ delete and amend the users. These changes are written back to the
+ active password file.
+ </para></listitem>
+ </orderedlist>
+<!--h2--></section>
+
+ <section role="h2" id="AddNewUsers-HowpasswordfilesandPrincipalDatabasesrelatetoauthenticationmechanisms"><title>
+ How password files and PrincipalDatabases relate to
+ authentication mechanisms
+ </title>
+ <para>
+ For each type of password file a PrincipalDatabase exists that
+ parses the contents. These PrincipalDatabases load various SASL
+ mechanism based on their supportability. e.g. the Base64MD5 file
+ format can't support Plain authentication as the plain password
+ is not available. Any client connecting need only be concerned
+ about the SASL module they support and not the type of
+ PrincipalDatabase. So I client that understands CRAM-MD5 will
+ work correctly with a Plain and Base64MD5 PrincipalDatabase.
+ </para><table>
+ <title>File Format and Principal Database</title><tgroup cols="2">
+ <tbody>
+ <row>
+ <entry>
+ FileFormat/PrincipalDatabase
+ </entry>
+ <entry>
+ SASL
+ </entry>
+ </row>
+ <row>
+ <entry>
+ Plain
+ </entry>
+ <entry>
+ AMQPLAIN PLAIN CRAM-MD5
+ </entry>
+ </row>
+ <row>
+ <entry>
+ Base64MD5
+ </entry>
+ <entry>
+ CRAM-MD5 CRAM-MD5-HASHED
+ </entry>
+ </row>
+ </tbody>
+ </tgroup></table><para>
+ For details of SASL support see <xref linkend="qpid_Qpid-Interoperability-Documentation"/>
+ </para>
+<!--h2--></section>
+
+</section>
diff --git a/qpid/doc/book/src/Binding-URL-Format.xml b/qpid/doc/book/src/Binding-URL-Format.xml
new file mode 100644
index 0000000000..3d938b740a
--- /dev/null
+++ b/qpid/doc/book/src/Binding-URL-Format.xml
@@ -0,0 +1,174 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+
+ 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.
+
+-->
+
+<section id="BindingURLFormat">
+ <title>
+ Binding URL Format
+ </title>
+ <programlisting>
+&lt;Exchange Class&gt;://&lt;Exchange Name&gt;/[&lt;Destination&gt;]/[&lt;Queue&gt;][?&lt;option&gt;='&lt;value&gt;'[&amp;&lt;option&gt;='&lt;value&gt;']]
+</programlisting>
+ <para>
+ This URL format is used for two purposes in the code base. The
+ broker uses this in the XML configuration file to create and bind
+ queues at broker startup. It is also used by the client as a
+ destination.
+ </para><para>
+ This format was used because it allows an explicit description of
+ exchange and queue relationship.
+ </para><para>
+ The Exchange Class is not normally required for client connection
+ as clients only publish to a named exchange however if exchanges
+ are being dynamically instantiated it will be required. The class
+ is required for the server to instantiate an exchange.
+ </para><para>
+ There are a number of options that are currently defined:
+ </para><table><title>Binding URL Options</title><tgroup cols="3">
+ <tbody>
+ <row>
+ <entry>
+ Option
+ </entry>
+ <entry>
+ type
+ </entry>
+ <entry>
+ Description
+ </entry>
+ </row>
+ <row>
+ <entry>
+ exclusive
+ </entry>
+ <entry>
+ boolean
+ </entry>
+ <entry>
+ Is this an exclusive connection
+ </entry>
+ </row>
+ <row>
+ <entry>
+ autodelete
+ </entry>
+ <entry>
+ boolean
+ </entry>
+ <entry>
+ Should this queue be deleted on client disconnection
+ </entry>
+ </row>
+ <row>
+ <entry>
+ durable
+ </entry>
+ <entry>
+ boolean
+ </entry>
+ <entry>
+ Create a durable queue
+ </entry>
+ </row>
+ <row>
+ <entry>
+ clientid
+ </entry>
+ <entry>
+ string
+ </entry>
+ <entry>
+ Use the following client id
+ </entry>
+ </row>
+ <row>
+ <entry>
+ subscription
+ </entry>
+ <entry>
+ boolean
+ </entry>
+ <entry>
+ Create a subscription to this destination
+ </entry>
+ </row>
+ <row>
+ <entry>
+ routingkey
+ </entry>
+ <entry>
+ string
+ </entry>
+ <entry>
+ Use this value as the routing key
+ </entry>
+ </row>
+ </tbody>
+ </tgroup></table><para>
+ Using these options in conjunction with the Binding URL format
+ should allow future expansion as new and custom exchange types
+ are created.
+ </para><para>
+ The URL format requires <emphasis>that at least one</emphasis> Queue or
+ routingkey option be present on the URL.
+ </para><para>
+ The routingkey would be used to encode a topic as shown in the
+ examples section below.
+ </para>
+
+ <section role="h4" id="BindingURLFormat-Examples">
+ <title>
+ Examples
+ </title>
+
+<example>
+<title> Queues</title>
+ <para>
+ A queue can be created in QPID using the following URL format.
+ </para><para>
+ direct://amq.direct//&lt;Queue Name&gt;
+ </para><para>
+ For example: direct://amq.direct//simpleQueue
+ </para><para>
+ Queue names may consist of any mixture of digits, letters, and
+ underscores.
+ </para>
+</example>
+<example>
+<title>Topics</title>
+ <para>
+ A topic can be created in QPID using the following URL format.
+ </para><para>
+ topic://amq.topic/&lt;Topic Subscription&gt;/
+ </para><para>
+ The topic subscription may only contain the letters A-Z and a-z
+ and digits 0-9.
+ </para>
+ <programlisting>
+direct://amq.direct/SimpleQueue
+direct://amq.direct/UnusuallyBoundQueue?routingkey='/queue'
+topic://amq.topic?routingkey='stocks.#'
+topic://amq.topic?routingkey='stocks.nyse.ibm'
+</programlisting>
+</example>
+<!--h4--></section>
+</section>
diff --git a/qpid/doc/book/src/Book-Info.xml b/qpid/doc/book/src/Book-Info.xml
new file mode 100644
index 0000000000..2e02fbe8ea
--- /dev/null
+++ b/qpid/doc/book/src/Book-Info.xml
@@ -0,0 +1,68 @@
+<?xml version='1.0' encoding='utf-8' ?>
+
+<!--
+
+ 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.
+
+-->
+
+<!DOCTYPE bookinfo PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
+]>
+
+<bookinfo id="book-Messaging_Installation_Guide-Messaging_Installation_Guide">
+ <title>Apache Qpid</title>
+ <subtitle>Open Source AMQP Messaging</subtitle>
+ <edition>1</edition>
+ <pubsnumber>0</pubsnumber>
+ <productname>Apache Qpid</productname>
+ <productnumber>6</productnumber>
+ <corpauthor>
+ <inlinemediaobject>
+ <imageobject>
+ <imagedata fileref="Common_Content/images/qpid-logo.png" format="PNG" />
+ </imageobject>
+ </inlinemediaobject>
+ </corpauthor>
+
+ <copyright>
+ <year>2010</year>
+ <holder>The Apache Software Foundation</holder>
+ </copyright>
+
+ <legalnotice>
+ <para>Licensed 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</para>
+
+ <para><filename>http://www.apache.org/licenses/LICENSE-2.0</filename></para>
+
+ <para>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.
+ </para>
+
+
+ </legalnotice>
+
+</bookinfo>
+
+
diff --git a/qpid/doc/book/src/Book.xml b/qpid/doc/book/src/Book.xml
new file mode 100644
index 0000000000..ee69532152
--- /dev/null
+++ b/qpid/doc/book/src/Book.xml
@@ -0,0 +1,93 @@
+<?xml version='1.0' encoding='utf-8' ?>
+
+<!--
+
+ 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.
+
+-->
+
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
+]>
+
+<book>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="Book-Info.xml"/>
+ <part>
+ <title>Basics</title>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="Introduction.xml"/>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="AMQP.xml"/>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="Getting-Started.xml"/>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="Download.xml"/>
+ </part>
+
+<!--
+ The broker sections define their own <part/> elements, with <partintro/> text.
+-->
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="AMQP-Messaging-Broker-CPP.xml"/>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="AMQP-Messaging-Broker-Java.xml"/>
+
+ <part>
+ <title>AMQP Messaging Clients Clients</title>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="AMQP-Java-JMS-Messaging-Client.xml"/>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="AMQP-C++-Messaging-Client.xml"/>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="AMQP-.NET-Messaging-Client.xml"/>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="AMQP-Python-Messaging-Client.xml"/>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="AMQP-Ruby-Messaging-Client.xml"/>
+
+ </part>
+ <part>
+ <title>Appendices</title>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="AMQP-Compatibility.xml"/>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="Qpid-Interoperability-Documentation.xml"/>
+<!-- <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="FAQ.xml"/> -->
+ </part>
+</book>
+
+<!--
+Documentation
+Getting Started
+
+ * Download
+ * Getting Started
+
+AMQP (Advanced Message Queueing Protocol)
+
+ * Toward a Commodity Enterprise Middleware
+ * AMQP (Advanced Message Queueing Protocol)
+
+Qpid AMQP Brokers
+
+ * AMQP Messaging Broker (implemented in C++)
+ * AMQP Messaging Broker (implemented in Java)
+
+Qpid AMQP Clients
+
+ * AMQP Java JMS Messaging Client
+ * AMQP C++ Messaging Client
+ * AMQP .NET Messaging Client
+ * AMQP Python Messaging Client
+ * AMQP Ruby Messaging Client
+
+Interoperability
+
+ * AMQP Compatibility
+ * SASL Interoperability
+
+FAQ
+
+ * Frequently Asked Questions
+-->
diff --git a/qpid/doc/book/src/Broker-CPP.xml b/qpid/doc/book/src/Broker-CPP.xml
new file mode 100644
index 0000000000..99584be23d
--- /dev/null
+++ b/qpid/doc/book/src/Broker-CPP.xml
@@ -0,0 +1,40 @@
+<!--
+ -
+ - 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.
+ -
+ -->
+h1. Running the AMQP Messaging Broker
+
+* [Running an AMQP 0-10 C++ broker | RASC]
+* [Configuring Queue Options|Cheat Sheet for configuring Queue Options]
+* [Configuring Exchange Options|Cheat Sheet for configuring Exchange Options]
+* [Using Broker Federation]
+* [How to use SSL | SSL]
+* [Understanding Last Value Queues (LVQ) |LVQ]
+* [Queue State Replication|queue state replication]
+* [Getting Started]
+* [Starting a cluster]
+* [Understanding Access Control Lists|Qpid ACLs]
+
+h2. Management
+
+* [Managing| MgmtC++] the C++ Broker
+* [QMan - Qpid Management bridge]
+* [Qpid Management Framework]
+* [Qpid Management Framework (QMF) Protocol|management design notes]
+* [Manage anything with Qpid - QMF Python Console Tutorial|QMF Python Console Tutorial]
diff --git a/qpid/doc/book/src/Broker-Configuration-Guide.xml b/qpid/doc/book/src/Broker-Configuration-Guide.xml
new file mode 100644
index 0000000000..c52e1fbfd4
--- /dev/null
+++ b/qpid/doc/book/src/Broker-Configuration-Guide.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+
+ 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.
+
+-->
+
+<section>
+ <title>Broker Configuration Guide </title>
+
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="java/broker/configuration/Topic-Configuration.xml"/>
+</section>
diff --git a/qpid/doc/book/src/Broker-Java.xml b/qpid/doc/book/src/Broker-Java.xml
new file mode 100644
index 0000000000..f8ce89b185
--- /dev/null
+++ b/qpid/doc/book/src/Broker-Java.xml
@@ -0,0 +1,45 @@
+<!--
+ -
+ - 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.
+ -
+ -->
+h3. General User Guides
+
+* [Feature Guide| Java Broker Feature Guide]
+* [FAQ|Qpid Java FAQ]
+* [Getting Started Guide]
+* [Broker Environment Variables|Java Environment Variables]
+* [Troubleshooting Guide|Qpid Troubleshooting Guide]
+
+h3. How Tos
+* [Add New Users]
+* [Configure ACLs]
+* [Configure Java Qpid to use a SSL connection.]
+* [Configure Log4j CompositeRolling Appender]
+* [Configure the Broker via config.xml]
+* [Configure the Virtual Hosts via virtualhosts.xml]
+* [Debug using log4j]
+* [How to Tune M3 Java Broker Performance]
+* [Qpid Java Build How To]
+* [Use Priority Queues]
+
+h3. Management Tools
+* [Qpid JMX Management Console]
+* [MessageStore Tool]
+* [Qpid Java Broker Management CLI]
+* [Management Design notes]
diff --git a/qpid/doc/book/src/Cheat-Sheet-for-configuring-Exchange-Options.xml b/qpid/doc/book/src/Cheat-Sheet-for-configuring-Exchange-Options.xml
new file mode 100644
index 0000000000..fccdae1b9a
--- /dev/null
+++ b/qpid/doc/book/src/Cheat-Sheet-for-configuring-Exchange-Options.xml
@@ -0,0 +1,144 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+
+ 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.
+
+-->
+
+<section>
+ <title>
+ Cheat Sheet for configuring Exchange Options
+ </title>
+
+ <section role="h2" id="CheatSheetforconfiguringExchangeOptions-ConfiguringExchangeOptions">
+ <title>
+ Configuring Exchange Options
+ </title>
+ <para>
+ The C++ Broker M4 or later supports the following additional
+ Exchange options in addition to the standard AMQP define options
+ </para><itemizedlist>
+ <listitem><para>Exchange Level Message sequencing
+ </para></listitem>
+ <listitem><para>Initial Value Exchange
+ </para></listitem>
+ </itemizedlist><para>
+ Note that these features can be used on any exchange type, that
+ has been declared with the options set.
+ </para><para>
+ It also supports an additional option to the bind operation on a
+ direct exchange
+ </para><itemizedlist>
+ <listitem><para>Exclusive binding for key
+ </para></listitem>
+ </itemizedlist>
+
+ <section role="h3" id="CheatSheetforconfiguringExchangeOptions-ExchangeLevelMessagesequencing"><title>
+ Exchange Level Message sequencing
+ </title>
+ <para>
+ This feature can be used to place a sequence number into each
+ message's headers, based on the order they pass through an
+ exchange. The sequencing starts at 0 and then wraps in an AMQP
+ int64 type.
+ </para><para>
+ The field name used is "qpid.msg_sequence"
+ </para><para>
+ To use this feature an exchange needs to be declared specifying
+ this option in the declare
+ </para>
+ <programlisting>
+....
+ FieldTable args;
+ args.setInt("qpid.msg_sequence",1);
+
+...
+ // now declare the exchange
+ session.exchangeDeclare(arg::exchange="direct", arg::arguments=args);
+</programlisting>
+ <para>
+ Then each message passing through that exchange will be numbers
+ in the application headers.
+ </para>
+ <programlisting>
+ unit64_t seqNo;
+ //after message transfer
+ seqNo = message.getHeaders().getAsInt64("qpid.msg_sequence");
+</programlisting>
+ <!--h3--></section>
+ <section role="h3" id="CheatSheetforconfiguringExchangeOptions-InitialValueExchange"><title>
+ Initial
+ Value Exchange
+ </title>
+ <para>
+ This feature caches a last message sent to an exchange. When a
+ new binding is created onto the exchange it will then attempt to
+ route this cached messaged to the queue, based on the binding.
+ This allows for topics or the creation of configurations where a
+ new consumer can receive the last message sent to the broker,
+ with matching routing.
+ </para><para>
+ To use this feature an exchange needs to be declared specifying
+ this option in the declare
+ </para>
+ <programlisting>
+....
+ FieldTable args;
+ args.setInt("qpid.ive",1);
+
+...
+ // now declare the exchange
+ session.exchangeDeclare(arg::exchange="direct", arg::arguments=args);
+</programlisting>
+ <para>
+ now use the exchange in the same way you would use any other
+ exchange.
+ </para>
+ <!--h3--></section>
+
+ <section role="h3" id="CheatSheetforconfiguringExchangeOptions-Exclusivebindingforkey"><title>
+ Exclusive
+ binding for key
+ </title>
+ <para>
+ Direct exchanges in qpidd support a qpid.exclusive-binding option
+ on the bind operation that causes the binding specified to be the
+ only one for the given key. I.e. if there is already a binding at
+ this exchange with this key it will be atomically updated to bind
+ the new queue. This means that the binding can be changed
+ concurrently with an incoming stream of messages and each message
+ will be routed to exactly one queue.
+ </para>
+ <programlisting>
+....
+ FieldTable args;
+ args.setInt("qpid.exclusive-binding",1);
+
+ //the following will cause the only binding from amq.direct with 'my-key'
+ //to be the one to 'my-queue'; if there were any previous bindings for that
+ //key they will be removed. This is atomic w.r.t message routing through the
+ //exchange.
+ session.exchangeBind(arg::exchange="amq.direct", arg::queue="my-queue",
+ arg::bindingKey="my-key", arg::arguments=args);
+
+...
+</programlisting>
+<!--h3--></section>
+<!--h2--></section>
+</section>
diff --git a/qpid/doc/book/src/Cheat-Sheet-for-configuring-Queue-Options.xml b/qpid/doc/book/src/Cheat-Sheet-for-configuring-Queue-Options.xml
new file mode 100644
index 0000000000..d50948e0cc
--- /dev/null
+++ b/qpid/doc/book/src/Cheat-Sheet-for-configuring-Queue-Options.xml
@@ -0,0 +1,259 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+
+ 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.
+
+-->
+
+<section><title>
+ Cheat Sheet for configuring Queue Options
+ </title>
+
+ <section role="h2" id="CheatSheetforconfiguringQueueOptions-ConfiguringQueueOptions"><title>
+ Configuring
+ Queue Options
+ </title>
+
+ <para>
+ The C++ Broker M4 or later supports the following additional
+ Queue constraints.
+ </para>
+ <itemizedlist>
+ <listitem><para>
+ <xref linkend="CheatSheetforconfiguringQueueOptions-ConfiguringQueueOptions"/>
+ </para></listitem>
+ <listitem><para>
+ <itemizedlist>
+ <listitem><para>
+ <xref linkend="CheatSheetforconfiguringQueueOptions-ApplyingQueueSizingConstraints"/>
+ </para></listitem>
+ <listitem><para>
+ <xref linkend="CheatSheetforconfiguringQueueOptions-ChangingtheQueueorderingBehaviors-28FIFO-2FLVQ-29"/>
+ </para></listitem>
+ <listitem><para>
+ <xref linkend="CheatSheetforconfiguringQueueOptions-Settingadditionalbehaviors"/>
+ </para></listitem>
+ <listitem><para>
+ <itemizedlist>
+ <listitem><para>
+ <xref linkend="CheatSheetforconfiguringQueueOptions-PersistLastNode"/>
+ </para></listitem>
+ <listitem><para>
+ <xref linkend="CheatSheetforconfiguringQueueOptions-Queueeventgeneration"/>
+ </para></listitem>
+ </itemizedlist>
+ </para></listitem>
+ <listitem><para>
+ <xref linkend="CheatSheetforconfiguringQueueOptions-OtherClients"/>
+ </para></listitem>
+ </itemizedlist>
+ </para></listitem>
+ </itemizedlist>
+
+ <para>
+ The 0.10 C++ Broker supports the following additional Queue configuration options:
+ </para>
+ <itemizedlist>
+ <listitem><para>
+ <xref linkend="producer-flow-control"/>
+ </para></listitem>
+ </itemizedlist>
+
+ <section role="h3" id="CheatSheetforconfiguringQueueOptions-ApplyingQueueSizingConstraints"><title>
+ Applying Queue Sizing Constraints
+ </title>
+
+ <para>
+ This allows to specify how to size a queue and what to do when
+ the sizing constraints have been reached. The queue size can be
+ limited by the number messages (message depth) or byte depth on
+ the queue.
+ </para><para>
+ Once the Queue meets/ exceeds these constraints the follow
+ policies can be applied
+ </para><itemizedlist>
+ <listitem><para>REJECT - Reject the published message
+ </para></listitem>
+ <listitem><para>FLOW_TO_DISK - Flow the messages to disk, to preserve memory
+ </para></listitem>
+ <listitem><para>RING - start overwriting messages in a ring based on sizing.
+ If head meets tail, advance head
+ </para></listitem>
+ <listitem><para>RING_STRICT - start overwriting messages in a ring based on
+ sizing. If head meets tail, AND the consumer has the tail message
+ acquired it will reject
+ </para></listitem>
+ </itemizedlist><para>
+ Examples:
+ </para><para>
+ Create a queue an auto delete queue that will support 100 000
+ bytes, and then REJECT
+ </para>
+ <programlisting>
+#include "qpid/client/QueueOptions.h"
+
+ QueueOptions qo;
+ qo.setSizePolicy(REJECT,100000,0);
+
+ session.queueDeclare(arg::queue=queue, arg::autoDelete=true, arg::arguments=qo);
+</programlisting>
+ <para>
+ Create a queue that will support 1000 messages into a RING buffer
+ </para>
+ <programlisting>
+#include "qpid/client/QueueOptions.h"
+
+ QueueOptions qo;
+ qo.setSizePolicy(RING,0,1000);
+
+ session.queueDeclare(arg::queue=queue, arg::arguments=qo);
+</programlisting>
+ <!--h3--></section>
+ <section role="h3" id="CheatSheetforconfiguringQueueOptions-ChangingtheQueueorderingBehaviors-28FIFO-2FLVQ-29"><title>
+ Changing the Queue ordering Behaviors (FIFO/LVQ)
+ </title>
+ <para>
+ The default ordering in a queue in Qpid is FIFO. However
+ additional ordering semantics can be used namely LVQ (Last Value
+ Queue). Last Value Queue is define as follows.
+ </para><para>
+ If I publish symbols RHT, IBM, JAVA, MSFT, and then publish RHT
+ before the consumer is able to consume RHT, that message will be
+ over written in the queue and the consumer will receive the last
+ published value for RHT.
+ </para><para>
+ Example:
+ </para>
+ <programlisting>
+#include "qpid/client/QueueOptions.h"
+
+ QueueOptions qo;
+ qo.setOrdering(LVQ);
+
+ session.queueDeclare(arg::queue=queue, arg::arguments=qo);
+
+ .....
+ string key;
+ qo.getLVQKey(key);
+
+ ....
+ for each message, set the into application headers before transfer
+ message.getHeaders().setString(key,"RHT");
+
+</programlisting>
+ <para>
+ Notes:
+ </para><itemizedlist>
+ <listitem><para>Messages that are dequeued and the re-queued will have the
+ following exceptions. a.) if a new message has been queued with
+ the same key, the re-queue from the consumer, will combine these
+ two messages. b.) If an update happens for a message of the same
+ key, after the re-queue, it will not update the re-queued
+ message. This is done to protect a client from being able to
+ adversely manipulate the queue.
+ </para></listitem>
+ <listitem><para>Acquire: When a message is acquired from the queue, no matter
+ it's position, it will behave the same as a dequeue
+ </para></listitem>
+ <listitem><para>LVQ does not support durable messages. If the queue or
+ messages are declared durable on an LVQ, the durability will be
+ ignored.
+ </para></listitem>
+ </itemizedlist><para>
+ A fully worked <xref linkend="LVQ-Examplesource"/> can be found here
+ </para>
+ <!--h3--></section>
+ <section role="h3" id="CheatSheetforconfiguringQueueOptions-Settingadditionalbehaviors"><title>
+ Setting additional behaviors
+ </title>
+ <section role="h4" id="CheatSheetforconfiguringQueueOptions-PersistLastNode"><title>
+ Persist
+ Last Node
+ </title>
+ <para>
+ This option is used in conjunction with clustering. It allows for
+ a queue configured with this option to persist transient messages
+ if the cluster fails down to the last node. If additional nodes
+ in the cluster are restored it will stop persisting transient
+ messages.
+ </para><para>
+ Note
+ </para><itemizedlist>
+ <listitem><para>if a cluster is started with only one active node, this mode
+ will not be triggered. It is only triggered the first time the
+ cluster fails down to 1 node.
+ </para></listitem>
+ <listitem><para>The queue MUST be configured durable
+ </para></listitem>
+ </itemizedlist><para>
+ Example:
+ </para>
+ <programlisting>
+#include "qpid/client/QueueOptions.h"
+
+ QueueOptions qo;
+ qo.clearPersistLastNode();
+
+ session.queueDeclare(arg::queue=queue, arg::durable=true, arg::arguments=qo);
+</programlisting>
+ <!--h4--></section>
+ <section role="h4" id="CheatSheetforconfiguringQueueOptions-Queueeventgeneration"><title>
+ Queue
+ event generation
+ </title>
+ <para>
+ This option is used to determine whether enqueue/dequeue events
+ representing changes made to queue state are generated. These
+ events can then be processed by plugins such as that used for
+ <xref linkend="queue-state-replication"/>.
+ </para><para>
+ Example:
+ </para>
+ <programlisting>
+#include "qpid/client/QueueOptions.h"
+
+ QueueOptions options;
+ options.enableQueueEvents(1);
+ session.queueDeclare(arg::queue="my-queue", arg::arguments=options);
+</programlisting>
+ <para>
+ The boolean option indicates whether only enqueue events should
+ be generated. The key set by this is
+ 'qpid.queue_event_generation' and the value is and integer value
+ of 1 (to replicate only enqueue events) or 2 (to replicate both
+ enqueue and dequeue events).
+ </para>
+ <!--h3--></section>
+ <!--h4--></section>
+ <section role="h3" id="CheatSheetforconfiguringQueueOptions-OtherClients"><title>
+ Other
+ Clients
+ </title>
+ <para>
+ Note that these options can be set from any client. QueueOptions
+ just correctly formats the arguments passed to the QueueDeclare()
+ method.
+ </para>
+
+ <!--h3--></section>
+
+ <!--h2--></section>
+
+
+</section>
diff --git a/qpid/doc/book/src/Clients.xml b/qpid/doc/book/src/Clients.xml
new file mode 100644
index 0000000000..3dc2d38e86
--- /dev/null
+++ b/qpid/doc/book/src/Clients.xml
@@ -0,0 +1,25 @@
+<!--
+ -
+ - 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.
+ -
+ -->
+[AMQP Java JMS Messaging Client]
+[AMQP C++ Messaging Client]
+[AMQP .NET Messaging Client]
+[AMQP Python Messaging Client]
+[AMQP Ruby Messaging Client]
diff --git a/qpid/doc/book/src/Configure-ACLs.xml b/qpid/doc/book/src/Configure-ACLs.xml
new file mode 100644
index 0000000000..ec3aaa8465
--- /dev/null
+++ b/qpid/doc/book/src/Configure-ACLs.xml
@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+
+ 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.
+
+-->
+
+<section>
+ <title>
+ Configure ACLs
+ </title>
+ <section role="h2" id="ConfigureACLs-ConfigureACLs">
+ <title>
+ Configure ACLs
+ </title>
+ <section role="h3" id="ConfigureACLs-Specification">
+ <title>
+ Specification
+ </title>
+ <itemizedlist>
+ <listitem><para>
+ <xref linkend="qpid_Java-XML-ACLs"/>
+ </para></listitem>
+ <listitem><para>
+ <xref linkend="qpid_ACL"/>
+ </para></listitem>
+ </itemizedlist>
+
+ <!--h3-->
+ </section>
+
+ <section role="h3" id="ConfigureACLs-CBroker">
+ <title>
+ C++ Broker
+ </title>
+ <para>
+ The C++ broker supports <xref linkend="qpid_ACL"/> of the ACLs
+ </para>
+
+ <!--h3-->
+ </section>
+
+ <section role="h3" id="ConfigureACLs-JavaBroker">
+ <title>
+ Java Broker
+ </title>
+
+ <itemizedlist>
+ <listitem><para>
+ <xref linkend="qpid_Java-XML-ACLs"/>
+ </para></listitem>
+ <listitem><para>Support for Version 2 specification is in progress.
+ </para></listitem>
+ </itemizedlist>
+
+ <!--h3-->
+ </section>
+
+ <!--h2-->
+ </section>
+
+</section>
diff --git a/qpid/doc/book/src/Configure-Java-Qpid-to-use-a-SSL-connection.xml b/qpid/doc/book/src/Configure-Java-Qpid-to-use-a-SSL-connection.xml
new file mode 100644
index 0000000000..c09923711d
--- /dev/null
+++ b/qpid/doc/book/src/Configure-Java-Qpid-to-use-a-SSL-connection.xml
@@ -0,0 +1,84 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+
+ 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.
+
+-->
+
+<section><title>
+ Configure Java Qpid to use a SSL connection.
+ </title>
+
+ <section role="h2" id="ConfigureJavaQpidtouseaSSLconnection.-UsingSSLconnectionwithQpidJava."><title>
+ Using SSL connection with Qpid Java.
+ </title>
+ <para>
+ This section will show how to use SSL to enable secure
+ connections between a Java client and broker.
+ </para>
+<!--h2--></section>
+ <section role="h2" id="ConfigureJavaQpidtouseaSSLconnection.-Setup"><title>
+ Setup
+ </title>
+ <section role="h3" id="ConfigureJavaQpidtouseaSSLconnection.-BrokerSetup"><title>
+ Broker
+ Setup
+ </title>
+ <para>
+ The broker configuration file (config.xml) needs to be updated to
+ include the SSL keystore location details.
+ </para>
+
+<programlisting>
+&lt;!-- Additions required to Connector Section --&gt;
+
+&lt;ssl&gt;
+ &lt;enabled&gt;true&lt;/enabled&gt;
+ &lt;sslOnly&gt;true&lt;/sslOnly&gt;
+ &lt;keystorePath&gt;/path/to/keystore.ks&lt;/keystorePath&gt;
+ &lt;keystorePassword&gt;keystorepass&lt;/keystorePassword&gt;
+&lt;/ssl&gt;
+</programlisting>
+
+ <para>
+ The sslOnly option is included here for completeness however this
+ will disable the unencrypted port and leave only the SSL port
+ listening for connections.
+ </para>
+<!--h3--></section>
+ <section role="h3" id="ConfigureJavaQpidtouseaSSLconnection.-ClientSetup"><title>
+ Client
+ Setup
+ </title>
+ <para>
+ The best place to start looking is class
+ <emphasis>SSLConfiguration</emphasis> this is provided to the connection
+ during creation however there is currently no example that
+ demonstrates its use.
+ </para>
+<!--h3--></section>
+<!--h2--></section>
+
+ <section role="h2" id="ConfigureJavaQpidtouseaSSLconnection.-Performingtheconnection."><title>
+ Performing
+ the connection.
+ </title>
+ <para/>
+ <!--h2--></section>
+</section>
diff --git a/qpid/doc/book/src/Configure-Log4j-CompositeRolling-Appender.xml b/qpid/doc/book/src/Configure-Log4j-CompositeRolling-Appender.xml
new file mode 100644
index 0000000000..2c21f9e76d
--- /dev/null
+++ b/qpid/doc/book/src/Configure-Log4j-CompositeRolling-Appender.xml
@@ -0,0 +1,150 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+
+ 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.
+
+-->
+
+<section><title>
+ Configure Log4j CompositeRolling Appender
+ </title>
+ <section role="h2" id="ConfigureLog4jCompositeRollingAppender-HowtoconfiguretheCompositeRollinglog4jAppender"><title>
+ How to configure the CompositeRolling log4j Appender
+ </title>
+ <para>
+ There are several sections of our default log4j file that will
+ need your attention if you wish to fully use this Appender.
+ </para>
+
+ <orderedlist>
+ <listitem>
+ <para>Enable the Appender</para>
+ <para>
+ The default log4j.xml file uses the FileAppender, swap this for
+ the ArchivingFileAppender as follows:
+ </para>
+ <programlisting>
+ &lt;!-- Log all info events to file --&gt;
+ &lt;root&gt;
+ &lt;priority value="info"/&gt;
+
+ &lt;appender-ref ref="ArchivingFileAppender"/&gt;
+ &lt;/root&gt;
+</programlisting>
+ </listitem>
+ <listitem>
+ <para>
+ Configure the Appender
+ </para>
+
+ <para>
+ The Appender has a number of parameters that can be adjusted
+ depending on what you are trying to achieve. For clarity lets
+ take a quick look at the complete default appender:
+ </para>
+ <programlisting>
+ &lt;appender name="ArchivingFileAppender" class="org.apache.log4j.QpidCompositeRollingAppender"&gt;
+ &lt;!-- Ensure that logs allways have the dateFormat set--&gt;
+ &lt;param name="StaticLogFileName" value="false"/&gt;
+ &lt;param name="File" value="${QPID_WORK}/log/${logprefix}qpid${logsuffix}.log"/&gt;
+ &lt;param name="Append" value="false"/&gt;
+ &lt;!-- Change the direction so newer files have bigger numbers --&gt;
+ &lt;!-- So log.1 is written then log.2 etc This prevents a lot of file renames at log rollover --&gt;
+ &lt;param name="CountDirection" value="1"/&gt;
+ &lt;!-- Use default 10MB --&gt;
+ &lt;!--param name="MaxFileSize" value="100000"/--&gt;
+ &lt;param name="DatePattern" value="'.'yyyy-MM-dd-HH-mm"/&gt;
+ &lt;!-- Unlimited number of backups --&gt;
+ &lt;param name="MaxSizeRollBackups" value="-1"/&gt;
+ &lt;!-- Compress(gzip) the backup files--&gt;
+ &lt;param name="CompressBackupFiles" value="true"/&gt;
+ &lt;!-- Compress the backup files using a second thread --&gt;
+ &lt;param name="CompressAsync" value="true"/&gt;
+ &lt;!-- Start at zero numbered files--&gt;
+ &lt;param name="ZeroBased" value="true"/&gt;
+ &lt;!-- Backup Location --&gt;
+ &lt;param name="backupFilesToPath" value="${QPID_WORK}/backup/log"/&gt;
+
+ &lt;layout class="org.apache.log4j.PatternLayout"&gt;
+ &lt;param name="ConversionPattern" value="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/&gt;
+ &lt;/layout&gt;
+ &lt;/appender&gt;
+</programlisting>
+ <para>
+ The appender configuration has three groups of parameter
+ configuration.
+ </para><para>
+ The first group is for configuration of the file name. The
+ default is to write a log file to QPID_WORK/log/qpid.log
+ (Remembering you can use the logprefix and logsuffix values to
+ modify the file name, see Property Config).
+ </para>
+ <programlisting>
+ &lt;!-- Ensure that logs always have the dateFormat set--&gt;
+ &lt;param name="StaticLogFileName" value="false"/&gt;
+ &lt;param name="File" value="${QPID_WORK}/log/${logprefix}qpid${logsuffix}.log"/&gt;
+ &lt;param name="Append" value="false"/&gt;
+</programlisting>
+ <para>
+ The second section allows the specification of a Maximum File
+ Size and a DatePattern that will be used to move on to the next
+ file.
+ </para><para>
+ When MaxFileSize is reached a new log file will be created
+ The DataPattern is used to decide when to create a new log file,
+ so here a new file will be created for every minute and every
+ 10Meg of data. So if 15MB of data is made every minute then there
+ will be two log files created each minute. One at the start of
+ the minute and a second when the file hit 10MB. When the next
+ minute arrives a new file will be made even though it only has
+ 5MB of content. For a production system it would be expected to
+ be changed to something like 'yyyy-MM-dd' which would make a new
+ log file each day and keep the files to a max of 10MB.
+ </para><para>
+ The final MaxSizeRollBackups allows you to limit the amount of
+ disk you are using by only keeping the last n backups.
+ </para>
+ <programlisting>
+ &lt;!-- Change the direction so newer files have bigger numbers --&gt;
+ &lt;!-- So log.1 is written then log.2 etc This prevents a lot of file renames at log rollover --&gt;
+ &lt;param name="CountDirection" value="1"/&gt;
+ &lt;!-- Use default 10MB --&gt;
+ &lt;!--param name="MaxFileSize" value="100000"/--&gt;
+ &lt;param name="DatePattern" value="'.'yyyy-MM-dd-HH-mm"/&gt;
+ &lt;!-- Unlimited number of backups --&gt;
+ &lt;param name="MaxSizeRollBackups" value="-1"/&gt;
+</programlisting>
+ <para>
+ The final section allows the old log files to be compressed and
+ copied to a new location.
+ </para>
+ <programlisting>
+ &lt;!-- Compress(gzip) the backup files--&gt;
+ &lt;param name="CompressBackupFiles" value="true"/&gt;
+ &lt;!-- Compress the backup files using a second thread --&gt;
+ &lt;param name="CompressAsync" value="true"/&gt;
+ &lt;!-- Start at zero numbered files--&gt;
+ &lt;param name="ZeroBased" value="true"/&gt;
+ &lt;!-- Backup Location --&gt;
+ &lt;param name="backupFilesToPath" value="${QPID_WORK}/backup/log"/&gt;
+</programlisting>
+</listitem>
+</orderedlist>
+<!--h2--></section>
+</section>
diff --git a/qpid/doc/book/src/Configure-the-Broker-via-config.xml.xml b/qpid/doc/book/src/Configure-the-Broker-via-config.xml.xml
new file mode 100644
index 0000000000..b91e0796b8
--- /dev/null
+++ b/qpid/doc/book/src/Configure-the-Broker-via-config.xml.xml
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+
+ 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.
+
+-->
+
+<section>
+ <title>
+ Configure the Broker via config.xml
+ </title>
+ <section role="h2" id="ConfiguretheBrokerviaconfig.xml-Brokerconfig.xmlOverview">
+ <title>
+ Broker config.xml Overview
+ </title>
+ <para>
+ The broker config.xml file which is shipped in the etc directory
+ of any Qpid binary distribution details various options and
+ configuration for the Java Qpid broker implementation.
+ </para>
+ <para>
+ In tandem with the virtualhosts.xml file, the config.xml file
+ allows you to control much of the deployment detail for your Qpid
+ broker in a flexible fashion.
+ </para>
+ <para>
+ Note that you can pass the config.xml you wish to use for your
+ broker instance to the broker using the -c command line option.
+ In turn, you can specify the paths for the broker password file
+ and virtualhosts.xml files in your config.xml for simplicity.
+ </para>
+ <para>
+ For more information about command line configuration options
+ please see <xref linkend="QpidDesign-Configuration-ConfigurationMethods"/>.
+ </para>
+ <!--h2-->
+ </section>
+
+ <section role="h2" id="ConfiguretheBrokerviaconfig.xml-QpidVersion">
+ <title>
+ Qpid
+ Version
+ </title>
+ <para>
+ The config format has changed between versions here you can find
+ the configuration details on a per version basis.
+ </para>
+ <para>
+ <xref linkend="qpid_M2-20--20config.xml"/>
+ <xref linkend="qpid_M2.1-20--20config.xml"/>
+ </para>
+ <!--h2-->
+ </section>
+
+</section>
diff --git a/qpid/doc/book/src/Configure-the-Virtual-Hosts-via-virtualhosts.xml.xml b/qpid/doc/book/src/Configure-the-Virtual-Hosts-via-virtualhosts.xml.xml
new file mode 100644
index 0000000000..690175d57e
--- /dev/null
+++ b/qpid/doc/book/src/Configure-the-Virtual-Hosts-via-virtualhosts.xml.xml
@@ -0,0 +1,131 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+
+ 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.
+
+-->
+
+<section><title>
+ Configure the Virtual Hosts via virtualhosts.xml
+ </title><section role="h2" id="ConfiguretheVirtualHostsviavirtualhosts.xml-virtualhosts.xmlOverview"><title>
+ virtualhosts.xml Overview
+ </title>
+ <para>
+ This configuration file contains details of all queues and
+ topics, and associated properties, to be created on broker
+ startup. These details are configured on a per virtual host
+ basis.
+ </para><para>
+ Note that if you do not add details of a queue or topic you
+ intend to use to this file, you must first create a consumer on a
+ queue/topic before you can publish to it using Qpid.
+ </para><para>
+ Thus most application deployments need a virtualhosts.xml file
+ with at least some minimal detail.
+ </para>
+
+ <section role="h3" id="ConfiguretheVirtualHostsviavirtualhosts.xml-XMLFormatwithComments"><title>
+ XML Format with Comments
+ </title>
+ <para>
+ The virtualhosts.xml which currently ships as part of the Qpid
+ distribution is really targeted at development use, and supports
+ various artifacts commonly used by the Qpid development team.
+ </para><para>
+ As a result, it is reasonably complex. In the example XML below,
+ I have tried to simplify one example virtual host setup which is
+ possibly more useful for new users of Qpid or development teams
+ looking to simply make use of the Qpid broker in their
+ deployment.
+ </para><para>
+ I have also added some inline comments on each section, which
+ should give some extra information on the purpose of the various
+ elements.
+ </para>
+
+
+
+ <programlisting>
+&lt;virtualhosts&gt;
+ &lt;!-- Sets the default virtual host for connections which do not specify a vh --&gt;
+ &lt;default&gt;localhost&lt;/default&gt;
+ &lt;!-- Define a virtual host and all it's config --&gt;
+ &lt;virtualhost&gt;
+ &lt;name&gt;localhost&lt;/name&gt;
+ &lt;localhost&gt;
+ &lt;!-- Define the types of additional AMQP exchange available for this vh --&gt;
+ &lt;!-- Always get amq.direct (for queues) and amq.topic (for topics) by default --&gt;
+ &lt;exchanges&gt;
+ &lt;!-- Example of declaring an additional exchanges type for developer use only --&gt;
+ &lt;exchange&gt;
+ &lt;type&gt;direct&lt;/type&gt;
+ &lt;name&gt;test.direct&lt;/name&gt;
+ &lt;durable&gt;true&lt;/durable&gt;
+ &lt;/exchange&gt;
+ &lt;/exchanges&gt;
+
+ &lt;!-- Define the set of queues to be created at broker startup --&gt;
+ &lt;queues&gt;
+ &lt;!-- The properties configured here will be applied as defaults to all --&gt;
+ &lt;!-- queues subsequently defined unless explicitly overridden --&gt;
+ &lt;exchange&gt;amq.direct&lt;/exchange&gt;
+ &lt;!-- Set threshold values for queue monitor alerting to log --&gt;
+ &lt;maximumQueueDepth&gt;4235264&lt;/maximumQueueDepth&gt; &lt;!-- 4Mb --&gt;
+ &lt;maximumMessageSize&gt;2117632&lt;/maximumMessageSize&gt; &lt;!-- 2Mb --&gt;
+ &lt;maximumMessageAge&gt;600000&lt;/maximumMessageAge&gt; &lt;!-- 10 mins --&gt;
+
+ &lt;!-- Define a queue with all default settings --&gt;
+ &lt;queue&gt;
+ &lt;name&gt;ping&lt;/name&gt;
+ &lt;/queue&gt;
+ &lt;!-- Example definitions of queues with overriden settings --&gt;
+ &lt;queue&gt;
+ &lt;name&gt;test-queue&lt;/name&gt;
+ &lt;test-queue&gt;
+ &lt;exchange&gt;test.direct&lt;/exchange&gt;
+ &lt;durable&gt;true&lt;/durable&gt;
+ &lt;/test-queue&gt;
+ &lt;/queue&gt;
+ &lt;queue&gt;
+ &lt;name&gt;test-ping&lt;/name&gt;
+ &lt;test-ping&gt;
+ &lt;exchange&gt;test.direct&lt;/exchange&gt;
+ &lt;/test-ping&gt;
+ &lt;/queue&gt;
+ &lt;/queues&gt;
+ &lt;/localhost&gt;
+ &lt;/virtualhost&gt;
+&lt;/virtualhosts&gt;
+</programlisting>
+<!--h3--></section>
+ <section role="h3" id="ConfiguretheVirtualHostsviavirtualhosts.xml-Usingyourownvirtualhosts.xml"><title>
+ Using your own virtualhosts.xml
+ </title>
+
+ <para>
+ Note that the config.xml file shipped as an example (or developer
+ default) in the Qpid distribution contains an element which
+ defines the path to the virtualhosts.xml.
+ </para><para>
+ When using your own virtualhosts.xml you must edit this path to
+ point at the location of your file.
+ </para>
+<!--h3--></section>
+<!--h2--></section>
+</section>
diff --git a/qpid/doc/book/src/Configuring-Management-Users.xml b/qpid/doc/book/src/Configuring-Management-Users.xml
new file mode 100644
index 0000000000..a2a8d46d88
--- /dev/null
+++ b/qpid/doc/book/src/Configuring-Management-Users.xml
@@ -0,0 +1,117 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+
+ 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.
+
+-->
+
+<section><title>
+ Configuring Management Users
+ </title><para>
+ The Qpid Java broker has a single source of users for the system.
+ So a user can connect to the broker to send messages and via the
+ JMX console to check the state of the broker.
+ </para><para>
+
+ </para>
+
+ <section role="h2" id="ConfiguringManagementUsers-Addinganewmanagementuser"><title>
+ Adding
+ a new management user
+ </title>
+ <para>
+ The broker does have some minimal configuration available to
+ limit which users can connect to the JMX console and what they
+ can do when they are there.
+ </para><para>
+ There are two steps required to add a new user with rights for
+ the JMX console.
+ </para><orderedlist>
+ <listitem><para>Create a new user login, see HowTo:<xref linkend="qpid_Add-New-Users"/>
+ </para></listitem>
+ <listitem><para>Grant the new user permission to the JMX Console
+ </para></listitem>
+ </orderedlist>
+
+ <section role="h3" id="ConfiguringManagementUsers-GrantingJMXConsolePermissions"><title>
+ Granting
+ JMX Console Permissions
+ </title>
+ <para>
+ By default new users do not have access to the JMX console. The
+ access to the console is controlled via the file
+ <emphasis>jmxremote.access</emphasis>.
+ </para><para>
+ This file contains a mapping from user to privilege.
+ </para><para>
+ There are three privileges available:
+ </para><orderedlist>
+ <listitem><para>readonly - The user is able to log in and view queues but not
+ make any changes.
+ </para></listitem>
+ <listitem><para>readwrite - Grants user ability to read and write queue
+ attributes such as alerting values.
+ </para></listitem>
+ <listitem><para>admin - Grants the user full access including ability to edit
+ Users and JMX Permissions in addition to readwrite access.
+ </para></listitem>
+ </orderedlist><para>
+ This file is read at start up and can forcibly be reloaded by an
+ admin user through the management console.
+ </para>
+<!--h3--></section>
+
+ <section role="h3" id="ConfiguringManagementUsers-AccessFileFormat"><title>
+ Access
+ File Format
+ </title>
+ <para>
+ The file is a standard Java properties file and has the following
+ format
+ </para>
+ <programlisting>
+&lt;username&gt;=&lt;privilege&gt;
+</programlisting>
+ <para>
+ If the username value is not a valid user (list in the specified
+ PrincipalDatabase) then the broker will print a warning when it
+ reads the file as that entry will have no meaning.
+ </para><para>
+ Only when the the username exists in both the access file and the
+ PrincipalDatabase password file will the user be able to login
+ via the JMX Console.
+ </para><section role="h4" id="ConfiguringManagementUsers-ExampleFile"><title>
+ Example File
+ </title>
+ <para>
+ The file will be timestamped by the management console if edited
+ through the console.
+ </para>
+ <programlisting>
+#Generated by JMX Console : Last edited by user:admin
+#Tue Jun 12 16:46:39 BST 2007
+admin=admin
+guest=readonly
+user=readwrite
+</programlisting>
+
+<!--h4--></section>
+<!--h3--></section>
+<!--h2--></section>
+</section>
diff --git a/qpid/doc/book/src/Configuring-Qpid-JMX-Management-Console.xml b/qpid/doc/book/src/Configuring-Qpid-JMX-Management-Console.xml
new file mode 100644
index 0000000000..72e4ba8969
--- /dev/null
+++ b/qpid/doc/book/src/Configuring-Qpid-JMX-Management-Console.xml
@@ -0,0 +1,181 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+
+ 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.
+
+-->
+
+<section><title>
+ Configuring Qpid JMX Management Console
+ </title><section role="h2" id="ConfiguringQpidJMXManagementConsole-ConfiguringQpidJMXManagementConsole"><title>
+ Configuring Qpid JMX Management Console
+ </title>
+
+ <para>
+ Qpid has a JMX management interface that exposes a number of
+ components of the running broker.
+ You can find out more about the features exposed by the JMX
+ interfaces <xref linkend="qpid_Qpid-Management-Features"/>.
+ </para><para>
+
+ </para>
+
+ <section role="h3" id="ConfiguringQpidJMXManagementConsole-InstallingtheQpidJMXManagementConsole"><title>
+ Installing the Qpid JMX Management Console
+ </title>
+
+ <orderedlist>
+ <listitem><para>Unzip the archive to a suitable location.</para>
+
+ <note><title>SSL encrypted connections</title>
+ <para>
+ Recent versions of the broker can make use of SSL to
+ encrypt their RMI based JMX connections. If a broker
+ being connected to is making use of this ability then
+ additional console configuration may be required,
+ particularly when using self-signed certificates. See
+ <xref linkend="qpid_Management-Console-Security"/> for details.
+ </para>
+ </note>
+ </listitem>
+ </orderedlist>
+
+ <note>
+ <title>JMXMP based connections</title>
+ <para>
+ In previous releases of Qpid (M4 and below) the broker
+ JMX connections could make use of the JMXMPConnector for
+ additional security over its default RMI based JMX
+ configuration. This is no longer the case, with SSL
+ encrypted RMI being the favored approach going forward.
+ However, if you wish to connect to an older broker using
+ JMXMP the console will support this so long as the
+ <emphasis>jmxremote_optional.jar</emphasis> file is provided to it.
+ For details see <xref linkend="qpid_Management-Console-Security"/>.
+ </para>
+ </note>
+<!--h3--></section>
+
+
+ <section role="h3" id="ConfiguringQpidJMXManagementConsole-RunningtheQpidJMXManagementConsole"><title>
+ Running the Qpid JMX Management Console
+ </title>
+
+ <para>
+ The console can be started in the following way, depending on
+ platform:
+ </para><itemizedlist>
+ <listitem><para>Windows: by running the 'qpidmc.exe' executable file.
+ </para></listitem>
+ </itemizedlist><itemizedlist>
+ <listitem><para>Linux: by running the 'qpidmc' executable.
+ </para></listitem>
+ </itemizedlist><itemizedlist>
+ <listitem><para>Mac OS X: by launching the consoles application bundle (.app
+ file).
+ </para></listitem>
+ </itemizedlist>
+<!--h3--></section>
+
+
+ <section role="h3" id="ConfiguringQpidJMXManagementConsole-UsingtheQpidJMXManagementConsole"><title>
+ Using the Qpid JMX Management Console
+ </title>
+
+ <para>
+ Please see <xref linkend="Qpid-JMX-Management-Console-User-Guide"/> for details on using this Eclipse RCP
+ application.
+ </para>
+
+<!--h3--></section>
+<!--h2--></section>
+
+ <section role="h2" id="ConfiguringQpidJMXManagementConsole-UsingJConsole"><title>
+ Using
+ JConsole
+ </title>
+
+ <para>
+ See <xref linkend="qpid_JConsole"/>
+ </para>
+<!--h2--></section>
+
+
+ <section role="h2" id="ConfiguringQpidJMXManagementConsole-UsingHermesJMS"><title>
+ Using
+ HermesJMS
+ </title>
+
+ <para>
+ HermesJMS also offers integration with the Qpid management
+ interfaces. You can get instructions and more information from
+ <ulink url="http://cwiki.apache.org/confluence/display/qpid/HermesJMS">HermesJMS</ulink>.
+ </para>
+<!--h2--></section>
+
+ <section role="h2" id="ConfiguringQpidJMXManagementConsole-UsingMC4J"><title>
+ Using
+ MC4J
+ </title>
+
+ <para>
+ <ulink url="qpid_www.mc4j.org">MC4J</ulink> is an alternative
+ management tool. It provide a richer "dashboard" that can
+ customise the raw MBeans.
+ </para>
+ <section role="h4" id="ConfiguringQpidJMXManagementConsole-Installation"><title>
+ Installation
+ </title>
+
+ <itemizedlist>
+ <listitem><para>First download and install MC4J for your platform. Version
+ 1.2 beta 9 is the latest version that has been tested.
+ </para></listitem>
+ <listitem><para>Copy the directory blaze/java/management/mc4j into
+ the directory &lt;MC4J-Installation&gt;/dashboards
+ </para></listitem>
+ </itemizedlist>
+<!--h4--></section>
+
+ <section role="h4" id="ConfiguringQpidJMXManagementConsole-Configuration"><title>
+ Configuration
+ </title>
+
+ <para>
+ You should create a connection the JVM to be managed. Using the
+ Management-&gt;Create Server Connection menu option. The
+ connection URL should be of the form:
+ service:jmx:rmi:///jndi/rmi://localhost:8999/jmxrmi
+ making the appropriate host and post changes.
+ </para>
+<!--h4--></section>
+
+ <section role="h4" id="ConfiguringQpidJMXManagementConsole-Operation"><title>
+ Operation
+ </title>
+
+ <para>
+ You can view tabular summaries of the queues, exchanges and
+ connections using the Global Dashboards-&gt;QPID tree view. To
+ drill down on individual beans you can right click on the bean.
+ This will show any available graphs too.
+ </para>
+<!--h4--></section>
+<!--h2--></section>
+</section>
diff --git a/qpid/doc/book/src/Connection-URL-Format.xml b/qpid/doc/book/src/Connection-URL-Format.xml
new file mode 100644
index 0000000000..cb772487cd
--- /dev/null
+++ b/qpid/doc/book/src/Connection-URL-Format.xml
@@ -0,0 +1,387 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+
+ 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.
+
+-->
+
+<section id="Connection-URL-Format">
+ <title>
+ Connection URL Format
+ </title>
+
+ <section role="h4" id="ConnectionURLFormat-Format">
+ <title>
+ Format
+ </title>
+ <programlisting>
+amqp://[&lt;user&gt;:&lt;pass&gt;@][&lt;clientid&gt;]&lt;virtualhost&gt;[?&lt;option&gt;='&lt;value&gt;'[&amp;&lt;option&gt;='&lt;value&gt;']]
+ </programlisting>
+ <para>
+ The connection url defines the values that are common across
+ the cluster of brokers. The virtual host is second in the list
+ as the AMQP specification demands that it start with a '/'
+ otherwise it be more readable to be swapped with
+ clientid. There is currently only one required option and that
+ is the <emphasis>brokerlist</emphasis> option. In addition the
+ following options are recognised. </para>
+<!--h4--></section>
+
+
+ <section role="h4" id="ConnectionURLFormat-WorkedExample">
+
+ <title> Worked Example </title>
+
+
+
+ <para> You could use a URL which looks something like this:
+ </para>
+
+<programlisting>
+amqp://guest:guest@client1/development?brokerlist='tcp://localhost:5672'
+</programlisting>
+
+ <para> Breaking this example down, here's what it all
+ means: </para>
+
+ <itemizedlist>
+ <listitem><para> amqp = the protocol we're using
+ </para></listitem>
+
+ <listitem><para> guest:guest@localhost = username:password@clientid
+ where the clientid is the name of your server (used under
+ the covers but don't worry about this for now). Always use
+ the guest:guest combination at the moment.</para></listitem>
+
+ <listitem><para> development = the name of the virtualhost, where the
+ virtualhost is a path which acts as a namespace. You can
+ effectively use any value here so long as you're consistent
+ throughout. The virtualhost must start with a slash "/" and
+ continue with names separated by slashes. A name consists of
+ any combination of at least one of [A-Za-z0-9] plus zero or
+ more of [.-_+!=:]. </para></listitem>
+
+ <listitem><para>brokerlist = this is the host address and port for
+ the broker you want to connect to. The connection factory
+ will assume tcp if you don't specify a transport
+ protocol. The port also defaults to 5672. Naturally you have
+ to put at least one broker in this list. </para></listitem>
+
+ </itemizedlist>
+
+ <para> This example is not using failover so only provides
+ one host for the broker. If you do wish to connect using
+ failover you can provide two (or more) brokers in the
+ format: </para>
+
+ <para>
+ brokerlist='tcp://host1&amp;tcp://host2:5673' </para>
+
+ <para>The default failover setup will automatically retry
+ each broker once after a failed connection. If the
+ brokerlist contains more than one server then these servers
+ are tried in a round robin. Details on how to modifiy this
+ behaviour will follow soon ! </para>
+
+ <!--h4-->
+ </section>
+
+ <section role="h4"
+ id="ConnectionURLFormat-Options">
+
+ <title> Options</title>
+
+ <table>
+ <title>Connection URL Options</title>
+ <tgroup cols="3">
+ <tbody>
+ <row>
+ <entry>
+ Option
+ </entry>
+ <entry>
+ Default
+ </entry>
+ <entry>
+ Description
+ </entry>
+ </row>
+ <row>
+ <entry>
+ brokerlist
+ </entry>
+ <entry>
+ see below
+ </entry>
+ <entry>
+ The list of brokers to use for this connection
+ </entry>
+ </row>
+ <row>
+ <entry>
+ failover
+ </entry>
+ <entry>
+ see below
+ </entry>
+ <entry>
+ The type of failover method to use with the broker list.
+ </entry>
+ </row>
+ <row>
+ <entry>
+ maxprefetch
+ </entry>
+ <entry>
+ 5000
+ </entry>
+ <entry>
+ The maximum number of messages to prefetch from the broker.
+ </entry>
+ </row>
+ </tbody>
+ </tgroup></table>
+<!--h4--></section>
+
+<section role="h4" id="ConnectionURLFormat-Brokerlistoption">
+ <title> Brokerlist option </title>
+ <programlisting>
+brokerlist='&lt;broker url&gt;[;&lt;broker url&gt;]'
+</programlisting>
+ <para>
+ The broker list defines the various brokers that can be used for
+ this connection. A minimum of one broker url is required
+ additional URLs are semi-colon(';') delimited.
+ </para>
+<!--h4--></section>
+
+<section role="h4" id="ConnectionURLFormat-BrokerURLformat">
+
+<title> Broker URL format </title>
+
+ <programlisting>
+&lt;transport&gt;://&lt;host&gt;[:&lt;port&gt;][?&lt;option&gt;='&lt;value&gt;'[&amp;&lt;option&gt;='&lt;value&gt;']]
+</programlisting>
+ <para>
+ There are currently quite a few default values that can be
+ assumed. This was done so that the current client examples would
+ not have to be re-written. The result is if there is no
+ transport, 'tcp' is assumed and the default AMQP port of 5672 is
+ used if no port is specified.
+ </para><table><title>Broker URL- Transport</title>
+ <tgroup cols="1">
+ <tbody>
+ <row>
+ <entry>
+ Transport
+ </entry>
+ </row>
+ <row>
+ <entry>
+ tcp
+ </entry>
+ </row>
+ <row>
+ <entry>
+ vm
+ </entry>
+ </row>
+ </tbody>
+ </tgroup></table><para>
+ Currently only 'tcp' and 'vm' transports are supported. Each
+ broker can take have additional options that are specific to that
+ broker. The following are currently implemented options. To add
+ support for further transports the
+ ''client.transportTransportConnection'' class needs updating
+ along with the parsing to handle the transport.
+ </para>
+ <table><title>Broker URL - Connection Options</title>
+ <tgroup cols="3">
+ <tbody>
+ <row>
+ <entry>
+ Option
+ </entry>
+ <entry>
+ Default
+ </entry>
+ <entry>
+ Description
+ </entry>
+ </row>
+ <row>
+ <entry>
+ retries
+ </entry>
+ <entry>
+ 1
+ </entry>
+ <entry>
+ The number of times to retry connection to this Broker
+ </entry>
+ </row>
+ <row>
+ <entry>
+ ssl
+ </entry>
+ <entry>
+ false
+ </entry>
+ <entry>
+ Use ssl on the connection
+ </entry>
+ </row>
+ <row>
+ <entry>
+ connecttimeout
+ </entry>
+ <entry>
+ 30000
+ </entry>
+ <entry>
+ How long in (milliseconds) to wait for the connection to
+ succeed
+ </entry>
+ </row>
+ <row>
+ <entry>
+ connectdelay
+ </entry>
+ <entry>
+ none
+ </entry>
+ <entry>
+ How long in (milliseconds) to wait before attempting to
+ reconnect
+ </entry>
+ </row>
+ </tbody>
+ </tgroup></table>
+<!--h4--></section>
+
+ <section role="h4" id="ConnectionURLFormat-Brokerlistfailoveroption">
+
+ <title> Brokerlist failover option </title>
+ <programlisting>
+failover='&lt;method&gt;[?&lt;options&gt;]'
+</programlisting>
+ <para>
+ This option controls how failover occurs when presented with a
+ list of brokers. There are only two methods currently implemented
+ but interface qpid.jms.failover.FailoverMethod can be
+ used for defining further methods.
+ </para><para>
+ Currently implemented failover methods.
+ </para><table><title>Broker List - Failover Options</title><tgroup cols="2">
+ <tbody>
+ <row>
+ <entry>
+ Method
+ </entry>
+ <entry>
+ Description
+ </entry>
+ </row>
+ <row>
+ <entry>
+ singlebroker
+ </entry>
+ <entry>
+ This will only use the first broker in the list.
+ </entry>
+ </row>
+ <row>
+ <entry>
+ roundrobin
+ </entry>
+ <entry>
+ This method tries each broker in turn.
+ </entry>
+ </row>
+ <row>
+ <entry>
+ nofailover
+ </entry>
+ <entry>
+ [New in 0.5] This method disables all retry and failover
+ logic.
+ </entry>
+ </row>
+ </tbody>
+ </tgroup></table><para>
+ The current defaults are naturally to use the 'singlebroker' when
+ only one broker is present and the 'roundrobin' method with
+ multiple brokers. The '''method''' value in the URL may also be
+ any valid class on the classpath that implements the
+ FailoverMethod interface.
+ </para><para>
+ The 'nofailover' method is useful if you are using a 3rd party
+ tool such as Mule that has its own reconnection strategy that you
+ wish to use.
+ </para>
+
+ <table>
+ <title>Broker List - Failover Options</title>
+ <tgroup cols="3">
+ <tbody>
+ <row>
+ <entry>
+ Option
+ </entry>
+ <entry>
+ Default
+ </entry>
+ <entry>
+ Description
+ </entry>
+ </row>
+ <row>
+ <entry>
+ cyclecount
+ </entry>
+ <entry>
+ 1
+ </entry>
+ <entry>
+ The number of times to loop through the list of available
+ brokers before failure.
+ </entry>
+ </row>
+ </tbody>
+ </tgroup></table><para>
+ <emphasis>Note:</emphasis> Default was changed from 0 to 1 in Release 0.5
+ </para>
+<!--h4--></section>
+
+ <section role="h3" id="ConnectionURLFormat-SampleURLs">
+
+ <title>
+ Sample URLs
+ </title>
+ <programlisting>
+amqp:///test?brokerlist='localhost'
+amqp:///test?brokerlist='tcp://anotherhost:5684?retries='10''
+amqp://guest:guest@/test?brokerlist='vm://:1;vm://:2'&amp;failover='roundrobin'
+amqp://guest:guest@/test?brokerlist='vm://:1;vm://:2'&amp;failover='roundrobin?cyclecount='20''
+amqp://guest:guest@client/test?brokerlist='tcp://localhost;tcp://redundant-server:5673?ssl='true''&amp;failover='roundrobin'
+amqp://guest:guest@/test?brokerlist='vm://:1'&amp;failover='nofailover'
+</programlisting>
+
+<!--h3--></section>
+</section>
diff --git a/qpid/doc/book/src/Debug-using-log4j.xml b/qpid/doc/book/src/Debug-using-log4j.xml
new file mode 100644
index 0000000000..c4ec107cd0
--- /dev/null
+++ b/qpid/doc/book/src/Debug-using-log4j.xml
@@ -0,0 +1,298 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+
+ 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.
+
+-->
+
+<section><title>
+ Debug using log4j
+ </title>
+
+ <section role="h2" id="Debugusinglog4j-Debuggingwithlog4jconfigurations"><title>
+ Debugging
+ with log4j configurations
+ </title>
+ <para>
+ Unfortunately setting of logging in the Java Broker is not simply
+ a matter of setting one of WARN,INFO,DEBUG. At some point in the
+ future we may have more BAU logging that falls in to that
+ category but more likely is that we will have a varioius config
+ files that can be swapped in (dynamically) to understand what is
+ going on.
+ </para><para>
+ This page will be host to a variety of useful configuration
+ setups that will allow a user or developer to extract only the
+ information they are interested in logging. Each section will be
+ targeted at logging in a particular area and will include a full
+ log4j file that can be used. In addition the logging
+ <emphasis>category</emphasis> elements will be presented and discussed so
+ that the user can create their own file.
+ </para><para>
+ Currently the configuration that is available has not been fully
+ documented and as such there are gaps in what is desired and what
+ is available. Some times this is due to the desire to reduce the
+ overhead in message processing, but sometimes it is simply an
+ oversight. Hopefully in future releases the latter will be
+ addressed but care needs to be taken when adding logging to the
+ 'Message Flow' path as this will have performance implications.
+ </para>
+
+ <section role="h3" id="Debugusinglog4j-LoggingConnectionState-5CDeprecated-5C"><title>
+ Logging
+ Connection State *Deprecated*
+ </title>
+ <para>
+ <emphasis>deprecation notice</emphasis> Version 0.6 of the Java broker includes
+ <xref linkend="qpid_Configure-Operational-Status-Logging"/> functionality which improves upon these messages and
+ as such enabling status logging would be more beneficial.
+ The configuration file has been left here for assistence with
+ broker versions prior to 0.6.
+ </para><para>
+ The goals of this configuration are to record:
+ </para><itemizedlist>
+ <listitem><para>New Connections
+ </para></listitem>
+ <listitem><para>New Consumers
+ </para></listitem>
+ <listitem><para>Identify slow consumers
+ </para></listitem>
+ <listitem><para>Closing of Consumers
+ </para></listitem>
+ <listitem><para>Closing of Connections
+ </para></listitem>
+ </itemizedlist><para>
+ An additional goal of this configuration is to minimise any
+ impact to the 'message flow' path. So it should not adversely
+ affect production systems.
+ </para>
+<programlisting>
+<![CDATA[
+<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
+ <appender name="FileAppender" class="org.apache.log4j.FileAppender">
+ <param name="File" value="${QPID_WORK}/log/${logprefix}qpid${logsuffix}.log"/>
+ <param name="Append" value="false"/>
+
+ <layout class="org.apache.log4j.PatternLayout">
+ <param name="ConversionPattern" value="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/>
+ </layout>
+
+ </appender>
+
+ <appender name="STDOUT" class="org.apache.log4j.ConsoleAppender">
+
+ <layout class="org.apache.log4j.PatternLayout">
+ <param name="ConversionPattern" value="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/>
+ </layout>
+ </appender>
+
+ <category name="Qpid.Broker">
+
+ <priority value="debug"/>
+ </category>
+
+
+ <!-- Provide warnings to standard output -->
+ <category name="org.apache.qpid">
+ <priority value="warn"/>
+ </category>
+
+
+ <!-- Connection Logging -->
+
+ <!-- Log details of client starting connection -->
+ <category name="org.apache.qpid.server.handler.ConnectionStartOkMethodHandler">
+ <priority value="info"/>
+ </category>
+ <!-- Log details of client closing connection -->
+ <category name="org.apache.qpid.server.handler.ConnectionCloseMethodHandler">
+ <priority value="info"/>
+ </category>
+ <!-- Log details of client responding to be asked to closing connection -->
+
+ <category name="org.apache.qpid.server.handler.ConnectionCloseOkMethodHandler">
+ <priority value="info"/>
+ </category>
+
+
+ <!-- Consumer Logging -->
+ <!-- Provide details of Consumers connecting-->
+ <category name="org.apache.qpid.server.handler.BasicConsumeMethodHandler">
+ <priority value="debug"/>
+ </category>
+
+ <!-- Provide details of Consumers disconnecting, if the call it-->
+ <category name="org.apache.qpid.server.handler.BasicCancelMethodHandler">
+ <priority value="debug"/>
+ </category>
+ <!-- Provide details of when a channel closes to attempt to match to the Consume as a Cancel is not always issued-->
+ <category name="org.apache.qpid.server.handler.ChannelCloseHandler">
+ <priority value="info"/>
+ </category>
+
+ <!-- Provide details of Consumers starting to consume-->
+ <category name="org.apache.qpid.server.handler.ChannelFlowHandler">
+ <priority value="debug"/>
+ </category>
+ <!-- Provide details of what consumers are going to be consuming-->
+ <category name="org.apache.qpid.server.handler.QueueBindHandler">
+ <priority value="info"/>
+ </category>
+
+ <!-- No way of determining if publish message is returned, client log should show it.-->
+
+ <root>
+ <priority value="debug"/>
+ <appender-ref ref="STDOUT"/>
+ <appender-ref ref="FileAppender"/>
+ </root>
+
+</log4j:configuration>
+]]>
+</programlisting>
+ <!--h3--></section>
+
+ <section role="h3" id="Debugusinglog4j-DebuggingMyApplication"><title>
+ Debugging My
+ Application
+ </title>
+ <para>
+ This is the most often asked for set of configuration. The goals
+ of this configuration are to record:
+ </para><itemizedlist>
+ <listitem><para>New Connections
+ </para></listitem>
+ <listitem><para>New Consumers
+ </para></listitem>
+ <listitem><para>Message Publications
+ </para></listitem>
+ <listitem><para>Message Consumption
+ </para></listitem>
+ <listitem><para>Identify slow consumers
+ </para></listitem>
+ <listitem><para>Closing of Consumers
+ </para></listitem>
+ <listitem><para>Closing of Connections
+ </para></listitem>
+ </itemizedlist><para>
+ NOTE: This configuration enables message logging on the 'message
+ flow' path so should only be used were message volume is
+ low.
+ <emphasis>Every message that is sent to the broker will generate at
+ least four logging statements</emphasis>
+ </para>
+<programlisting>
+<![CDATA[
+<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
+ <appender name="FileAppender" class="org.apache.log4j.FileAppender">
+ <param name="File" value="${QPID_WORK}/log/${logprefix}qpid${logsuffix}.log"/>
+ <param name="Append" value="false"/>
+
+ <layout class="org.apache.log4j.PatternLayout">
+ <param name="ConversionPattern" value="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/>
+ </layout>
+
+ </appender>
+
+ <appender name="STDOUT" class="org.apache.log4j.ConsoleAppender">
+
+ <layout class="org.apache.log4j.PatternLayout">
+ <param name="ConversionPattern" value="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/>
+ </layout>
+ </appender>
+
+ <category name="Qpid.Broker">
+
+ <priority value="debug"/>
+ </category>
+
+
+ <!-- Provide warnings to standard output -->
+ <category name="org.apache.qpid">
+ <priority value="warn"/>
+ </category>
+
+
+ <!-- Connection Logging -->
+
+ <!-- Log details of client starting connection -->
+ <category name="org.apache.qpid.server.handler.ConnectionStartOkMethodHandler">
+ <priority value="info"/>
+ </category>
+ <!-- Log details of client closing connection -->
+ <category name="org.apache.qpid.server.handler.ConnectionCloseMethodHandler">
+ <priority value="info"/>
+ </category>
+ <!-- Log details of client responding to be asked to closing connection -->
+
+ <category name="org.apache.qpid.server.handler.ConnectionCloseOkMethodHandler">
+ <priority value="info"/>
+ </category>
+
+ <!-- Consumer Logging -->
+ <!-- Provide details of Consumers connecting-->
+ <category name="org.apache.qpid.server.handler.BasicConsumeMethodHandler">
+ <priority value="debug"/>
+ </category>
+
+ <!-- Provide details of Consumers disconnecting, if the call it-->
+ <category name="org.apache.qpid.server.handler.BasicCancelMethodHandler">
+ <priority value="debug"/>
+ </category>
+ <!-- Provide details of when a channel closes to attempt to match to the Consume as a Cancel is not always issued-->
+ <category name="org.apache.qpid.server.handler.ChannelCloseHandler">
+ <priority value="info"/>
+ </category>
+
+ <!-- Provide details of Consumers starting to consume-->
+ <category name="org.apache.qpid.server.handler.ChannelFlowHandler">
+ <priority value="debug"/>
+ </category>
+ <!-- Provide details of what consumers are going to be consuming-->
+ <category name="org.apache.qpid.server.handler.QueueBindHandler">
+ <priority value="info"/>
+ </category>
+
+ <!-- No way of determining if publish message is returned, client log should show it.-->
+
+ <!-- WARNING DO NOT ENABLE THIS IN PRODUCTION -->
+ <!-- Will generate minimum one log statements per published message -->
+ <!-- Will generate will log receiving of all body frame, count will vary on size of message.-->
+ <!-- Empty Message = no body, Body is up to 64kb of data -->
+ <!-- Will generate three log statements per recevied message -->
+
+ <!-- Log messages flow-->
+ <category name="org.apache.qpid.server.AMQChannel">
+
+ <priority value="debug"/>
+ </category>
+
+ <root>
+ <priority value="debug"/>
+ <appender-ref ref="STDOUT"/>
+ <appender-ref ref="FileAppender"/>
+ </root>
+
+</log4j:configuration>
+]]>
+</programlisting>
+
+<!--h3--></section>
+<!--h2--></section>
+</section>
diff --git a/qpid/doc/book/src/Download.xml b/qpid/doc/book/src/Download.xml
new file mode 100644
index 0000000000..7bc08143ac
--- /dev/null
+++ b/qpid/doc/book/src/Download.xml
@@ -0,0 +1,174 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+
+ 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.
+
+-->
+
+<chapter id="chapter-Download">
+
+<title>Download Apache Qpid</title>
+
+<para/>
+
+
+<section><title>Production Releases</title>
+
+<para>These releases are well tested and appropriate for production use. 0.5 is the latest release of Qpid.</para>
+
+<para>Qpid supports the latest version of AMQP 0-10, and some components also the AMQP 0-8 and 0-9, earlier versions. The Java Broker and Client provide protocol negotiation. Other versions can be found at <ulink url="http://www.apache.org/dist/qpid/">http://www.apache.org/dist/qpid/</ulink></para>
+
+<para>For details on cross component compatibility among releases, see: <ulink url="### FIX ME ###">AMQP Release Compatibility for Qpid|AMQP compatibility</ulink></para>
+
+<para>If you have any questions about these releases, please mail the user list (<ulink url="mailto:users@qpid.apache.org">users@qpid.apache.org</ulink>).</para>
+
+</section>
+
+<section><title>0.5 Release</title>
+
+<section><title>Multiple Component Packages</title>
+
+<table frame="all">
+<title/>
+<tgroup cols='4' align='left' colsep='1' rowsep='1'>
+<thead><row><entry> Component </entry><entry> Download </entry><entry> AMQP 0-10 </entry><entry> AMQP 0-8/0-9 </entry></row></thead>
+<tbody>
+<row><entry> Full release &amp; keys </entry><entry> <ulink url="http://www.apache.org/dist/qpid/0.5/">http://www.apache.org/dist/qpid/0.5/</ulink> </entry><entry> Y </entry><entry> Y </entry></row>
+<row><entry> C++ broker &amp; client </entry><entry> <ulink url="http://www.apache.org/dist/qpid/0.5/qpid-cpp-0.5.tar.gz">http://www.apache.org/dist/qpid/0.5/qpid-cpp-0.5.tar.gz</ulink> </entry><entry> Y </entry><entry> </entry></row>
+<row><entry> Java broker, client &amp; tools </entry><entry> <ulink url="http://www.apache.org/dist/qpid/0.5/qpid-java-0.5.tar.gz">http://www.apache.org/dist/qpid/0.5/qpid-java-0.5.tar.gz</ulink> </entry><entry> client </entry><entry> Y </entry></row>
+</tbody>
+</tgroup>
+</table>
+</section>
+
+<section><title>Single Component Package</title>
+
+
+<table>
+<title>Broker</title>
+<tgroup cols="4" align='left' colsep='1' rowsep='1'>
+<thead><row><entry> Language </entry><entry> Download </entry><entry> AMQP 0-10 </entry><entry> AMQP 0-8/0-9 </entry></row></thead>
+<tbody>
+<row><entry> Java </entry><entry> <ulink url="http://www.apache.org/dist/qpid/0.5/qpid-java-broker-0.5.tar.gz">http://www.apache.org/dist/qpid/0.5/qpid-java-broker-0.5.tar.gz</ulink> </entry><entry> </entry><entry> Y </entry></row>
+</tbody>
+</tgroup>
+</table>
+
+
+<table>
+<title>Client</title>
+<tgroup cols="4" align='left' colsep='1' rowsep='1'>
+<thead><row><entry> Language </entry><entry> Download </entry><entry> AMQP 0-10 </entry><entry> AMQP 0-8/0-9 </entry></row></thead>
+<tbody>
+<row><entry> C# (.NET, WCF, Excel) 0-10 client (C++ Broker Compatible) </entry><entry> <ulink url="http://www.apache.org/dist/qpid/0.5/qpid-dotnet-0-10-0.5.zip">http://www.apache.org/dist/qpid/0.5/qpid-dotnet-0-10-0.5.zip</ulink> </entry><entry> Y </entry><entry> </entry></row>
+<row><entry> C# (.NET) 0-8 client (Java Broker Compatible) </entry><entry> <ulink url="http://www.apache.org/dist/qpid/0.5/qpid-dotnet-0-8-0.5.zip">http://www.apache.org/dist/qpid/0.5/qpid-dotnet-0-8-0.5.zip</ulink> </entry><entry> </entry><entry> Y </entry></row>
+<row><entry> Java </entry><entry> <ulink url="http://www.apache.org/dist/qpid/0.5/qpid-java-client-0.5.tar.gz">http://www.apache.org/dist/qpid/0.5/qpid-java-client-0.5.tar.gz</ulink> </entry><entry> Y </entry><entry> Y </entry></row>
+<row><entry> Python </entry><entry> <ulink url="http://www.apache.org/dist/qpid/0.5/qpid-python-0.5.tar.gz">http://www.apache.org/dist/qpid/0.5/qpid-python-0.5.tar.gz</ulink> </entry><entry> Y </entry><entry> Y </entry></row>
+<row><entry> Ruby </entry><entry> <ulink url="http://www.apache.org/dist/qpid/0.5/qpid-ruby-0.5.tar.gz">http://www.apache.org/dist/qpid/0.5/qpid-ruby-0.5.tar.gz</ulink> </entry><entry> Y </entry><entry> Y </entry></row>
+</tbody>
+</tgroup>
+</table>
+
+
+<table>
+<title>C++ broker management</title>
+<tgroup cols="3" align='left' colsep='1' rowsep='1'>
+<thead><row><entry> Component </entry><entry> Download </entry><entry> AMQP 0-10 </entry></row></thead>
+<tbody>
+<row><entry> cmd line (packaged with python) </entry><entry> <ulink url="http://www.apache.org/dist/qpid/0.5/qpid-python-0.5.tar.gz">http://www.apache.org/dist/qpid/0.5/qpid-python-0.5.tar.gz</ulink> </entry><entry> Y </entry></row>
+<row><entry> QMan JMX bridge, WS-DM </entry><entry> <ulink url="http://www.apache.org/dist/qpid/0.5/qpid-management-client-0.5.tar.gz">http://www.apache.org/dist/qpid/0.5/qpid-management-client-0.5.tar.gz</ulink> </entry><entry> Y </entry></row>
+</tbody>
+</tgroup>
+</table>
+
+
+<table>
+<title>Java broker management</title>
+<tgroup cols="2" align='left' colsep='1' rowsep='1'>
+<thead><row><entry> Component </entry><entry> Download </entry></row></thead>
+<tbody>
+<row><entry> Eclipse RCP client </entry><entry> <ulink url="http://www.apache.org/dist/qpid/0.5/qpid-management-eclipse-plugin-0.5-linux-gtk-x86.tar.gz">Linux x86</ulink>
+<ulink url="http://www.apache.org/dist/qpid/0.5/qpid-management-eclipse-plugin-0.5-linux-gtk-x86_64.tar.gz">Linux x86_64</ulink>
+<ulink url="http://www.apache.org/dist/qpid/0.5/qpid-management-eclipse-plugin-0.5-macosx.zip">Mac OS X</ulink>
+<ulink url="http://www.apache.org/dist/qpid/0.5/qpid-management-eclipse-plugin-0.5-win32-win32-x86.zip">Windows x86</ulink>
+</entry></row>
+<row><entry> Command line interface </entry><entry> <ulink url="http://www.apache.org/dist/qpid/0.5/qpid-management-tools-qpid-cli-0.5.tar.gz">http://www.apache.org/dist/qpid/0.5/qpid-management-tools-qpid-cli-0.5.tar.gz</ulink> </entry></row>
+</tbody>
+</tgroup>
+</table>
+</section>
+</section>
+
+
+<section id="qpid_3rd-Party-Libraries"><title>QpidComponents.org</title>
+
+<para><ulink url="http://QpidComponents.org">http://QpidComponents.org</ulink> provides further components for Apache Qpid, including both persistence and management tools. These components are open source, but are not developed as part of the Apache Qpid project due to licensing or other restrictions.</para>
+
+</section>
+
+
+<section><title>Contributed C++ Packages</title>
+
+<section><title>Pre-built Linux Packages</title>
+
+<section><title>Fedora 8, 9, 10</title>
+
+<para>On Fedora, Qpid can be installed using yum. Because Java RPMs are not yet available in Fedora repos, the Java client is not in these distributions.</para>
+
+<para>To install the server:</para>
+<programlisting>
+# yum install qpidd
+</programlisting>
+<para>To install C++ and Python clients:</para>
+<programlisting>
+# yum install qpidc-devel
+</programlisting>
+<programlisting>
+# yum install amqp python-qpid
+</programlisting>
+<para>To install documentation:</para>
+<programlisting>
+# yum install rhm-docs
+</programlisting>
+<para>To install persistence using an external store module:</para>
+<programlisting>
+# yum install rhm
+</programlisting>
+</section>
+</section>
+
+
+<section><title>Windows Installer</title>
+
+<para>The Windows installer is available from <ulink url="http://www.apache.org/dist/qpid/0.5-windows/qpidc-0.5.msi">http://www.apache.org/dist/qpid/0.5-windows/qpidc-0.5.msi</ulink>. It is built from the 0.5 C++ broker and client source distribution listed above. It has been tested for Windows XP SP2 and above.</para>
+
+<para>The Windows executables require the Visual C++ 2008 SP1 run-time components. If the Visual C++ 2008 SP1 runtime is not available, the Qpid broker will not execute. If you intend to run the broker and Visual C++ 2008 is not installed, you must install the Visual C++ 2008 SP1 Redistributable. Please see <ulink url="http://www.microsoft.com/downloads/details.aspx?familyid=A5C84275-3B97-4AB7-A40D-3802B2AF5FC2&amp;displaylang=en">http://www.microsoft.com/downloads/details.aspx?familyid=A5C84275-3B97-4AB7-A40D-3802B2AF5FC2&amp;displaylang=en</ulink> for download and installation instructions.</para>
+
+<para>If you intend to develop Qpid client applications using this kit, you should install <ulink url="http://www.boostpro.com/download/boost_1_35_0_setup.exe">Boost version 1.35</ulink> (please be sure to select VC9 support when installing) in addition to Visual Studio 2008 SP1.</para>
+
+</section>
+</section>
+
+<section><title>Source Code Repository</title>
+
+<para>The latest version of the code is always available in the <ulink url="Source Repository">Source Repository</ulink>.
+</para>
+</section>
+
+
+</chapter>
diff --git a/qpid/doc/book/src/Excel-AddIn.xml b/qpid/doc/book/src/Excel-AddIn.xml
new file mode 100644
index 0000000000..e38f620bd8
--- /dev/null
+++ b/qpid/doc/book/src/Excel-AddIn.xml
@@ -0,0 +1,169 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+
+ 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.
+
+-->
+<section>
+ <title>
+ Excel AddIn
+ </title>
+ <section role="h1" id="ExcelAddIn-ExcelAddIn">
+ <title>
+ Excel AddIn
+ </title>
+ <para>
+ Qpid .net comes with Excel AddIns that are located in:
+ </para>
+ <para>
+ <filename>&lt;project-root&gt;\qpid\dotnet\client-010\addins</filename>
+ </para>
+
+ <para>
+ There are currently three projects:
+ </para>
+ <variablelist>
+ <varlistentry>
+ <term>ExcelAddIn</term>
+ <listitem>
+ <para>An RTD excel Addin</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>ExcelAddInProducer
+ </term>
+ <listitem>
+ <para>A sample client to demonstrate the RTD AddIn</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>ExcelAddInMessageProcessor
+ </term>
+ <listitem>
+ <para>A sample message processor for the RTD AddIn</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <section role="h2" id="ExcelAddIn-QpidRDTAddIn">
+ <title>
+ Qpid RDT AddIn
+ </title>
+ <section role="h3" id="ExcelAddIn-DeployingtheRTDAddIn">
+ <title>
+ Deploying the RTD
+ AddIn
+ </title>
+ <para>
+ Excel provides a function called RTD (real-time data) that lets
+ you specify a COM server via its ProgId here "Qpid" so that you
+ can push qpid messages into Excel.
+ </para>
+ <para>
+ The provided RTD AddIn consumes messages from one queue and
+ process them through a provided message processor.
+ </para>
+ <para>
+ For using the Qpid RTD follows those steps:
+ </para>
+
+ <procedure>
+ <step><para>
+ Copy the configuration Excel.exe.config into <filename>Drive\Program Files\Microsoft Office\Office12</filename>.
+ </para></step>
+ <step><para>
+ Edit <filename>Excel.exe.xml</filename> and set the targeted Qpid broker host, port
+ number, username and password.
+ </para></step>
+ <step> <para>
+ Select the cell or cell range to contain the RTD information
+ </para></step>
+ <step><para>
+ Enter the following formula <command>=rtd("Qpid",,"myQueue")</command>. Where
+ MyQueue is the queue from which you wish to receive messages from.
+ </para></step>
+ </procedure>
+ <para>
+ Note: The Qpid RTD is a COM-AddIn that must be registered with
+ Excel. This is done automatically when compiling the Addin with
+ visual studio.
+ </para>
+ <!--h3-->
+ </section>
+
+
+ <section role="h3" id="ExcelAddIn-Definingamessageprocessor">
+ <title>
+ Defining a message processor
+ </title>
+
+ <para>
+ The default behavior of the RDT AddIn is to display the message
+ payload. This could be altered by specifying your own message
+ processor.
+ A Message processor is a class that implements the API
+ <command>ExcelAddIn.MessageProcessor</command>. For example, the provided processor
+ in <filename>client-010\addins\ExcelAddInMessageProcessor</filename> displays the
+ message body and the the header price when specified.
+ </para>
+ <para>
+ To use you own message processor follows those steps:
+ </para>
+ <procedure>
+ <step><para>Write your own message processor that extends ExcelAddIn.MessageProcessor</para></step>
+ <step><para>Edit Excel.exe.config and uncomment the entries:</para>
+ <programlisting>
+&lt;add key="ProcessorAssembly"
+value="&lt;path&gt;\qpid\dotnet\client-010\addins\ExcelAddInMessageProcessor\bin\Debug\ExcelAddInMessageProcessor.dll"/&gt;
+ </programlisting>
+ <programlisting>
+ &lt;add key="ProcessorClass"
+ value="ExcelAddInMessageProcessor.Processor"/&gt;
+ </programlisting>
+ <itemizedlist>
+ <listitem>
+ <para>ProcessorAssembly is the path on the Assembly that contains
+ your processor class
+ </para>
+ </listitem>
+ <listitem>
+ <para>ProcessorClass is your processor class name
+ </para>
+ </listitem>
+ </itemizedlist>
+ </step>
+ <step><para>run excel and define a rtd function</para></step>
+ </procedure>
+ <para>
+ Note: the provided ExcelAddInProducer can be used for
+ testing the provided message processor. As messages are
+ sent to queue1 the following rtd function should be used
+ <command>=rtd("Qpid",,"queue1")</command>.
+ </para>
+
+ <!--h3-->
+ </section>
+
+ <!--h2-->
+ </section>
+
+ <!--h1-->
+ </section>
+
+</section>
diff --git a/qpid/doc/book/src/FAQ.xml b/qpid/doc/book/src/FAQ.xml
new file mode 100644
index 0000000000..5647f18f69
--- /dev/null
+++ b/qpid/doc/book/src/FAQ.xml
@@ -0,0 +1,524 @@
+<!--
+ -
+ - 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.
+ -
+ -->
+{toc}
+
+
+*This page is a collection of FAQ and How to-s for Qpid. If you have a question, post it to the users list and we will place the answer here to build out our FAQ/ How to.*
+
+h1. FAQ
+
+h2. About AMQP
+
+h3. What is AMQP?
+
+AMQP is a wire-level protocol and model for high performance enterprise messaging.
+
+[From the AMQP website:|http://www.amqp.org]
+
+ AMQP is an Open Standard for Messaging Middleware.
+
+ By complying to the AMQP standard, middleware products written for different platforms and in different languages can send messages to one another. AMQP addresses the problem of transporting value-bearing messages across and between organizations in a timely manner.
+
+ AMQP enables complete interoperability for messaging middleware; both the networking protocol and the semantics of broker services are defined in AMQP.
+
+h3. Where did AMQP come from
+
+AMQP was born out from Frustration by John O'Hara at JPMC. He started a project internally to create commodity messaging that was easy to use. Carl Trieloff from Red Hat had started a project to build messaging for both users and for use in infrastructure, while looking around spoke to John about his work. Out of these discussion was born the AMQP working Group with 6 initial members, under an agreement that it will be eternally be licensed for everyone to use.
+
+Since then the Working Group has had many join, and has been making solid progress working on revisions of the specification. [For more details see.|http://jira.amqp.org/confluence/display/AMQP/About+AMQP]
+
+h3. Why use AMQP?
+
+AMQP is has been designed to be able to handle the hardest workloads, scale to the largest systems, but also deal with reduction of change and maintenance costs by doing a refresh on many aged practices. The specification is also not language specific allowing the freedom from language and platform lock in, without compromise on user experience, security, scalability and consistently excellent performance.
+
+[Text mostly taken from|http://jira.amqp.org/confluence/display/AMQP/About+AMQP]
+
+h2. Qpid & AMQP
+
+
+h3. Is Qpid AMQP Compliant?
+
+Yes, Apache Qpid implements the latest AMQP specifications, providing transaction management, queuing, distribution, security, management, clustering, federation and heterogeneous multi-platform support and a lot more. And Apache Qpid is extremely fast. [Apache Qpid aims to be 100% AMQP Compliant|AMQP compatibility].
+
+h3. What Client support does Qpid have?
+
+Apache Qpid provides AMQP Client APIs for the following languages:
+* C+\+
+* C# .NET, using WCF
+* Ruby
+* Python
+* Java JMS, fully conformant with Java CTS1.1
+
+If you need another client, join the lists and ask or feel free to contribute one.
+
+h3. What messaging topologies are supported by AMQP and Qpid?
+
+AMQP provides the ability to do Point-to-Point, Peer-to-Peer, Pub-Sub, and Eventing. This allows many patterns to be craeted:
+
++*Point-to-point*+
+
+This is one of the simplest use-cases. AMQP allows for this in a few ways.
+ a.) A client can create a named queue allowing the producer to publish the message to the direct exchange with the key mapping the queue name. This will route the message to that queue.
+ b.) The above pattern can be extended by specifying a reply-to address in the published messages allowing for the consumer to reply the producer without knowing who it was send from prior to receiving the message.
+
++*One-to-many*+
+
+There are a few patterns that can be used.
+
+ a.) AMQP provides a 'fanout' exchange which will send a message to all the queues that have been bound to it. Different domains or topics are created with the 'fanout' exchange by declaring different named fan-out exchanges.
+
+ b.) A 'topic' or 'headers' exchange can also be used. in this case the pattern match is used to send the message to all the bound queues. It can be thought of as a filter allowing you to create just about any One-to-many routing patterns.
+
++*Pub-Sub*+
+
+Topic can be created with the 'topic' or other 'direct' exchange to allow consumer to bind to into the steams of data they care about. This pattern combined with the use of reply-to and Alternate-routing is the staple of what most people use messaging for today.
+
++*FAST Reliable Messaging*+
+
+AMQP 0-10 allows for fully reliable transfers between any two peers. This means that you can publish or subscribe to the broker fully reliable without requiring the need for transactions. This can all be done in async mode with the C++ broker allowing for high throughput while running entirely reliable.
+
++*Transactional*+
+
+AMQP supports two types of transactions in AMQP 0-10, TX and DTX. This allows for local (1PC), and 2PC transaction and the ability to coordinate with a TM (Transaction Manager). The Java broker supports TX, the C++ broker support TX, DTX, XA, JTA for fully ACID transactions. This allows you to commit a single unit of work with may contain enqueues & dequeues either locally on the broker, or in coordination with other transactional resource like RDBMS.
+
++*Transient message delivery*+
+
+By default messages are transient. Transient message can be sent to queues that are durable. They will not be safe stored or recovered, and will perform as any other transient message - fast!
+
++*Durable message delivery*+
+
+There is a header on each message where the message properties are specified, one of these is durability. Messages that are marked as durable and published to a durable queue will be safe stored. Durable messages will survive restart of the broker or cluster.
+
++*Federation (Hub-spoke, Trees, graphs)*+
+
+As AMQP 0-10 is symmetric for peer-to-peer communication all the building block are in place for creating networks of brokers. The C++ broker allows you to link the brokers together using 'qpid-route' and then create routes between the brokers either statically or with dynamic routes.
+
+This allows for a message to be published to one broker and consumed from another broker in the federated broker network. This feature is great to create data-center, or project isolation, but allow cross communication. It also allows networks to be created to scaled. [For more details see|Using Broker Federation]
+
++*And many others, including custom pattern*+
+
++*Message Reply, Rings, Initial Value Caches, Last Value Messaging*+
+
+All the above cases can be constructed using the AMQP and features of Qpid. For example reply can be constructed using message browsing and setting TTL on the messages. The C++ broker also support ring queues, last value queues, initial value caches on exchanges. With a bit of throught many additional patterns can be constructed.
+
+*+Store-and-forward+*
+
+Store-and-forward can be achieved by publishing to well know durable queues, that are not marked with auto delete. Consumers will be able to 'came back' to consume then at any time, even after restarts.
+
+h3. What AMQP and other exchanges does Qpid support?
+
+Both brokers support:
+ * Direct Exchange
+ * Topic Exchange
+ * Fanout Exchange
+ * Headers Exchange
+
+In additional the C++ broker support
+ * XML Exchange - Query routing
+ * Custom exchange via plug-in.
+
+Custom exchanges allow you to provide your own custom routing logic and algorithms via a plug-in. If you build an interesting exchange, please feel free to contribute it back to the Qpid project.
+
+h2. Security
+
+h3. What encryption does Qpid support?
+
+ * Qpid support SSL/TSL as per the AMQP specification.
+ * In addition the C++ broker supports Kerberos encryption of messages independent on which transport is used. Support in not yet included in all clients for this but is in process.
+
+h3. What authentication does Qpid support?
+
+SASL Authentication is supported. All Clients support PLAIN, and Kerberos support if being added to all the clients. The C++ broker support Kerberbos authentication.
+
+h3. What authorization does Qpid support?
+
+Full ACL is supported in the brokers. [For details on configuring ACL see|Qpid ACLs].
+
+ACL supports realms and allows for granular permission to be set on all the broker actions including management on an user or group basis.
+
+h3. How to setup Kerberos with the Java client
+
+You could force the java client to use kerberos auth by specifying it in the connection URL as follows.
+{code}
+amqp://guest:guest@clientid/testpath?brokerlist='tcp://localhost:5672?'&sasl_mechs='GSSAPI'
+{code}
+
+You would then need to pass in the following jvm arguments
+{code}
+-Djavax.security.auth.useSubjectCrehttp://code.google.com/p/confluence-el/dsOnly=false
+# (This will force the SASL GASSPI client to obtain the kerberos credentials explicitly instead of obtaining from the "subject" that owns the currents thread)
+-Djava.security.auth.login.config=myjas.conf (this specifies the jass config file)
+-Dsun.security.krb5.debug=true (to enable detailed debug info for troubleshooting)
+{code}
+
+Before running the java client you would need to do kinit and grab a kerberos ticket. Alternative you could set useTicketCache=false and when the client loads, it will prompt you for the user/pass and will obtain the ticket
+(You would also need to setup your kerberos environment properly -refer to doc links below).
+
+Sample JASS Config file
+{code}
+com.sun.security.jgss.initiate {
+ com.sun.security.auth.module.Krb5LoginModule required useTicketCache=true;
+};
+{code}
+
+
+h2. Semantics of Exclusive
+
+h3. I want to be able to have an exclusive consumer, but when it dies I want another to be able to pick up the queue and then block others, can this be done?
+
+Yes, Declare you queue exclusive. this will prevent anyone else from connecting to the queue. If the consumer dies the next consumer can attach to the queue by redeclaring it using the exclusive flag. Make sure not to set auto delete. Any consumer trying to declare, while a consumer is attached to the queue will receive an exception.
+
+h3. When will the queue become free for a re-declare
+
+Once the session that held the consumer is closed.
+
+
+h2. Performance
+
+h3. Does Qpid Perform (Latency/Throughput)?
+
+Yes, The Qpid C++ broker has been achieved great benchmark results in published papers by those that redistribute it. [Red Hat MRG|http://www.redhat.com/mrg] product build on Qpid has shown 760,000msg/sec ingress on an 8 way box or 6,000,000msg/sec OPRA messages.
+
+Latencies have been recored as low as 180-250us (.18ms-.3ms) for TCP round trip and 60-80us for RDMA round trip using the C++ broker.
+
+h3. How do I measure throughput?
+
+There is a great resource supplied in the C++ broker test directory called perftest. If allows you to create load on a broker for all the exchanges, multiple queues, multiple connection, coordinate multiple publishing and consuming processes, beachmark transactions and much much more such as acquire mode, txn size, message size.
+
+For all the options
+{code}
+./perftest --help
+{code}
+
+h3. How do I measure latency?
+
+There is a great resource supplied in the C++ broker test directory called latencytest. It is a loopback test that produces messages by count or at a rate, time stamps them and then consumes them back and record the latency. It supports many of the Qpid options, including the ability to vary things like frame-size.
+
+Latencies to expect round trip:
+ * 1G TCP ~ .3ms -.5ms
+ * 10G TCP - .18ms - .22ms
+ * RDMA transport - 40us - 80us
+
+Don't forget to set tune the machine and set --tcp-nodelay on both the C++ broker & client.
+
+For all the options
+{code}
+./latencytest --help
+{code}
+
+h3. How do I measure performance with Java clients?
+
+In Java we provide a utility called QpidBench. It allows you to test the performance of the native AMQP API in Java for 0-10 and the JMS API against both brokers.
+
+h3. Can I run my Java client with JAVA-RT?
+
+Yes, recently a thread abstraction layer has been added to the Java client allowing it to be used with both the SUN and IBM RT JVMs. This increases the determinism of latency when using the Java client.
+
+h3. Does Qpid support flow control?
+
+yes, AMQP 0-10 allows for flow control on the consumer and producer.
+
+h3. How do I configure producer side flow control
+
+from qpidd --help
+
+set the following in the config file on via cmd line options.
+{code}
+ --max-session-rate MESSAGES/S (0) Sets the maximum message rate per session (0=unlimited)
+{code}
+
+h2. Management
+
+h3. What Management does Qpid support
+
+The Java broker supports JMX and provides an Eclipse plug-in and command line tool to manage via JMX. The C++ broker has far more extensive management support via QMF which will be added to the Java broker in a future release.
+
+The C++ Broker supports a layered management protocol over AMQP called QMF. This allows for the management of resource either in the broker or connected to the broker via the AMQP fabric. This management includes statistics, control, eventing, and reporting/updating properties.
+
+h3. How do I manage a broker?
+
+A set of tools are provided to manage the C++ broker, they include
+ * qpid-tool - telnet type tool to access data, view schema, issue command an and QMF resource
+ * qpid-config - tool to configure queues, exchanges, etc. all the details on the AMQP model
+ * qpid-route - tool to configure broker federation
+ * qpid-events - utility that will print to cmd line or syslog event from a broker like, userconnected, user crested/deleted a queue.
+ * qpid-stats - utility that will print out queue statistics to the cmd line or syslog like rate and message depth.
+
+Then you can also access all thsi information via JMX or WS-DM (work in progress) using QMan.
+
+h3. What logging tracing and events does Qpid support?
+
+Qpid support the ability to output events from any the broker or any managed object via QMF, or to do a variety of logging from the broker & clients. for tracing options run qpidd --help.
+
+Multiple levels of of logging are supported in the C++ broker from debug, warning, error, info, etc -- all of which can be filtered.
+
+h3. Can I get to all the management data from a client?
+
+yes, All the management data is just AMQP messages on specially named queues. An API is provided for working with the management data called QMFC
+
+h3. What is QMF
+
+QMF is the layered Management protocol used to manage the C++ broker. For details on teh protocol see the Development pages.
+
+QMF allows you to manage any resource and provides the following infrsstructure:
+ * Properties
+ * Statistics
+ * Commands
+ * Events
+ * Schema for resources and versioning
+ * tools for creating agents and consuming QMF data.
+
+h3. What are QMF Agents, and what do they do for me?
+
+An Agent is any client (producer or consumer) that generates a QMF schema and registers itself to be management by QMF.
+
+A great use case of this is a consumer that is processing order from a queue can reference itself to that queue and for example provide a schema for the number or successful orders process and a method to suspend processing. Now it becomes possible to use qpid-tool to connect to the broker, see which order processors are on queue via the reference and the via the stats of the order processor client. It is also possible to issue a command to the client via qpid-tool to suspend processing. ACL in the broker can be applied to all these actions if desired.
+
+h3. What is QMFC and what does it do for mr?
+
+QMFC is the API used to consume QMF data, event and issue commands to QMF agents from an AMQP client.
+
+h3. What is QMan
+
+Qman is a tool that dynamically reads the QMF Schema information and creates JMX objects that consumed by any JMX console or application server to manage Qpid. QMan is also adding support for WS-DM management of QMF resources.
+
+
+h2. Clustering, Federation and Disaster Recovery
+
+h3. Does Qpid provide Fault Tolerance for the cluster?
+
+The C++ broker has plug-ins for Active-Active clustering which keep all the nodes of the cluster in sync. This means that any action that is performed on one of the brokers on the cluster is performed on all of them at the same time. New nodes can be added to the cluster at any time, and removed at any time with no consequences, exept for the extra multi-cast load created for the sync on joining.
+
+h3. What does the cluster guarantee?
+
+Everything! All configuration, all messages and all actions are replicated in a cluster. This means that two consumers can be connected to different nodes in the cluster and they will behave EXACTLY the same as if they where on a single broker.
+
+h3. Do clients get notified members joining or leaving the cluster?
+
+yes, All clients are updated with the addresses of node add/removed as supported by the AMQP 0-10 specification. This means that the client can dynamically track the nodes in the cluster and reconnect as required.
+
+h3. Can I specify more than one host to connect initially to the cluster to avoid single point of failure?
+
+yes, the AMQP address is multi-honed and more than one IP address can be specified at the initial connection. The client will then iterate through the host until it makes a successful connection. This feature can also be used in none clustered brokers.
+
+h3. How does Clustering work?
+
+When C++ brokers are configured into a cluster, the nodes communicate with each other over a mulitcast protocol called AIS, an open Telco multicast protocol that provides all the quorum and group services.
+
+Every action that is performed on any node of the cluster is then sequenced via totem and then performed on each node of the cluster in sync. As the cluster backbone is multicast, a separate network can be used for cluster communication and there is little impact adding additional nodes to the cluster with-in reason.
+
+h3. What is Federation?
+
+Federation provides the ability to create networks of brokers that communicate with each other in all types of typologies. This allows a producer to publish messages to one broker and someone to consume the messages from another broke somewhere on the broker federated network.
+
+[For more details see|Using Broker Federation]
+
+h3. Disater recover features are in process, Q&A will be added once they are complete.
+
+h2. Heartbeats
+
+Heartbeat can be configured to allow clients to detect when a broker has failed and connect to another broker or cluster member.Heartbeats are sent by the broker at a client specified, per-connection frequency. If the client does not receive a heartbeat or any other traffic for two heartbeat intervals, the connection will be made to fail.
+
+h3. What would happen when there is a no heartbeat within a predefined interval?
+
+If there is no traffic for two heartbeat intervals, the client will fail the connection. The application will see the exact same response as when the connection is killed.
+
+h3. What happens if the broker is unable to send heartbeat?
+
+As above, if there is no other traffic the client will eventually kill the connection.
+
+h3. Does the client retry?
+
+You can control the heartbeat interval on the client through the heartbeat member of ConnectionSettings (it is measured in seconds). Some of the options on policies do vary for different clients.
+
+h3. Failover taking too long...
+
+First check to make sure a heartbeat has been specified in the connection properties for the connection.
+
+Then make sure that the interfaces on each broker are reachable from the host you run my clients, else it will take a long time for the socket to timeout until it gets to one that can be reached.
+
+Make sure the list of URL's on the cient are the ones you want tht client to try
+
+Make sure that the broker is only exporting URL's that the client can connect to, use the --cluster-url option on the broker to specify this.
+
+h2. Threading
+
+h3. Could someone provide a brief description of the worker thread duties in the current Qpid release?
+
+The broker uses IO threads for all the work it does. This means that when work is signalled via an event (socket, RDMA, timer) an IO thread is scheduled and it runs until it completes the work and then returns back to the IO thread pool. This allows the CPUs to be utilized efficiently. The general rule is that we allocate 1 thread per core +1. So on a 8 way machine you see worker-threads default to 9. On a 4 way it will be 5. Sometimes it if work changing the default allocation if:
+
+a.) you run on high core count machine >8 to a lower number
+b.) if you taskset, then set to the cores allocated +1
+
+h3. Why was the number X chosen as the default number of worker threads?
+
+Qpidd defaults to cores + 1
+
+h3. What happens in parallel?
+
+Concurrency in the broker is at the session level. So yes. If you want more concurrency, create another session on the same connection.
+
+h3. How are worker threads allocated to individual client sessions if there are more clients than threads in the pool?
+
+They are not allocated to a specific client
+
+h2. Persistence
+
+h3. Does Qpid support persistence (durability)?
+
+Yes, there are third-party (non-Apache) modules for both C++ and Java. Historically, BDB has been used to provide persistence for both C++ and Java. However, this has created a licensing conflict with Apache, and thus the store modules are maintained off-site.
+
+The Java broker includes a fully Apache licensed persistent store that uses Derby DB.
+
+The terms _durable_ and _persistent_ are used interchangeably in this FAQ.
+
+h3. Where do I get the 3rd party persistence store modules?
+
+The 3rd party persistence store modules may be obtained through anonymous subversion at the following locations:
+
+C++: http://anonsvn.jboss.org/repos/rhmessaging/store/trunk/cpp
+Java: http://anonsvn.jboss.org/repos/rhmessaging/store/trunk/java/bdbstore
+
+For further details see [3rd Party Libraries]
+
+h3. How do I build the persistence store module from subversion checkouts?
+
++*C\+\+*+
+The README file contains detailed instructions, but here is a summary:
+ # Make sure that both the db4-devel and libaio-devel packages are installed prior to building.
+ # Make sure that qpid is built and you know the location of the qpid directory (ie the top-level directory containing the python and cpp sub-directories).
+ # In the store directory, run:
+{code}
+./bootstrap
+./configure --with-qpid-checkout=/abs/path/to/qpid/dir
+make
+{code}
+# When built, the store library *msgstore.so* will be located in the *lib/.libs* directory.
+
++*Java*+
+TODO
+
+h3. How do I use the persistence store module?
+
++*C\+\+*+
+ # Start the broker making sure that the store module is loaded, ie
+{code}
+qpidd --load-module=/path/to/msgstore.so --data-dir=/path/to/store-files ...
+{code}
+ # Make sure that queues that will handle persistent messages are set durable.
+{note:title=Note: Existing non-persistent queues cannot be made persistent}
+If a queue has been declared without persistence, doing so again with persistence enabled while the old queue still exists in the broker will be ignored. Make sure that when a queue is declared persistent, there is no non-persistent queue of the same name in existence.
+{note}
+ # For each message sent to a durable queue, make sure that it is set durable.
+
++*Java*+
+TODO
+
+h3. How do I configure the persistence store?
+
++*C\+\+*+
+
+The broker loads help information from each module. To see the help options for the store, load the store module and specify help:
+{code}
+qpidd --load-module /abs/path/to/store/lib/.libs/msgstore.so --help
+{code}
+
+Note that a set of journal files will be created for each queue declared and marked persistent. Each persistent queue has its own private journal. These are stored in the data directory by default (ie it uses the broker's *\-\-data\-dir* setting) or can be overridden with the *\-\-store\-dir* option. Note that if the broker is started with the *\-\-no\-data\-dir* option, then no store default exists, and the *\-\-store\-dir* option MUST be specified.
+
+The store file details - or "store geometry" - can be set with command-line options. These include the size and number of files that make up the journal for each queue. The *\-\-num\-jfiles* options sets the number of files to use (between 4 and 64) and the *\-\-jfile\-size\-pgs* sets the size of the file in 64kiB blocks.
+
+The size of the pages in the write page cache is set with the *\-\-wcache\-page-size* option, and sets a size in KiB. (Legal values are powers of 2, ie: 1, 2, 4, 8, 16, 32, 64, 128). Typically small page sizes give improved latency (especially for small messages), but are bad for message throughput, while large page sizes improve throughput but may cause some messages to have higher latencies.
+
++*Java*+
++Derby Store+
+For details of configuring the Derby Store see [here|Derby Store Plugin]
+
++3rd Party Stores+
+
+For details of using the 3rd party persistent modules see [here|3rd Party Libraries]
+
+
+h3. \[C++ store\] What is a RHM_IORES_ENQCAPTHRESH error?
+
+The journal ran out of space (ENQueue CAPacity THRESHold). The journal is a circular file buffer of fixed capacity set by the journal file size and number of files. When an attempt to write a record causes the journal to exceed an approx. 80% threshold, then the enqueue is rejected with this error code. Dequeues (a written record of a consumed message) may continue, however, as these free up space in the journal. Once space has been freed up, enqueues may continue as normal.
+
+This error may be caused by:
+# The journal is too small for the size and number of messages being stored. The journal must be made large enough to hold all of the messages you expect to be on the queue at any one moment (a worst-case scenario). Make the journal capacity larger through the use of the *\-\-num\-jfiles* and *\-\-jfile\-size\-pgs* parameters.
+{info:title=Rule of thumb for sizing the journal}
+Make the journal twice the size of all the messages you need to store at any one moment in time.
+{info}
+# Messages are not being dequeued (consumed) as expected. Since the store is a circular file buffer, if one un-dequeued (not consumed) message remains, it can eventually "block" the storage of new messages as the buffer gets overwritten.
+
+h3. \[C++ store\] What is the TPL? What are the \-\-tpl\-\* options for?
+The TPL stands for *Transaction Prepared List*. The store creates a single instance of a store for storing transaction boundaries called the Transaction Prepared List. Because the TPL is frequently flushed and has very different usage patterns to a normal store, it has been provided with its own set of configuration parameters:
+* *\-\-tpl\-num\-jfiles:* The number of files in the TPL journal
+* *\-\-tpl\-jfile\-size-pgs:* The file size in 64kiB blocks of the TPL journal.
+* *\-\-tpl\-wcache\-page-size:* The size of the write cache in the TPL in KiB, which is typically set a lot smaller than the average message store.
+
+h1. How To
+
+h2. C++
+
+h3. How to use RDMA with Qpid
+
+The RDMA plugin uses native OFED1.3 and puts AMQP directly onto the DMA. When using the RDMA plug-in for Qpid note the following
+* IP over IB or Fibre needs to be setup for the initial negociation
+* You need to make sure you have enough memory to pin for DMA use ulimit \-l something large
+* you might need to edit /etc/security/limits.conf first then log in again
+
+Once you have it up and running, use latencytest to make sure it is working. You should see latencies between 50 and 80us round trip.
+
+h3. Message TTL, auto expire
+
+I need to be able to set time for a message that I send to be removed from the queue if it is not read by my subscriber. For example: I enqueue a message and I want it to be automatically dequeued after a certain amount of time has passed.Is there a feature like this in qpid?
+
+yes, the TTL can be set in the message headers and the messages get dequeued if TTL expires
+
+E.g. from c++:
+{code}
+Message m("Hello World!");
+ m.getDeliveryProperties().setTtl(500);
+{code}
+Sets a 500 millisecond timeout.
+
+h3. How to install the qpid-tools for c++ broker?
+
+I see
+{code}
+[commands]$ ./qpid-queue-stats
+ Traceback (most recent call last):
+ File "./qpid-queue-stats", line 29, in
+ from qmf.console import Session, Console
+ ImportError: No module named qmf.console
+{code}
+
+This problem occurs because the PYTHONPATH environment variable does not include the location of the qpid python files. If you are running from the SVN checkout, add <path>/qpid/python to PYTHONPATH (where <path> is the location of your SVN tree). If you are installing from source, make sure you configure with the same prefix where Python is installed. This is most likely:
+
+{code}
+# configure --prefix=/usr
+# make
+# make install
+{code}
+If you are running from vendor RPMs, this should work automatically.
+
+
+h2. Java
+{children:page=Qpid Java How To}
diff --git a/qpid/doc/book/src/Getting-Started.xml b/qpid/doc/book/src/Getting-Started.xml
new file mode 100644
index 0000000000..216a52170e
--- /dev/null
+++ b/qpid/doc/book/src/Getting-Started.xml
@@ -0,0 +1,90 @@
+<chapter id="Getting-Started">
+
+<!--
+
+ 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.
+
+-->
+<title>Getting Started</title>
+<para>To get started with Apache Qpid, follow the steps below.</para>
+
+<orderedlist>
+<listitem><para>Download Apache Qpid.</para></listitem>
+<listitem>
+ <para>Start a broker. </para>
+ <itemizedlist>
+ <listitem><para><xref linkend="chapter-Running-a-Qpid-Java-Broker"/></para></listitem>
+ <listitem><para><xref linkend="section-Running-a-Qpid-CPP-Broker"/></para></listitem>
+ <listitem><para><xref linkend="chapter-Managing-CPP-Broker"/>(AMQP 0-10, works with the Qpid C++ broker)</para></listitem>
+ </itemizedlist>
+</listitem>
+<listitem>
+ <para>Run an example program from the downloaded software, or from the following URLs (these are svn URLs, which you can use to browse the examples or check them out):</para>
+ <itemizedlist>
+ <listitem><para>C++ (AMQP 0-10):</para>
+ <itemizedlist>
+ <listitem><para>Examples:</para><para><ulink url="https://svn.apache.org/repos/asf/qpid/trunk/qpid/cpp/examples/">https://svn.apache.org/repos/asf/qpid/trunk/qpid/cpp/examples/</ulink></para></listitem>
+ <listitem><para>Running the C++ Examples:</para><para><ulink url="https://svn.apache.org/repos/asf/qpid/trunk/qpid/cpp/examples/README.txt">https://svn.apache.org/repos/asf/qpid/trunk/qpid/cpp/examples/README.txt</ulink></para></listitem>
+ </itemizedlist>
+</listitem>
+<listitem>
+ <para>Java JMS (AMQP 0-10):</para>
+ <itemizedlist>
+ <listitem><para>Examples:</para><para><ulink url="https://svn.apache.org/repos/asf/qpid/trunk/qpid/java/client/example/">https://svn.apache.org/repos/asf/qpid/trunk/qpid/java/client/example/</ulink></para></listitem>
+ <listitem><para>Script for Running the Java JMS Examples </para><para><ulink url="https://svn.apache.org/repos/asf/qpid/trunk/qpid/java/client/example/src/main/java/runSample.sh">https://svn.apache.org/repos/asf/qpid/trunk/qpid/java/client/example/src/main/java/runSample.sh</ulink></para></listitem>
+ </itemizedlist>
+</listitem>
+<listitem>
+ <para>Python (AMQP 0-10):</para>
+ <itemizedlist>
+ <listitem><para>Examples:</para><para><ulink url="https://svn.apache.org/repos/asf/qpid/trunk/qpid/python/examples/">https://svn.apache.org/repos/asf/qpid/trunk/qpid/python/examples/</ulink></para></listitem>
+ <listitem><para>Running the Python Examples</para><para><ulink url="https://svn.apache.org/repos/asf/qpid/trunk/qpid/python/examples/README">https://svn.apache.org/repos/asf/qpid/trunk/qpid/python/examples/README</ulink></para></listitem>
+ </itemizedlist>
+</listitem>
+<listitem>
+ <para>Ruby (AMQP 0-10):</para>
+ <itemizedlist>
+ <listitem><para>Examples: </para><para><ulink url="https://svn.apache.org/repos/asf/qpid/trunk/qpid/ruby/examples/">https://svn.apache.org/repos/asf/qpid/trunk/qpid/ruby/examples/</ulink></para></listitem>
+ </itemizedlist>
+</listitem>
+<listitem>
+ <para>.NET (AMQP 0-10):</para>
+ <itemizedlist>
+ <listitem><para>Examples:</para><para><ulink url="http://svn.apache.org/viewvc/qpid/trunk/qpid/dotnet/client-010/examples/">http://svn.apache.org/viewvc/qpid/trunk/qpid/dotnet/client-010/examples/</ulink></para></listitem>
+ <listitem><para><xref linkend="NETUserGuide-Tutorial"/></para></listitem>
+ </itemizedlist>
+</listitem>
+</itemizedlist>
+</listitem>
+<listitem>
+ <para>Read the API Guides and Documentation</para>
+ <itemizedlist>
+ <listitem><para>C++ Client API (AMQP 0-10)</para><para><ulink url="http://qpid.apache.org/docs/api/cpp/html/index.html"></ulink></para></listitem>
+ <listitem><para><xref linkend="How-to-Use-JNDI"/></para></listitem>
+ <listitem><para>Python Client API (AMQP 0-10)</para><para><ulink url="http://qpid.apache.org/docs/api/python/html/index.html">http://qpid.apache.org/docs/api/python/html/index.html</ulink></para></listitem>
+ </itemizedlist>
+</listitem>
+<listitem>
+ <para>Get your Questions Answered</para>
+ <itemizedlist>
+ <listitem><para>Read the <xref linkend="FAQ"/></para></listitem>
+ <listitem><para>Ask a question on the user list</para><para>mailto:users-subscribe@qpid.apache.org</para></listitem>
+ </itemizedlist>
+</listitem>
+</orderedlist>
+</chapter>
diff --git a/qpid/doc/book/src/How-to-Tune-M3-Java-Broker-Performance.xml b/qpid/doc/book/src/How-to-Tune-M3-Java-Broker-Performance.xml
new file mode 100644
index 0000000000..f7fffbaceb
--- /dev/null
+++ b/qpid/doc/book/src/How-to-Tune-M3-Java-Broker-Performance.xml
@@ -0,0 +1,172 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+
+ 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.
+
+-->
+<section id="How-to-Tune-M3-Java-Broker-Performance">
+ <title>
+ How to Tune M3 Java Broker Performance
+ </title>
+ <section role="h3" id="HowtoTuneM3JavaBrokerPerformance-ProblemStatement">
+ <title>
+ Problem
+ Statement
+ </title>
+ <para>
+ During destructive testing of the Qpid M3 Java Broker, we tested
+ some tuning techniques and deployment changes to improve the Qpid
+ M3 Java Broker's capacity to maintain high levels of throughput,
+ particularly in the case of a slower consumer than produceer
+ (i.e. a growing backlog).
+ </para>
+ <para>
+ The focus of this page is to detail the results of tuning &amp;
+ deployment changes trialled.
+ </para>
+ <para>
+ The successful tuning changes are applicable for any deployment
+ expecting to see bursts of high volume throughput (1000s of
+ persistent messages in large batches). Any user wishing to use
+ these options <emphasis>must test them thoroughly in their own
+ environment with representative volumes</emphasis>.
+ </para>
+ <!--h3-->
+ </section>
+
+ <section role="h3" id="HowtoTuneM3JavaBrokerPerformance-SuccessfulTuningOptions">
+ <title>
+ Successful
+ Tuning Options
+ </title>
+ <para>
+ The key scenario being taregetted by these changes is a broker
+ under heavy load (processing a large batch of persistent
+ messages)can be seen to perform slowly when filling up with an
+ influx of high volume transient messages which are queued behind
+ the persistent backlog. However, the changes suggested will be
+ equally applicable to general heavy load scenarios.
+ </para>
+ <para>
+ The easiest way to address this is to separate streams of
+ messages. Thus allowing the separate streams of messages to be
+ processed, and preventing a backlog behind a particular slow
+ consumer.
+ </para>
+ <para>
+ These strategies have been successfully tested to mitigate this
+ problem:
+ </para>
+ <table>
+ <title/>
+ <tgroup cols="2">
+ <tbody>
+ <row>
+ <entry>
+ Strategy
+ </entry>
+ <entry>
+ Result
+ </entry>
+ </row>
+ <row>
+ <entry>
+ Seperate connections to one broker for separate streams of
+ messages.
+ </entry>
+ <entry>
+ Messages processed successfully, no problems experienced
+ </entry>
+ </row>
+ <row>
+ <entry>
+ Seperate brokers for transient and persistent messages.
+ </entry>
+ <entry>
+ Messages processed successfully, no problems experienced
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ <para>
+ <emphasis>Separate Connections</emphasis>
+ Using separate connections effectively means that the two streams
+ of data are not being processed via the same buffer, and thus the
+ broker gets &amp; processes the transient messages while
+ processing the persistent messages. Thus any build up of
+ unprocessed data is minimal and transitory.
+ </para>
+ <para>
+ <emphasis>Separate Brokers</emphasis>
+ Using separate brokers may mean more work in terms of client
+ connection details being changed, and from an operational
+ perspective. However, it is certainly the most clear cut way of
+ isolating the two streams of messages and the heaps impacted.
+ </para>
+ <section role="h4" id="HowtoTuneM3JavaBrokerPerformance-Additionaltuning">
+ <title>
+ Additional
+ tuning
+ </title>
+ <para>
+ It is worth testing if changing the size of the Qpid read/write
+ thread pool improves performance (eg. by setting
+ JAVA_OPTS="-Damqj.read_write_pool_size=32" before running
+ qpid-server). By default this is equal to the number of CPU
+ cores, but a higher number may show better performance with some
+ work loads.
+ </para>
+ <para>
+ It is also important to note that you should give the Qpid broker
+ plenty of memory - for any serious application at least a -Xmx of
+ 3Gb. If you are deploying on a 64 bit platform, a larger heap is
+ definitely worth testing with. We will be testing tuning options
+ around a larger heap shortly.
+ </para>
+ <!--h4-->
+ </section>
+ <!--h3-->
+ </section>
+
+ <section role="h3" id="HowtoTuneM3JavaBrokerPerformance-NextSteps">
+ <title>
+ Next
+ Steps
+ </title>
+ <para>
+ These two options have been testing using a Qpid test case, and
+ demonstrated that for a test case with a profile of persistent
+ heavy load following by constant transient high load traffic they
+ provide significant improvment.
+ </para>
+ <para>
+ However, the deploying project <emphasis>must</emphasis> complete their own
+ testing, using the same destructive test cases, representative
+ message paradigms &amp; volumes, in order to verify the proposed
+ mitigation options.
+ </para>
+ <para>
+ The using programme should then choose the option most applicable
+ for their deployment and perform BAU testing before any
+ implementation into a production or pilot environment.
+ </para>
+ <!--h3-->
+ </section>
+</section>
diff --git a/qpid/doc/book/src/How-to-Use-JNDI.xml b/qpid/doc/book/src/How-to-Use-JNDI.xml
new file mode 100644
index 0000000000..74506dde0f
--- /dev/null
+++ b/qpid/doc/book/src/How-to-Use-JNDI.xml
@@ -0,0 +1,175 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+
+ 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.
+
+-->
+
+<chapter id="How-to-Use-JNDI">
+ <title>
+ How to Use JNDI
+ </title>
+ <section role="h2" id="HowtoUseJNDI-HowtousethePropertiesFileInitialContextFactory">
+ <title>
+ How to use the PropertiesFileInitialContextFactory
+ </title>
+
+ <para>
+ This ContextFactory uses a java properties formatted file to
+ setup initial values.
+ </para>
+ <section role="h3" id="HowtoUseJNDI-JNDIPropertysetup">
+ <title>
+ JNDI Property setup
+ </title>
+ <para>
+ By setting the JNDI Initial Context Factory and URL as
+ below it is possible to load any File from the locally
+ mounted file system to use for JNDI purposes. The format
+ of the file is described in the next section.
+ </para>
+ <programlisting>
+java.naming.factory.initial = org.apache.qpid.jndi.PropertiesFileInitialContextFactory
+java.naming.provider.url = &lt;path to JNDI File&gt;
+</programlisting>
+ <para>
+ By simply setting these two system properties you can jump
+ straight to the InitialContext creation in your code.
+ </para>
+ </section>
+ <section role="h3" id="HowtoUseJNDI-Examplepropertiesfile">
+ <title>
+ Example properties file </title>
+ <para>
+ This is the example properties file.
+ </para>
+ <programlisting>
+# register some connection factories
+# connectionfactory.[jndiname] = [ConnectionURL]
+connectionfactory.local = amqp://guest:guest@clientid/testpath?brokerlist='vm://:1'
+
+# register some queues in JNDI using the form
+# queue.[jndiName] = [physicalName]
+queue.MyQueue = example.MyQueue
+
+# register some topics in JNDI using the form
+# topic.[jndiName] = [physicalName]
+topic.ibmStocks = stocks.nyse.ibm
+
+# Register an AMQP destination in JNDI
+# NOTE: Qpid currently only supports direct,topics and headers
+# destination.[jniName] = [BindingURL]
+destination.direct = direct://amq.direct//directQueue
+</programlisting>
+ <para>
+ The property file allows a number of queues to be defined that
+ can then be discovered via JNDI. There are four properties used
+ by the PFICFactory.
+ <emphasis>connectionfactory.&lt;jndiname&gt;</emphasis> this is the <xref linkend="Connection-URL-Format"/> that the connection
+ factory will use to perform connections.
+ <emphasis>queue.&lt;jndiname&gt;</emphasis> this defines a jms queue or in
+ amqp a amq.direct exchange
+ <emphasis>topic.&lt;jndiname&gt;</emphasis> this defines a jms topic or in
+ amqp a amq.topic exchange
+ <emphasis>destination.&lt;jndiname&gt;</emphasis> this takes a <xref linkend="BindingURLFormat"/>
+ and so can be used for defining all amq destinations, queues,
+ topics and header matching.
+ </para><para>
+ In all of these properties the <emphasis>&lt;jndiname&gt;</emphasis> is the
+ string value that would be given when performing a lookup.
+ </para><para>
+ <emphasis>NOTE</emphasis>: This does not create the queue on the broker. You
+ should ensure that you have created the queue before publishing
+ to it. Queues can be declared in the virtualhosts.xml file so
+ that they are created on broker startup, or created dynamically
+ by consuming clients. Topics and other destinations that use
+ temporary queues cannot be created in this way, so a consumer
+ must be created first before publishing messages with mandatory
+ routing.
+ </para>
+ </section>
+ <section role="h3" id="HowtoUseJNDI-Examplelookupcode">
+ <title>
+ Example lookup code
+ </title><!--h3-->
+
+ <para>
+ The <emphasis>bindingValue</emphasis> is the String that would be placed in
+ <emphasis>&lt;jndiname&gt;</emphasis> above.
+ </para>
+
+ <example>
+ <title>Simple JNDI lookup using files</title>
+ <programlisting>
+//Ensure you have your system properties set
+final String INITIAL_CONTEXT_FACTORY = "org.apache.qpid.jndi.PropertiesFileInitialContextFactory";
+
+System.setProperty(Context.INITIAL_CONTEXT_FACTORY, INITIAL_CONTEXT_FACTORY);
+System.setProperty(Context.PROVIDER_URL, _JNDIFile);
+
+// Create the initial context
+Context ctx = new InitialContext();
+
+// Perform the binds
+object = ctx.lookup(bindingValue);
+
+// Close the context when we're done
+ctx.close();
+</programlisting>
+</example>
+
+<example>
+<title>Simple JNDI lookup using properties</title>
+
+ <programlisting>
+
+final String INITIAL_CONTEXT_FACTORY = "org.apache.qpid.jndi.PropertiesFileInitialContextFactory";
+
+final String CONNECTION_JNDI_NAME = "local";
+final String CONNECTION_NAME = "amqp://guest:guest@clientid/testpath?brokerlist='vm://:1'";
+
+final String QUEUE_JNDI_NAME = "queue";
+final String QUEUE_NAME = "example.MyQueue";
+
+// Set the properties ...
+Properties properties = new Properties();
+properties.put(Context.INITIAL_CONTEXT_FACTORY, INITIAL_CONTEXT_FACTORY);
+properties.put("connectionfactory."+CONNECTION_JNDI_NAME , CONNECTION_NAME);
+properties.put("queue."+QUEUE_JNDI_NAME , QUEUE_NAME);
+
+// Create the initial context
+Context ctx = new InitialContext(properties);
+
+// Perform the lookups
+ConnectionFactory factory = (ConnectionFactory)ctx.lookup(CONNECTION_JNDI_NAME);
+Queue queue = (Queue)ctx.lookup(QUEUE_JNDI_NAME);
+
+// Close the context when we're done
+ctx.close();
+</programlisting>
+</example>
+ </section>
+
+ <section>
+ <title>Using Qpid with Other JNDI Providers</title>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="Using Qpid with other JNDI Providers.xml"/>
+ </section>
+<!--h2-->
+ </section>
+
+</chapter>
diff --git a/qpid/doc/book/src/How-to-Use-SlowConsumerDisconnect.xml b/qpid/doc/book/src/How-to-Use-SlowConsumerDisconnect.xml
new file mode 100644
index 0000000000..5f4c627430
--- /dev/null
+++ b/qpid/doc/book/src/How-to-Use-SlowConsumerDisconnect.xml
@@ -0,0 +1,280 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
+ "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd">
+<!--
+
+ 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.
+
+-->
+<section>
+ <title>Slow Consumer Disconnect - User Guide</title>
+
+ <section>
+<title>Introduction</title>
+ <para>Slow Consumer Disconnect (SCD) is a new feature in Qpid that provides a configurable
+ mechanism to prevent a single slow consumer from causing a back up of unconsumed messages on
+ the broker. </para>
+
+ <para>This is most relevant where Topics are in use, since a published message is not removed
+ from the broker's memory until all subscribers have acknowledged that message. </para>
+
+ <para>Cases where a consumer is 'slow' can arise due to one of the following: poor network
+ connectivity exists; a transient system issue affects a single client; a single subscriber
+ written by a client team is behaving incorrectly and not acknowledging messages; a
+ downstream resource such as a database is non-responsive. </para>
+
+ <para>SCD will enable the application owner to configure limits for a given consumer's queue and
+ the behaviour to execute when those limits are reached. </para>
+
+ </section>
+
+ <section>
+<title>What can it do?</title>
+ <para>SCD is only applicable to topics or durable subscriptions and can be configured on either
+ a topic or a subscription name. </para>
+
+ <para>On triggering of a specified threshold the offending client will be disconnected from the
+ broker with a 506 error code wrapped in a JMSException returned to the client via the
+ ExceptionListener registered on the Connection object. </para>
+
+ <para>Note that it is essential that an ExceptionListener be specified by the client on
+ creation of the connection and that exceptions coming back on that listener are handled
+ correctly. </para>
+
+ </section>
+
+ <section>
+<title>Frequency of SCD Checking</title>
+ <section>
+<title><emphasis role='bold'>Configuring Frequency</emphasis></title>
+ <para>You can configure the frequency with which the SCD process will check for slow consumers,
+ along with the unit of time used to specify that frequency. </para>
+
+ <para>The <emphasis role="italic">virtualhosts.virtualhost.hostname.slow-consumer-detection</emphasis>
+ elements <emphasis role="italic">delay</emphasis> and <emphasis role="italic">timeunit</emphasis>
+ are used to specify the frequency and timeunit respectively in the virtualhosts.xml
+ file e.g. </para>
+
+<programlisting>
+&lt;virtualhosts&gt;
+ &lt;default&gt;test&lt;/default&gt;
+ &lt;virtualhost&gt;
+ &lt;name&gt;test&lt;/name&gt;
+ &lt;test&gt;
+ &lt;slow-consumer-detection&gt;
+ &lt;delay&gt;60&lt;delay/&gt;
+ &lt;timeunit&gt;seconds&lt;timeunit/&gt;
+ &lt;slow-consumer-detection/&gt;
+ &lt;/test&gt;
+ &lt;/virtualhost&gt;
+&lt;/virtualhosts&gt;
+</programlisting>
+
+ </section>
+
+ <section>
+<title><emphasis role='bold'>SCD Log output</emphasis></title>
+ <para>When the SCD component finds a queue with a configured threshold to check, the operational
+ logging component (if enabled) will output the following line:</para>
+
+ <programlisting>
+ SCD-1003 : Checking Status of Queue
+ </programlisting>
+
+ </section>
+
+ </section>
+
+ <section>
+<title>Client Exception<emphasis role='bold'>s</emphasis></title>
+ <para>When a Slow Consumer is disconnected, the client receives a 506 error from the broker
+ wrapped in a JMSException and the Session and Connection are closed:</para>
+
+<programlisting>
+Dispatcher-Channel-1 2010-09-01 16:23:34,206 INFO [qpid.client.AMQSession.Dispatcher]
+ Dispatcher-Channel-1 thread terminating for channel 1:org.apache.qpid.client.AMQSession_0_8@1de8aa8
+pool-2-thread-3 2010-09-01 16:23:34,238 INFO [apache.qpid.client.AMQConnection] Closing AMQConnection due to
+ :org.apache.qpid.AMQChannelClosedException: Error: Consuming to slow. [error code 506: resource error]
+javax.jms.JMSException: 506
+at org.apache.qpid.client.AMQConnection.exceptionReceived(AMQConnection.java:1396)
+at org.apache.qpid.client.protocol.AMQProtocolHandler.exception(AMQProtocolHandler.java:329)
+at org.apache.qpid.client.protocol.AMQProtocolHandler.methodBodyReceived(AMQProtocolHandler.java:536)
+at org.apache.qpid.client.protocol.AMQProtocolSession.methodFrameReceived(AMQProtocolSession.java:453)
+at org.apache.qpid.framing.AMQMethodBodyImpl.handle(AMQMethodBodyImpl.java:93)
+at org.apache.qpid.client.protocol.AMQProtocolHandler$1.run(AMQProtocolHandler.java:462)
+at org.apache.qpid.pool.Job.processAll(Job.java:110)
+at org.apache.qpid.pool.Job.run(Job.java:149)
+at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:885)
+at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:907)
+at java.lang.Thread.run(Thread.java:619)
+Caused by: org.apache.qpid.AMQChannelClosedException: Error: Consuming to slow. [error code 506: resource error]
+at org.apache.qpid.client.handler.ChannelCloseMethodHandler.methodReceived(ChannelCloseMethodHandler.java:96)
+at org.apache.qpid.client.handler.ClientMethodDispatcherImpl.dispatchChannelClose(ClientMethodDispatcherImpl.java:163)
+at org.apache.qpid.framing.amqp_8_0.ChannelCloseBodyImpl.execute(ChannelCloseBodyImpl.java:140)
+at org.apache.qpid.client.state.AMQStateManager.methodReceived(AMQStateManager.java:112)
+at org.apache.qpid.client.protocol.AMQProtocolHandler.methodBodyReceived(AMQProtocolHandler.java:511)
+... 8 more
+main 2010-09-01 16:23:34,316 INFO [apache.qpid.client.AMQSession] Closing session:
+ org.apache.qpid.client.AMQSession_0_8@ffeef1
+</programlisting>
+
+ </section>
+
+ <section>
+<title>Disconnection Thresholds</title>
+ <section>
+<title>Topic Subscriptions</title>
+ <para>One key feature of SCD is the disconnection of a consuming client when a specified
+ threshold is exceeded. For a pub-sub model using topics, this means that messages will no
+ longer be delivered to the private queue which was associated with that consuming client,
+ thus reducing any associated backlog in the broker. </para>
+
+ </section>
+
+ <section>
+<title>Durable Topic Subscriptions</title>
+ <para>For durable subscriptions, simply disconnecting the consuming client will not suffice
+ since the associated queue is by definition durable and messages would continue to flow to
+ it after disconnection, potentially worsening any backing up of data on the broker. </para>
+
+ <para>The solution is to configure durable subscriptions to delete the underlying queue on
+ disconnection. This means that messages will no longer be delivered to the private queue
+ associated with the subscription, thus preventing any backlog. </para>
+
+ <para>Full details of how to configure the thresholds are provided below. </para>
+
+ </section>
+
+ <section>
+<title>Message Age Threshold</title>
+ <para>You can configure SCD to be triggered on a topic or subscription when the oldest message
+ in the associated private queue for the consumer ages beyond the specified value, in
+ milliseconds. </para>
+
+ </section>
+
+ <section>
+<title>Queue Depth Threshold</title>
+ <para>You can opt to use the depth of the queue in bytes as a threshold. SCD will be triggered
+ by a queue depth greater than the threshold specified i.e. when a broker receives a
+ message that takes the queue depth over the threshold. </para>
+
+ </section>
+
+ <section>
+<title>Message Count Threshold</title>
+ <para>You can use the message count for the consumer's queue as the trigger, where a count
+ higher than that specified will trigger disconnection. </para>
+
+ </section>
+
+ <section>
+<title><emphasis role='bold'>Delete Policy</emphasis></title>
+ <para>You can configure the policy you wish to apply in your broker configuration. There are
+ currently 2 policies available: </para>
+
+ <para>
+<emphasis role='bold'>Delete Temporary Queues Only</emphasis>
+ </para>
+
+ <para>If you do not specify a &lt;topicDelete/&gt; element in your configuration, then only temporary
+ queues associated with a topic subscription will be deleted on client disconnect. This is
+ the default behaviour. </para>
+ <para/>
+
+ <para>
+<emphasis role='bold'>Delete Durable Subscription Queues</emphasis>
+ </para>
+
+ <para>If you add the &lt;topicDelete/&gt; element with the sub-element
+ &lt;delete-persistent/&gt; to your config, then the persistent queue which is associated
+ with durable subscriptions to a topic will also be deleted. This is an important
+ consideration since without deleting the underlying queue the client's unconsumed data
+ will grow indefinitely while they will be unable to reconnect to that queue due to the SCD
+ threshold configured, potentially having an adverse effect on the application or broker in
+ use.</para>
+ <para/>
+
+ <para><emphasis role="bold"> Example Topic Configuration </emphasis></para>
+
+ <para/>
+
+ <para>
+The following steps are required to configure SCD:
+ </para>
+
+<itemizedlist>
+ <listitem>
+ <para>Enable SCD checking for your virtual host</para>
+ </listitem>
+ <listitem>
+ <para>Specify frequency for SCD checking</para>
+ </listitem>
+ <listitem>
+ <para>Define thresholds for the topic</para>
+ </listitem>
+ <listitem>
+ <para>Define the policy to apply on trigger </para>
+ </listitem>
+</itemizedlist>
+
+ <para>The example below shows a simple definition, with all three thresholds specified and a
+ simple disconnection, with deletion of any temporary queue, defined. </para>
+
+ <para>For a durable subscription to this topic, no queue deletion would be applied on disconnect
+ - which is likely to be undesirable (see section above). </para>
+
+<programlisting>
+&lt;topics&gt;
+ &lt;topic&gt;
+ &lt;name&gt;stocks.us.*&lt;/name&gt;
+ &lt;slow-consumer-detection&gt;
+ &lt;!-- The maximum depth before which --&gt;
+ &lt;!-- the policy will be applied--&gt;
+ &lt;depth&gt;4235264&lt;/depth&gt;
+ &lt;!-- The maximum message age before which --&gt;
+ &lt;!-- the policy will be applied--&gt;
+ &lt;messageAge&gt;600000&lt;/messageAge&gt;
+ &lt;!-- The maximum number of message before --&gt;
+ &lt;!-- which the policy will be applied--&gt;
+ &lt;messageCount&gt;50&lt;/messageCount&gt;
+ &lt;!-- Policy Selection --&gt;
+ &lt;policy name="TopicDelete"/&gt;
+ &lt;/slow-consumer-detection&gt;
+ &lt;/topic&gt;
+&lt;/topics&gt;
+</programlisting>
+
+ </section>
+
+ </section>
+
+ <section>
+<title>Important Points To Note</title>
+ <para> Client application developers should be educated about how to correctly handle being
+ disconnected with a 506 error code, to avoid them getting into a thrashing state where they
+ continually attempt to connect, fail to consume fast enough and are disconnected again. </para>
+
+ <para>Clients affected by slow consumer disconnect configuration should always use transactions
+ where duplicate processing of an incoming message would have adverse affects, since they may
+ receive a message more than once if disconnected before acknowledging a message in flight. </para>
+
+ </section>
+
+ </section>
+
diff --git a/qpid/doc/book/src/InfoPlugin.xml b/qpid/doc/book/src/InfoPlugin.xml
new file mode 100644
index 0000000000..aebcd08c02
--- /dev/null
+++ b/qpid/doc/book/src/InfoPlugin.xml
@@ -0,0 +1,261 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+
+ 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.
+
+-->
+
+<section xmlns="http://docbook.org/ns/docbook" version="5.0">
+<title>
+OSGI Info Plugin
+</title>
+ <para> The Info OSGI Plugin was developed as a mean of monitoring the qpid broker startup/shutdown
+ times along with selected JVM and OS details. It was written as a OSGI plugin so it can be
+ used as needed. </para>
+
+
+<section>
+ <title>How it works</title>
+ <para> Assuming the plugin is deployed, upon the Activator invocation (which happens when OSGI
+ loads the bundles), the plugin looks for its configuration file. If the file cannot be
+ found, the plugin does not perform any operation and will silently exit. If the
+ configuration is found, it is loaded and parsed. A predefined set of data is collected and
+ messages are generated as per the configuration templates (see below for details).</para>
+ <para> Further, the messages are sent using one of the supported protocols (currently http
+ post and soap) to the configured destination. The same scenario takes place on the plugin
+ unload phase which usually takes place upon broker shutdown. </para>
+</section>
+
+<section>
+ <title>Data Gathering</title>
+ <para>
+The info plugin collects a pre-defined set of data, and generates a message according to a template
+defined in each section of the ini file. Data can be of 2 categories:
+<orderedlist numeration="loweralpha" spacing="normal">
+ <listitem>
+ <para>JVM specific</para>
+ </listitem>
+ <listitem>
+ <para>application specific</para>
+ </listitem>
+ </orderedlist>
+ </para>
+ <para>
+Each data has a variable name associated which can be used for the message generation template.
+The convention chosen for template is: @[variable (in uppercase)] (eg @IP, @PORT) (see configuration section
+for message examples).
+</para>
+<para>
+The following application specific info are gathered (variable names in round brackets):
+
+ <orderedlist numeration="arabic" spacing="normal">
+ <listitem>
+ <para>The JMX Port the application is listening to (jmxport)</para>
+ </listitem>
+ <listitem>
+ <para>The Port(s) the broker is listening to, comma delimited (port)</para>
+ </listitem>
+ <listitem>
+ <para>The Broker Version (version)</para>
+ </listitem>
+ <listitem>
+ <para>The key store path (KeystorePath)</para>
+ </listitem>
+ <listitem>
+ <para>The Plugin Directory (PluginDirectory)</para>
+ </listitem>
+ <listitem>
+ <para>The QPID work directory (QpidWork)</para>
+ </listitem>
+ <listitem>
+ <para>The JMX Principal Database (JMXPrincipalDatabase)</para>
+ </listitem>
+</orderedlist>
+</para>
+ <para>
+The following JVM specific info are collected (variable names in round brackets):
+
+ <orderedlist numeration="arabic" spacing="normal">
+ <listitem>
+ <para>Hostname (hostname)</para>
+ </listitem>
+ <listitem>
+ <para>IP address of the current machine (ip)</para>
+ </listitem>
+ <listitem>
+ <para>Number of CPU cores (CPUCores)</para>
+ </listitem>
+ <listitem>
+ <para>Maximum memory (Maximum_Memory)</para>
+ </listitem>
+ <listitem>
+ <para>Free Memory (Free_Memory)</para>
+ </listitem>
+ <listitem>
+ <para>Java Class Path (java.class.path)</para>
+ </listitem>
+ <listitem>
+ <para>Jave Home (java.home)</para>
+ </listitem>
+ <listitem>
+ <para>Java VM Name (java.vm.name)</para>
+ </listitem>
+ <listitem>
+ <para>Java VM Vendor (java.vm.vendor)</para>
+ </listitem>
+ <listitem>
+ <para>Java VM Version (java.vm.version)</para>
+ </listitem>
+ <listitem>
+ <para>Java Class Version (java.class.version)</para>
+ </listitem>
+ <listitem>
+ <para>Java Runtime Version (java.runtime.version)</para>
+ </listitem>
+ <listitem>
+ <para>OS Architecture (os.arch)</para>
+ </listitem>
+ <listitem>
+ <para>Sun Architecture Data Model (sun.arch.data.model)</para>
+ </listitem>
+ <listitem>
+ <para>User home directory (user.home)</para>
+ </listitem>
+ <listitem>
+ <para>User Name (user.name)</para>
+ </listitem>
+ <listitem>
+ <para>User Time Zone (user.timezone)</para>
+ </listitem>
+ </orderedlist>
+</para>
+</section>
+
+
+<section>
+ <title>Plugin Configuration</title>
+<para>
+The plugin configuration file is currently hardcoded to be: $QPID_HOME/etc/qpidinfo.ini
+We plan to provide a mean to change the configuration by using system property (eg -DInfoPluginConfig) but
+currently this is not available.
+</para>
+<para>
+As it might be useful to send more than 1 message, eventually to different destinations,
+we chose an ini file layout for the plugin configuration that consists of a global section
+and set of individual sections, one for each message to be sent.
+</para>
+ <para>
+ The configuration file has a global section composed of any key-value pairs placed before the start
+ of an ini-type section (eg [section]). The role of the global section is to provide a set of values
+ that would be inferred in each subsequent section. Any section from the config file can override any
+ global variable by specifying the respective key-value pair inside.
+ </para>
+ <para> The key protocol is mandatory, the plugin will not work if protocol=soap or protocol=http is
+ not specified. For soap, we expect the following keys to be present: <itemizedlist>
+ <listitem>
+ <para>soap.hostname</para>
+ </listitem>
+ <listitem>
+ <para>soap.port</para>
+ </listitem>
+ <listitem>
+ <para>soap.path</para>
+ </listitem>
+ <listitem>
+ <para>soap.envelope</para>
+ </listitem>
+ </itemizedlist> For http the following keys have to be present: <itemizedlist>
+ <listitem>
+ <para>http.url</para>
+ </listitem>
+ <listitem>
+ <para>http.envelope</para>
+ </listitem>
+ </itemizedlist> The names are self-explanatory, please see the example below. The protocol
+ key cannot be overwritten in the sections and it has to be chosen initially. </para>
+ </section>
+
+<section><title>Example Configuration</title>
+ <para>
+For soap messages, we will abbreviate the XML header by omitting the namespaces in the config,
+in order to be more readable. A minimal correct XML for the soap envelope would be
+ <programlisting>
+ <![CDATA[
+ <?xml version=\"1.0\"?>
+ <soap:Envelope
+ xmlns:soap=\"http://www.w3.org/2001/12/soap-envelope\"
+ soap:encodingStyle=\"http://www.w3.org/2001/12/soap-encoding\">
+ ...some content...
+ </soap:Envelope>
+ ]]>
+ </programlisting>
+
+ NB. On the ini file, there can be no text wrapping for any entry (as above), the whole text should come into
+ a single line, irrespective of how long it is.
+
+ </para>
+
+<programlisting>
+<![CDATA[
+## Ini file using SOAP
+protocol=soap
+soap.hostname=host1
+soap.port=8080
+
+[Message1]
+soap.path=/axis2/services/QpidInfo
+soap.action=qpidevent
+soap.envelope=<?xml version=\"1.0\"?><soap:Envelope>@ACTION-@VERSION</soap:Envelope>
+
+[Message2]
+soap.hostname=host2
+soap.port=9090
+soap.path=/axis1/services/Info
+soap.envelope=<?xml version=\"1.0\"?><soap:Envelope">@ACTION-@VERSION from @IP:@PORT</soap:Envelope>
+
+## End of File
+]]>
+</programlisting>
+
+<para>
+and another example, this time using http:
+
+<programlisting>
+<![CDATA[
+protocol=http
+http.url=http://mywebserver:8080/postServlet
+
+[Message1]
+http.envelope=Event from qpid broker at: @IP, running qpid version: @VERSION
+
+[Message2]
+http.url=http://myotherwebserver:9090/postServlet1
+http.envelope=Event for qpid broker @VERSION from @IP:@PORT running java @JAVA.VM.VERSION
+]]>
+</programlisting>
+ </para>
+ <para>
+ The ini file is supporting comments starting with # or ; anywhere in the file.
+ The global section is considered to be the first set of lines from the ini file before the first [Section] encountered.
+ </para>
+ </section>
+
+</section>
+
+
+
diff --git a/qpid/doc/book/src/Introduction.xml b/qpid/doc/book/src/Introduction.xml
new file mode 100644
index 0000000000..8f92c207cf
--- /dev/null
+++ b/qpid/doc/book/src/Introduction.xml
@@ -0,0 +1,106 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+
+ 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.
+
+-->
+
+<chapter>
+
+<title>Apache Qpid: Open Source AMQP Messaging</title>
+
+<para>Enterprise Messaging systems let programs communicate by exchanging messages, much as people communicate by exchanging email. Unlike email, enterprise messaging systems provide guaranteed delivery, speed, security, and freedom from spam. Until recently, there was no open standard for Enterprise Messaging systems, so programmers either wrote their own, or used expensive proprietary systems.</para>
+
+<para>AMQP Advanced Message Queuing Protocol is the first open standard for Enterprise Messaging. It is designed to support messaging for just about any distributed or business application. Routing can be configured flexibly, easily supporting common messaging paradigms like point-to-point, fanout, publish-subscribe, and request-response.</para>
+
+<para>Apache Qpid implements the latest AMQP specification, providing transaction management, queuing, distribution, security, management, clustering, federation and heterogeneous multi-platform support and a lot more. And Apache Qpid is extremely fast. Apache Qpid <ulink url="### FIX ME ###">aims to be 100% AMQP Compliant</ulink>.</para>
+
+<section>
+<title>AMQP Messaging Brokers</title>
+
+<para>Qpid provides two AMQP messaging brokers:</para>
+
+<itemizedlist>
+ <listitem><para>Implemented in C++ - high performance, low latency, and RDMA support.</para></listitem>
+ <listitem><para>Implemented in Java - Fully JMS compliant, runs on any Java platform.</para></listitem>
+</itemizedlist>
+
+<para>Both AMQP messaging brokers support clients in multiple languages, as long as the messaging client and the messaging broker use the same version of AMQP. See <ulink url="### FIX ME ###">Download</ulink> to see which messaging clients work with each broker.</para>
+
+</section>
+
+<section>
+<title>AMQP Client APIs: C++, Java, JMS, Ruby, Python, and C#</title>
+
+<para>Qpid provides AMQP Client APIs for the following languages:</para>
+
+<itemizedlist>
+ <listitem><para>C++</para></listitem>
+ <listitem><para>Java, fully conformant with JMS 1.1</para></listitem>
+ <listitem><para>C# .NET, 0-10 using WCF</para></listitem>
+ <listitem><para>Ruby</para></listitem>
+ <listitem><para>Python</para></listitem>
+</itemizedlist>
+
+</section>
+
+<section>
+<title>Operating Systems and Platforms:</title>
+
+<para>The Qpid C++ broker runs on the following operating systems:</para>
+
+<itemizedlist>
+ <listitem><para>Linux systems</para></listitem>
+ <listitem><para>Windows</para></listitem>
+ <listitem><para>Solaris (coming soon)</para></listitem>
+</itemizedlist>
+
+<para>The Qpid Java broker runs on:</para>
+
+<itemizedlist>
+ <listitem><para>Any Java platform</para></listitem>
+</itemizedlist>
+
+<para>Qpid clients can be run on the following operating systems and platforms:</para>
+
+<itemizedlist>
+ <listitem><para>Java:</para>
+ <itemizedlist>
+ <listitem><para>any platform, production proven on Windows, Linux, Solaris</para></listitem>
+ </itemizedlist>
+ </listitem>
+
+
+ <listitem><para>C++:</para>
+ <itemizedlist>
+ <listitem><para>Linux</para></listitem>
+ <listitem><para>Windows</para></listitem>
+ <listitem><para>Solaris (coming soon)</para></listitem>
+ </itemizedlist>
+ </listitem>
+
+ <listitem><para>C#</para>
+ <itemizedlist>
+ <listitem><para>.NET</para></listitem>
+ </itemizedlist>
+ </listitem>
+
+</itemizedlist>
+
+</section>
+</chapter>
diff --git a/qpid/doc/book/src/Java-Broker-Feature-Guide.xml b/qpid/doc/book/src/Java-Broker-Feature-Guide.xml
new file mode 100644
index 0000000000..bbc2a1aaf0
--- /dev/null
+++ b/qpid/doc/book/src/Java-Broker-Feature-Guide.xml
@@ -0,0 +1,84 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+
+ 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.
+
+-->
+
+<section>
+ <title>
+ Java Broker Feature Guide
+ </title>
+ <section role="h3" id="JavaBrokerFeatureGuide-TheQpidpureJavabrokercurrentlysupportsthefollowingfeatures-3A">
+ <title>
+ The Qpid pure Java broker currently supports the following
+ features:
+ </title>
+ <itemizedlist>
+ <listitem><para>All features required by the Sun JMS 1.1 specification, fully
+ tested
+ </para></listitem>
+ <listitem><para>Transaction support
+ </para></listitem>
+ <listitem><para>Persistence using a pluggable layer
+ </para></listitem>
+ <listitem><para>Pluggable security using SASL
+ </para></listitem>
+ <listitem><para>Management using JMX and an Eclipse Management Console
+ application
+ </para></listitem>
+ <listitem><para>High performance header-based routing for messages
+ </para></listitem>
+ <listitem><para>Message Priorities
+ </para></listitem>
+ <listitem><para>Configurable logging and log archiving
+ </para></listitem>
+ <listitem><para>Threshold alerting
+ </para></listitem>
+ <listitem><para>ACLs
+ </para></listitem>
+ <listitem><para>Extensively tested on each release, including performance
+ &amp; reliability testing
+ </para></listitem>
+ <listitem><para>Automatic client failover using configurable connection
+ properties
+ </para></listitem>
+ <listitem><para>Durable Queues/Subscriptions
+ </para></listitem>
+ </itemizedlist>
+ <section role="h3" id="JavaBrokerFeatureGuide-Upcomingfeatures-3A">
+ <title>
+ Upcoming
+ features:
+ </title>
+ <itemizedlist>
+ <listitem><para>Flow To Disk
+ </para></listitem>
+ <listitem><para>IP Whitelist
+ </para></listitem>
+ <listitem><para>AMQP 0-10 Support (for interoperability)
+ </para></listitem>
+ </itemizedlist>
+
+ <!--h3-->
+ </section>
+
+ <!--h3-->
+ </section>
+
+</section>
diff --git a/qpid/doc/book/src/Java-Broker-StatusLogMessages.xml b/qpid/doc/book/src/Java-Broker-StatusLogMessages.xml
new file mode 100644
index 0000000000..e905f9ff10
--- /dev/null
+++ b/qpid/doc/book/src/Java-Broker-StatusLogMessages.xml
@@ -0,0 +1,294 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ 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.
+
+-->
+<?oxygen RNGSchema="http://www.oasis-open.org/docbook/xml/5.0/rng/docbook.rng" type="xml"?>
+<book xmlns="http://docbook.org/ns/docbook"
+ xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0">
+ <info>
+ <title>Operational Logging</title>
+ <author>
+ <orgname>Apache Software Foundation</orgname>
+ </author>
+ </info>
+ <chapter>
+ <title>Status Log Messages</title>
+ <para>This file was derivied from LogMessages used within the Java Broker and originally defined on:
+ <tag xlink:href="http://cwiki.apache.org/confluence/display/qpid/Status+Update+Design#StatusUpdateDesign-InitialStatusMessages">Apache Wiki</tag></para>
+ <sect1>
+ <title>Technical Notes:</title>
+ <para>The status log messages file is a standard Java Properties file so white space is respected at the end of
+ the lines. This file could be processed in a number of ways:</para>
+ <para>
+ <orderedlist>
+ <listitem>
+ <para>ResourceBundle</para>
+ <para>This file is loaded as a ResourceBundle. The en_US addition to the
+ file is the localisation. Additional localisations can be provided and
+ will automatically be selected based on the &lt;locale> value in the
+ config.xml. The default locale is en_US.</para>
+ </listitem>
+ <listitem>
+ <para>MessageFormat</para>
+ <para> Each entry is prepared with the Java Core MessageFormat methods.
+ Therefore most functionality you can do via MessageFormat can be done
+ here: </para>
+ <para><tag xlink:href="http://java.sun.com/javase/6/docs/api/java/text/MessageFormat.html">Java API for MessageFormat</tag></para>
+ <para>The caveat here is that only default String and number FormatTypes can
+ be used. This is due to the processing described in 3 below. If support
+ for date, time or choice is required then the GenerateLogMessages class
+ should be updated to provide support.</para>
+ </listitem>
+ <listitem>
+ <para>GenerateLogMessage/Velocity Macro</para>
+ <para>This is the only processing that this file goes through</para>
+ <orderedlist>
+ <listitem>
+ <para>Class Generation:</para>
+ <para>The GenerateLogMessage processes this file and uses the
+ velocity Macro to create classes with static methods to perform
+ the logging and give us compile time validation. </para>
+ </listitem>
+ <listitem>
+ <para>Property Processing</para>
+ <para>During the class generation the message properties ({x}) are
+ identified and used to create the method signature.</para>
+ </listitem>
+ <listitem>
+ <para>Option Processing</para>
+ <para>The Classes perform final formatting of the messages at
+ runtime based on optional parameters that are defined within the
+ message. Optional parameters are enclosed in square brackets
+ e.g. [optional].</para>
+ </listitem>
+ </orderedlist>
+ </listitem>
+ </orderedlist>
+ </para>
+ <para><emphasis role="bold">Format Note:</emphasis></para>
+ <para> As mentioned earlier white space in this file is very important. One thing in
+ particular to note is the way MessageFormat performs its replacements. The
+ replacement text will totally replace the {xxx} section so there will be no addition
+ of white space or removal e.g. </para>
+ <programlisting><![CDATA[MSG = Text----{0}----]]>
+ </programlisting>
+ <para> When given parameter 'Hello' result in text: </para>
+ <programlisting><![CDATA[Text----Hello----]]>
+ </programlisting>
+ <para>For simple arguments this is expected however when using Style formats then it can
+ be a little unexpected. In particular a common pattern is used for number
+ replacements : {0,number,}. This is used in the Broker to display an Integer simply
+ as the Integer with no formatting. e.g new Integer(1234567) becomes the String
+ "1234567" which is can be contrasted with the pattern without a style format field :
+ {0,number} which becomes string "1,234,567".</para>
+ <para>What you may not expect is that {0,number, } would produce the String " 1234567"
+ note that the space after the ',' here has resulted in a space in front of the
+ number in the output.</para>
+ <para>More details on the SubformatPattern can be found on the API link above. To
+ provide fixed log messages as required by the Technical Specification:</para>
+ <para><tag xlink:href="http://cwiki.apache.org/confluence/display/qpid/Operational+Logging+-+Status+Update+-+Technical+SpecificationOperationalLogging-StatusUpdate-TechnicalSpecification-Howtoprovidefixedlogmessages">Operational Logging Tech Specification</tag></para>
+ <para>This file is processed by Velocity to create a number of classes that contain
+ static methods that provide LogMessages in the code to provide compile time
+ validation.</para>
+ <para>For details of what processing is done see GenerateLogMessages. </para>
+ <para>What a localiser or developer need know is the following: </para>
+ <para>The Property structure is important as it defines how the class and methods will
+ be built.</para>
+ </sect1>
+ <sect1>
+ <title>Class Generation</title>
+ <para> Each class of messages will be split in to their own &lt;Class>Messages.java.
+ Each logmessage file contains only one class of messages the &lt;Class> name is
+ derived from the name of the logmessages file e.g. &lt;Class&gt;_logmessages.properties.
+ </para>
+ </sect1>
+ <sect1>
+ <title>Property Format</title>
+ <para>The property format MUST adhere to the follow format to make it easier to use the
+ logging API as a developer but also so that operations staff can easily locate log
+ messages in the output.</para>
+ <para>The property file should contain entries in the following format:</para>
+ <programlisting><![CDATA[<Log Identifier,developer focused>=<Log Identifier,Operate focus>:<Log Message>]]>
+ </programlisting>
+
+ <para>eg:</para>
+ <programlisting><![CDATA[SHUTTING_DOWN = BRK-1003 : Shutting down : {0} port {1,number,}]]>
+ </programlisting>
+
+ <para>Note: the developer focused identifier will become a method name so only a valid
+ method name should be used. Currently only '-' are converted to '_'.</para>
+ <para>That said properties generate the logging code at build time so any error can be
+ easily identified.</para>
+ <para>The three character identifier show above in BRK-1003 should ideally be unique.
+ This is the only requirement, limiting to 3 characters is not required.</para>
+ <para>The current broker contains the following mappings:</para>
+ <para>
+ <table>
+ <title>Status Messages Mapping</title>
+ <tgroup cols="2">
+ <colspec colname="c1" colnum="1" colwidth="118.29pt"/>
+ <colspec colname="c2" colnum="2" colwidth="135.18pt"/>
+ <thead>
+ <row>
+ <entry>Class</entry>
+ <entry> Type</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>Broker</entry>
+ <entry>BRK</entry>
+ </row>
+ <row>
+ <entry>Management Console</entry>
+ <entry>MNG</entry>
+ </row>
+ <row>
+ <entry>VirtualHost</entry>
+ <entry>VHT</entry>
+ </row>
+ <row>
+ <entry>MessageStore</entry>
+ <entry>MST</entry>
+ </row>
+ <row>
+ <entry>ConfigStore</entry>
+ <entry>CFG</entry>
+ </row>
+ <row>
+ <entry>TransactionLog</entry>
+ <entry>TXN</entry>
+ </row>
+ <row>
+ <entry>Connection</entry>
+ <entry>CON</entry>
+ </row>
+ <row>
+ <entry>Channel</entry>
+ <entry>CHN</entry>
+ </row>
+ <row>
+ <entry>Queue</entry>
+ <entry>QUE</entry>
+ </row>
+ <row>
+ <entry>Exchange</entry>
+ <entry>EXH</entry>
+ </row>
+ <row>
+ <entry>Binding</entry>
+ <entry>BND</entry>
+ </row>
+ <row>
+ <entry>Subscription</entry>
+ <entry>SUB</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </para>
+ </sect1>
+ <sect1>
+ <title>Property Processing</title>
+ <para>
+ Each property is then processed by the GenerateLogMessages class to identify
+ the number and type of parameters, {x} entries. Parameters are defaulted to
+ String types but the use of FormatType number (e.g.{0,number}) will result
+ in a Number type being used. These parameters are then used to build the
+ method parameter list. e.g:
+ </para>
+
+ <para>Property:</para>
+ <programlisting><![CDATA[SHUTTING_DOWN = BRK-1003 : Shuting down : {0} port {1,number,}]]></programlisting>
+ <para>becomes Method:</para>
+ <programlisting><![CDATA[public static LogMessage SHUTTING_DOWN(String param1, Number param2)]]>
+ </programlisting>
+
+ <para>
+ This improves our compile time validation of log message content and
+ ensures that change in the message format does not accidentally cause
+ erroneous messages.</para>
+ </sect1>
+ <sect1>
+ <title>Option Processing</title>
+ <para>
+ Options are identified in the log message as being surrounded by square
+ brackets ([ ]). These optional values can themselves contain parameters
+ however nesting of options is not permitted. Identification is performed on
+ first matching so given the message:
+ </para>
+ <programlisting><![CDATA[Msg = Log Message [option1] [option2] ]]></programlisting>
+ <para>
+ Two options will be identified and enabled to select text 'option1' and
+ 'option2'.
+ </para>
+ <para>
+ The nesting of a options is not supported and will provide
+ unexpected results. e.g. Using Message:
+ </para>
+ <programlisting><![CDATA[Msg = Log Message [option1 [sub-option2]] ]]></programlisting>
+ <para>
+ The options will be 'option1 [sub-option2' and 'sub-option2'. The first
+ option includes the second option as the nesting is not detected.
+ </para>
+ <para>
+ The detected options are presented in the method signature as boolean options
+ numerically identified by their position in the message. e.g.
+ Property:
+ </para>
+ <programlisting><![CDATA[ CON-1001 = Open : Client ID {0} [: Protocol Version : {1}] ]]></programlisting>
+ <para>becomes Method:</para>
+ <programlisting><![CDATA[ public static LogMessage CON_1001(String param1, String param2, boolean opt1) ]]></programlisting>
+ <para>
+ The value of 'opt1' will show/hide the option in the message. Note that
+ 'param2' is still required however a null value can be used if the optional
+ section is not desired.
+ </para>
+ <para>
+ Again here the importance of white space needs to be highlighted.
+ Looking at the QUE-1001 message as an example. The first thought on how this
+ would look would be as follows:
+ </para>
+ <programlisting><![CDATA[ QUE-1001 = Create : Owner: {0} [AutoDelete] [Durable] [Transient] [Priority: {1,number,}] ]]></programlisting>
+ <para>
+ Each option is correctly defined so the text that is defined will appear when
+ selected. e.g. 'AutoDelete'. However, what may not be immediately apparent is
+ the white space. Using the above definition of QUE-1001 if we were to print
+ the message with only the Priority option displayed it would appear as this:
+ </para>
+ <programlisting><![CDATA[ "Create : Owner: guest Priority: 1" ]]></programlisting>
+ <para>
+ Note the spaces here in between gues and Priority are present because only the text between the brackets
+ has been removed.
+ </para>
+ <para>
+ Each option needs to include white space to correctly format the message. So
+ the correct definition of QUE-1001 is as follows:
+ </para>
+ <programlisting><![CDATA[ QUE-1001 = Create : Owner: {0}[ AutoDelete][ Durable][ Transient][ Priority: {1,number,}] ]]></programlisting>
+ <para>
+ Note that white space is included with each option and there is no extra
+ white space between the options. As a result the output with just Priority
+ enabled is as follows:
+ </para>
+ <programlisting><![CDATA[ "Create : Owner: guest Priority: 1" ]]></programlisting>
+ </sect1>
+ </chapter>
+</book>
diff --git a/qpid/doc/book/src/Java-Environment-Variables.xml b/qpid/doc/book/src/Java-Environment-Variables.xml
new file mode 100644
index 0000000000..e4da38a260
--- /dev/null
+++ b/qpid/doc/book/src/Java-Environment-Variables.xml
@@ -0,0 +1,84 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+
+ 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.
+
+-->
+
+<section>
+ <title>
+ Java Environment Variables
+ </title>
+ <section role="h2" id="JavaEnvironmentVariables-SettingQpidEnvironmentVariables">
+ <title>
+ Setting
+ Qpid Environment Variables
+ </title>
+
+ <section role="h3" id="JavaEnvironmentVariables-QpidDeploymentPathVariables">
+ <title>
+ Qpid
+ Deployment Path Variables
+ </title>
+ <para>
+ There are two main Qpid environment variables which are required
+ to be set for Qpid deployments, QPID_HOME and QPID_WORK.
+ </para>
+ <para>
+ QPID_HOME - This variable is used to tell the Qpid broker where
+ it's installed home is, which is in turn used to find dependency
+ JARs which Qpid uses.
+ </para>
+ <para>
+ QPID_WORK - This variable is used by Qpid when creating all
+ 'writeable' directories that it uses. This includes the log
+ directory and the storage location for any BDB instances in use
+ by your deployment (if you're using persistence with BDB). If you
+ do not set this variable, then the broker will default (in the
+ qpid-server script) to use the current user's homedir as the root
+ directory for creating the writeable locations that it uses.
+ </para>
+
+ <!--h3-->
+ </section>
+
+ <section role="h3" id="JavaEnvironmentVariables-SettingMaxMemoryforthebroker">
+ <title>
+ Setting
+ Max Memory for the broker
+ </title>
+ <para>
+ If you simply start the Qpid broker, it will default to use a
+ -Xmx setting of 1024M for the broker JVM. However, we would
+ recommend that you make the maximum -Xmx heap size available, if
+ possible, of 3Gb (for 32-bit platforms).
+ </para>
+ <para>
+ You can control the memory setting for your broker by setting the
+ QPID_JAVA_MEM variable before starting the broker e.g. -Xmx3668m
+ . Enclose your value within quotes if you also specify a -Xms
+ value. The value in use is echo'd by the qpid-server script on
+ startup.
+ </para>
+ <!--h3-->
+ </section>
+
+ <!--h2-->
+ </section>
+
+</section>
diff --git a/qpid/doc/book/src/Java-JMS-Selector-Syntax.xml b/qpid/doc/book/src/Java-JMS-Selector-Syntax.xml
new file mode 100644
index 0000000000..870e277b66
--- /dev/null
+++ b/qpid/doc/book/src/Java-JMS-Selector-Syntax.xml
@@ -0,0 +1,96 @@
+<!--
+ -
+ - 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.
+ -
+ -->
+<section>
+ <title>Java JMS Selector Syntax</title>
+ <para>The AMQP Java JMS Messaging Client supports the following syntax for JMS selectors.</para>
+
+<programlisting><![CDATA[
+Comments:
+
+ LINE_COMMENT: "--" (~["\n","\r"])* EOL
+ EOL: "\n"|"\r"|"\r\n"
+ BLOCK_COMMENT: "/*" (~["*"])* "*" ("*" | (~["*","/"] (~["*"])* "*"))* "/"
+
+Reserved Words (case insensitive):
+
+ NOT: "NOT"
+ AND: "AND"
+ OR: "OR"
+ BETWEEN: "BETWEEN"
+ LIKE: "LIKE"
+ ESCAPE: "ESCAPE"
+ IN: "IN"
+ IS: "IS"
+ TRUE: "TRUE"
+ FALSE: "FALSE"
+ NULL: "NULL"
+
+Literals (case insensitive):
+
+ DECIMAL_LITERAL: ["1"-"9"] (["0"-"9"])* (["l","L"])?
+ HEX_LITERAL: "0" ["x","X"] (["0"-"9","a"-"f","A"-"F"])+
+ OCTAL_LITERAL: "0" (["0"-"7"])*
+ FLOATING_POINT_LITERAL: ( (["0"-"9"])+ "." (["0"-"9"])* (<EXPONENT>)? // matches: 5.5 or 5. or 5.5E10 or 5.E10
+ | "." (["0"-"9"])+ (<EXPONENT>)? // matches: .5 or .5E10
+ | (["0"-"9"])+ <EXPONENT> ) // matches: 5E10
+ EXPONENT: "E" (["+","-"])? (["0"-"9"])+
+ STRING_LITERAL: "'" ( ("''") | ~["'"] )* "'"
+
+Identifiers (case insensitive):
+
+ ID : ["a"-"z", "_", "$"] (["a"-"z","0"-"9","_", "$"])*
+ QUOTED_ID : "\"" ( ("\"\"") | ~["\""] )* "\""
+
+Grammar:
+
+ JmsSelector := orExpression
+ orExpression := ( andExpression ( <OR> andExpression )* )
+ andExpression := ( equalityExpression ( <AND> equalityExpression )* )
+ equalityExpression := ( comparisonExpression ( "=" comparisonExpression
+ | "<>" comparisonExpression
+ | <IS> <NULL>
+ | <IS> <NOT> <NULL> )* )
+ comparisonExpression := ( addExpression ( ">" addExpression
+ | ">=" addExpression
+ | "<" addExpression
+ | "<=" addExpression
+ | <LIKE> stringLitteral ( <ESCAPE> stringLitteral )?
+ | <NOT> <LIKE> <STRING_LITERAL> ( <ESCAPE> <STRING_LITERAL> )?
+ | <BETWEEN> addExpression <AND> addExpression
+ | <NOT> <BETWEEN> addExpression <AND> addExpression
+ | <IN> "(" <STRING_LITERAL> ( "," <STRING_LITERAL> )* ")"
+ | <NOT> <IN> "(" <STRING_LITERAL> ( "," <STRING_LITERAL> )* ")" )* )
+ addExpression := multExpr ( ( "+" multExpr | "-" multExpr ) )*
+ multExpr := unaryExpr ( "*" unaryExpr | "/" unaryExpr | "%" unaryExpr )*
+ unaryExpr := ( "+" unaryExpr | "-" unaryExpr | <NOT> unaryExpr | primaryExpr )
+ primaryExpr := ( literal | variable | "(" orExpression ")" )
+ literal := ( <STRING_LITERAL>
+ | <DECIMAL_LITERAL>
+ | <HEX_LITERAL>
+ | <OCTAL_LITERAL>
+ | <FLOATING_POINT_LITERAL>
+ | <TRUE>
+ | <FALSE>
+ | <NULL> )
+ variable := ( <ID> | <QUOTED_ID> )
+]]></programlisting>
+
+</section>
diff --git a/qpid/doc/book/src/LVQ.xml b/qpid/doc/book/src/LVQ.xml
new file mode 100644
index 0000000000..7c9f588c51
--- /dev/null
+++ b/qpid/doc/book/src/LVQ.xml
@@ -0,0 +1,362 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+
+ 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.
+
+-->
+
+<section><title>
+ LVQ
+ </title>
+
+ <section role="h2" id="LVQ-UnderstandingLVQ"><title>
+ Understanding LVQ
+ </title>
+ <para>
+ Last Value Queues are useful youUser Documentation are only
+ interested in the latest value entered into a queue. LVQ
+ semantics are typically used for things like stock symbol updates
+ when all you care about is the latest value for example.
+ </para><para>
+ Qpid C++ M4 or later supports two types of LVQ semantics:
+ </para><itemizedlist>
+ <listitem><para>LVQ
+ </para></listitem>
+ <listitem><para>LVQ_NO_BROWSE
+ </para></listitem>
+ </itemizedlist>
+ <!--h2--></section>
+
+
+ <section role="h2" id="LVQ-LVQsemantics-3A"><title>
+ LVQ semantics:
+ </title>
+ <para>
+ LVQ uses a header for a key, if the key matches it replaces the
+ message in-place in the queue except
+ a.) if the message with the matching key has been acquired
+ b.) if the message with the matching key has been browsed
+ In these two cases the message is placed into the queue in FIFO,
+ if another message with the same key is received it will the
+ 'un-accessed' message with the same key will be replaced
+ </para><para>
+ These two exceptions protect the consumer from missing the last
+ update where a consumer or browser accesses a message and an
+ update comes with the same key.
+ </para><para>
+ An example
+ </para>
+ <programlisting>
+[localhost tests]$ ./lvqtest --mode create_lvq
+[localhost tests]$ ./lvqtest --mode write
+Sending Data: key1=key1.0x7fffdf3f3180
+Sending Data: key2=key2.0x7fffdf3f3180
+Sending Data: key3=key3.0x7fffdf3f3180
+Sending Data: key1=key1.0x7fffdf3f3180
+Sending Data: last=last
+[localhost tests]$ ./lvqtest --mode browse
+Receiving Data:key1.0x7fffdf3f3180
+Receiving Data:key2.0x7fffdf3f3180
+Receiving Data:key3.0x7fffdf3f3180
+Receiving Data:last
+[localhost tests]$ ./lvqtest --mode write
+Sending Data: key1=key1.0x7fffe4c7fa10
+Sending Data: key2=key2.0x7fffe4c7fa10
+Sending Data: key3=key3.0x7fffe4c7fa10
+Sending Data: key1=key1.0x7fffe4c7fa10
+Sending Data: last=last
+[localhost tests]$ ./lvqtest --mode browse
+Receiving Data:key1.0x7fffe4c7fa10
+Receiving Data:key2.0x7fffe4c7fa10
+Receiving Data:key3.0x7fffe4c7fa10
+Receiving Data:last
+[localhost tests]$ ./lvqtest --mode consume
+Receiving Data:key1.0x7fffdf3f3180
+Receiving Data:key2.0x7fffdf3f3180
+Receiving Data:key3.0x7fffdf3f3180
+Receiving Data:last
+Receiving Data:key1.0x7fffe4c7fa10
+Receiving Data:key2.0x7fffe4c7fa10
+Receiving Data:key3.0x7fffe4c7fa10
+Receiving Data:last
+</programlisting>
+<!--h2--></section>
+ <section role="h2" id="LVQ-LVQNOBROWSEsemantics-3A"><title>
+ LVQ_NO_BROWSE
+ semantics:
+ </title>
+ <para>
+ LVQ uses a header for a key, if the key matches it replaces the
+ message in-place in the queue except
+ a.) if the message with the matching key has been acquired
+ In these two cases the message is placed into the queue in FIFO,
+ if another message with the same key is received it will the
+ 'un-accessed' message with the same key will be replaced
+ </para><para>
+ Note, in this case browsed messaged are not invalidated, so
+ updates can be missed.
+ </para><para>
+ An example
+ </para>
+ <programlisting>
+[localhost tests]$ ./lvqtest --mode create_lvq_no_browse
+[localhost tests]$ ./lvqtest --mode write
+Sending Data: key1=key1.0x7fffce5fb390
+Sending Data: key2=key2.0x7fffce5fb390
+Sending Data: key3=key3.0x7fffce5fb390
+Sending Data: key1=key1.0x7fffce5fb390
+Sending Data: last=last
+[localhost tests]$ ./lvqtest --mode write
+Sending Data: key1=key1.0x7fff346ae440
+Sending Data: key2=key2.0x7fff346ae440
+Sending Data: key3=key3.0x7fff346ae440
+Sending Data: key1=key1.0x7fff346ae440
+Sending Data: last=last
+[localhost tests]$ ./lvqtest --mode browse
+Receiving Data:key1.0x7fff346ae440
+Receiving Data:key2.0x7fff346ae440
+Receiving Data:key3.0x7fff346ae440
+Receiving Data:last
+[localhost tests]$ ./lvqtest --mode browse
+Receiving Data:key1.0x7fff346ae440
+Receiving Data:key2.0x7fff346ae440
+Receiving Data:key3.0x7fff346ae440
+Receiving Data:last
+[localhost tests]$ ./lvqtest --mode write
+Sending Data: key1=key1.0x7fff606583e0
+Sending Data: key2=key2.0x7fff606583e0
+Sending Data: key3=key3.0x7fff606583e0
+Sending Data: key1=key1.0x7fff606583e0
+Sending Data: last=last
+[localhost tests]$ ./lvqtest --mode consume
+Receiving Data:key1.0x7fff606583e0
+Receiving Data:key2.0x7fff606583e0
+Receiving Data:key3.0x7fff606583e0
+Receiving Data:last
+[localhost tests]$
+
+</programlisting>
+ <!--h2--></section>
+ <section role="h2" id="LVQ-Examplesource"><title>
+ LVQ Program Example
+ </title>
+
+ <programlisting>
+
+/*
+ *
+ * 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 &lt;qpid/client/AsyncSession.h&gt;
+#include &lt;qpid/client/Connection.h&gt;
+#include &lt;qpid/client/SubscriptionManager.h&gt;
+#include &lt;qpid/client/Session.h&gt;
+#include &lt;qpid/client/Message.h&gt;
+#include &lt;qpid/client/MessageListener.h&gt;
+#include &lt;qpid/client/QueueOptions.h&gt;
+
+#include &lt;iostream&gt;
+
+using namespace qpid::client;
+using namespace qpid::framing;
+using namespace qpid::sys;
+using namespace qpid;
+using namespace std;
+
+
+enum Mode { CREATE_LVQ, CREATE_LVQ_NO_BROWSE, WRITE, BROWSE, CONSUME};
+const char* modeNames[] = { "create_lvq","create_lvq_no_browse","write","browse","consume" };
+
+// istream/ostream ops so Options can read/display Mode.
+istream&amp; operator&gt;&gt;(istream&amp; in, Mode&amp; mode) {
+ string s;
+ in &gt;&gt; s;
+ int i = find(modeNames, modeNames+5, s) - modeNames;
+ if (i &gt;= 5) throw Exception("Invalid mode: "+s);
+ mode = Mode(i);
+ return in;
+}
+
+ostream&amp; operator&lt;&lt;(ostream&amp; out, Mode mode) {
+ return out &lt;&lt; modeNames[mode];
+}
+
+struct Args : public qpid::Options,
+ public qpid::client::ConnectionSettings
+{
+ bool help;
+ Mode mode;
+
+ Args() : qpid::Options("Simple latency test optins"), help(false), mode(BROWSE)
+ {
+ using namespace qpid;
+ addOptions()
+ ("help", optValue(help), "Print this usage statement")
+ ("broker,b", optValue(host, "HOST"), "Broker host to connect to")
+ ("port,p", optValue(port, "PORT"), "Broker port to connect to")
+ ("username", optValue(username, "USER"), "user name for broker log in.")
+ ("password", optValue(password, "PASSWORD"), "password for broker log in.")
+ ("mechanism", optValue(mechanism, "MECH"), "SASL mechanism to use when authenticating.")
+ ("tcp-nodelay", optValue(tcpNoDelay), "Turn on tcp-nodelay")
+ ("mode", optValue(mode, "'see below'"), "Action mode."
+ "\ncreate_lvq: create a new queue of type lvq.\n"
+ "\ncreate_lvq_no_browse: create a new queue of type lvq with no lvq on browse.\n"
+ "\nwrite: write a bunch of data &amp; keys.\n"
+ "\nbrowse: browse the queue.\n"
+ "\nconsume: consume from the queue.\n");
+ }
+};
+
+class Listener : public MessageListener
+{
+ private:
+ Session session;
+ SubscriptionManager subscriptions;
+ std::string queue;
+ Message request;
+ QueueOptions args;
+ public:
+ Listener(Session&amp; session);
+ void setup(bool browse);
+ void send(std::string kv);
+ void received(Message&amp; message);
+ void browse();
+ void consume();
+};
+
+Listener::Listener(Session&amp; s) :
+ session(s), subscriptions(s),
+ queue("LVQtester")
+{}
+
+void Listener::setup(bool browse)
+{
+ // set queue mode
+ args.setOrdering(browse?LVQ_NO_BROWSE:LVQ);
+
+ session.queueDeclare(arg::queue=queue, arg::exclusive=false, arg::autoDelete=false, arg::arguments=args);
+
+}
+
+void Listener::browse()
+{
+ subscriptions.subscribe(*this, queue, SubscriptionSettings(FlowControl::unlimited(), ACCEPT_MODE_NONE, ACQUIRE_MODE_NOT_ACQUIRED));
+ subscriptions.run();
+}
+
+void Listener::consume()
+{
+ subscriptions.subscribe(*this, queue, SubscriptionSettings(FlowControl::unlimited(), ACCEPT_MODE_NONE, ACQUIRE_MODE_PRE_ACQUIRED));
+ subscriptions.run();
+}
+
+void Listener::send(std::string kv)
+{
+ request.getDeliveryProperties().setRoutingKey(queue);
+
+ std::string key;
+ args.getLVQKey(key);
+ request.getHeaders().setString(key, kv);
+
+ std::ostringstream data;
+ data &lt;&lt; kv;
+ if (kv != "last") data &lt;&lt; "." &lt;&lt; hex &lt;&lt; this;
+ request.setData(data.str());
+
+ cout &lt;&lt; "Sending Data: " &lt;&lt; kv &lt;&lt; "=" &lt;&lt; data.str() &lt;&lt; std::endl;
+ async(session).messageTransfer(arg::content=request);
+
+}
+
+void Listener::received(Message&amp; response)
+{
+
+ cout &lt;&lt; "Receiving Data:" &lt;&lt; response.getData() &lt;&lt; std::endl;
+/* if (response.getData() == "last"){
+ subscriptions.cancel(queue);
+ }
+*/
+}
+
+int main(int argc, char** argv)
+{
+ Args opts;
+ opts.parse(argc, argv);
+
+ if (opts.help) {
+ std::cout &lt;&lt; opts &lt;&lt; std::endl;
+ return 0;
+ }
+
+ Connection connection;
+ try {
+ connection.open(opts);
+ Session session = connection.newSession();
+ Listener listener(session);
+
+ switch (opts.mode)
+ {
+ case CONSUME:
+ listener.consume();
+ break;
+ case BROWSE:
+ listener.browse();
+ break;
+ case CREATE_LVQ:
+ listener.setup(false);
+ break;
+ case CREATE_LVQ_NO_BROWSE:
+ listener.setup(true);
+ break;
+ case WRITE:
+ listener.send("key1");
+ listener.send("key2");
+ listener.send("key3");
+ listener.send("key1");
+ listener.send("last");
+ break;
+ }
+ connection.close();
+ return 0;
+ } catch(const std::exception&amp; error) {
+ std::cout &lt;&lt; error.what() &lt;&lt; std::endl;
+ }
+ return 1;
+}
+
+</programlisting>
+<!--h2--></section>
+</section>
diff --git a/qpid/doc/book/src/Management-Console-Security.xml b/qpid/doc/book/src/Management-Console-Security.xml
new file mode 100644
index 0000000000..aa7bebb09e
--- /dev/null
+++ b/qpid/doc/book/src/Management-Console-Security.xml
@@ -0,0 +1,252 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+
+ 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.
+
+-->
+
+<section><title>
+ Management Console Security
+ </title><section role="h1" id="ManagementConsoleSecurity-ManagementConsoleSecurity"><title>
+ Management
+ Console Security
+ </title>
+ <itemizedlist>
+ <listitem><para>
+ <xref linkend="ManagementConsoleSecurity-SSLencryptedRMI-280.5andabove-29"/>
+ </para></listitem>
+ <listitem><para>
+ <xref linkend="ManagementConsoleSecurity-JMXMP-28M4andprevious-29"/>
+ </para></listitem>
+ <listitem><para>
+ <xref linkend="ManagementConsoleSecurity-UserAccounts-26AccessRights"/>
+ </para></listitem>
+ </itemizedlist>
+ <section role="h2" id="ManagementConsoleSecurity-SSLencryptedRMI-280.5andabove-29"><title>
+ SSL
+ encrypted RMI (0.5 and above)
+ </title>
+ <para>
+ Current versions of the broker make use of SSL encryption to
+ secure their RMI based JMX ConnectorServer for security purposes.
+ This ships enabled by default, although the test SSL keystore
+ used during development is not provided for security reasons
+ (using this would provide no security as anyone could have access
+ to it).
+ </para><section role="h3" id="ManagementConsoleSecurity-BrokerConfiguration"><title>
+ Broker
+ Configuration
+ </title>
+
+ <para>
+ The broker configuration must be updated before the broker will
+ start. This can be done either by disabling the SSL support,
+ utilizing a purchased SSL certificate to create a keystore of
+ your own, or using the example 'create-example-ssl-stores' script
+ in the brokers bin/ directory to generate a self-signed keystore.
+ </para><para>
+ The broker must be configured with a keystore containing the
+ private and public keys associated with its SSL certificate. This
+ is accomplished by setting the Java environment properties
+ <emphasis>javax.net.ssl.keyStore</emphasis> and
+ <emphasis>javax.net.ssl.keyStorePassword</emphasis> respectively with the
+ location and password of an appropriate SSL keystore. Entries for
+ these properties exist in the brokers main configuration file
+ alongside the other management settings (see below), although the
+ command line options will still work and take precedence over the
+ configuration file.
+ </para>
+ <programlisting>
+&lt;management&gt;
+ &lt;ssl&gt;
+ &lt;enabled&gt;true&lt;/enabled&gt;
+ &lt;!-- Update below path to your keystore location, eg ${conf}/qpid.keystore --&gt;
+ &lt;keyStorePath&gt;${prefix}/../test_resources/ssl/keystore.jks&lt;/keyStorePath&gt;
+ &lt;keyStorePassword&gt;password&lt;/keyStorePassword&gt;
+ &lt;/ssl&gt;
+&lt;/management&gt;
+</programlisting>
+<!--h3--></section>
+
+ <section role="h3" id="ManagementConsoleSecurity-JMXManagementConsoleConfiguration"><title>
+ JMX
+ Management Console Configuration
+ </title>
+
+ <para>
+ If the broker makes use of an SSL certificate signed by a known
+ signing CA (Certification Authority), the management console
+ needs no extra configuration, and will make use of Java's
+ built-in CA
+ truststore for certificate verification (you may however have to
+ update the system-wide default truststore if your CA is not
+ already present in it).
+ </para><para>
+ If however you wish to use a self-signed SSL certificate, then
+ the management console must be provided with an SSL truststore
+ containing a record for the SSL certificate so that it is able to
+ validate it when presented by the broker. This is performed by
+ setting the <emphasis>javax.net.ssl.trustStore</emphasis> and
+ <emphasis>javax.net.ssl.trustStorePassword</emphasis> environment variables
+ when starting the console. This can be done at the command line,
+ or alternatively an example configuration has been made within
+ the console's qpidmc.ini launcher configuration file that may
+ pre-configured in advance for repeated usage. See the <xref linkend="Qpid-JMX-Management-Console-User-Guide"/> for more
+ information on this configuration process.
+ </para>
+<!--h3--></section>
+
+ <section role="h3" id="ManagementConsoleSecurity-JConsoleConfiguration"><title>
+ JConsole
+ Configuration
+ </title>
+
+ <para>
+ As with the JMX Management Console above, if the broker is using
+ a self-signed SSL certificate then in order to connect remotely
+ using JConsole, an appropriate trust store must be provided at
+ startup. See <xref linkend="qpid_JConsole"/> for further details on configuration.
+ </para>
+<!--h3--></section>
+
+ <section role="h3" id="ManagementConsoleSecurity-AdditionalInformation"><title>
+ Additional
+ Information
+ </title>
+
+ <para>
+ More information on Java's handling of SSL certificate
+ verification and customizing the keystores can be found in the
+ <ulink url="http://java.sun.com/javase/6/docs/technotes/guides/security/jsse/JSSERefGuide.html#CustomizingStores">http://java.sun.com/javase/6/docs/technotes/guides/security/jsse/JSSERefGuide.html#CustomizingStores</ulink>.
+ </para>
+<!--h3--></section>
+<!--h2--></section>
+
+
+
+ <section role="h2" id="ManagementConsoleSecurity-JMXMP-28M4andprevious-29"><title>
+ JMXMP
+ (M4 and previous)
+ </title>
+
+ <para>
+ In previous releases of Qpid (M4 and below) the broker, can make
+ use of Sun's Java Management Extensions Messaging Protocol
+ (JMXMP) to provide encryption of the JMX connection, offering
+ increased security over the default unencrypted RMI based JMX
+ connection.
+ </para><section role="h3" id="ManagementConsoleSecurity-DownloadandInstall"><title>
+ Download and
+ Install
+ </title>
+
+ <para>
+ This is possible by adding the jmxremote_optional.jar as provided
+ by Sun. This jar is covered by the Sun Binary Code License and is
+ not compatible with the Apache License which is why this
+ component is not bundled with Qpid.
+ </para><para>
+ Download the JMX Remote API 1.0.1_04 Reference Implementation
+ from <xref linkend="qpid_download.jsp"/>. The included
+ 'jmxremote-1_0_1-bin\lib\jmxremote_optional.jar' file must be
+ added to the broker classpath:
+ </para><para>
+ First set your classpath to something like this:
+ </para>
+ <programlisting>
+CLASSPATH=jmxremote_optional.jar
+</programlisting>
+ <para>
+ Then, run qpid-server passing the following additional flag:
+ </para>
+ <programlisting>
+qpid-server -run:external-classpath=first
+</programlisting>
+ <para>
+ Following this the configuration option can be updated to enabled
+ use of the JMXMP based JMXConnectorServer.
+ </para>
+<!--h3--></section>
+
+ <section role="h3" id="ManagementConsoleSecurity-BrokerConfiguration2"><title>
+ Broker
+ Configuration
+ </title>
+
+ <para>
+ To enabled this security option change the
+ <emphasis>security-enabled</emphasis> value in your broker configuration
+ file.
+ </para>
+ <programlisting>
+ &lt;management&gt;
+ &lt;security-enabled&gt;true&lt;/security-enabled&gt;
+ &lt;/management&gt;
+</programlisting>
+ <para>
+ You may also (for M2 and earlier) need to set the following
+ system properties using the environment variable QPID_OPTS:
+ </para><para>
+ QPID_OPTS="-Dcom.sun.management.jmxremote
+ -Dcom.sun.management.jmxremote.port=8999
+ -Dcom.sun.management.jmxremote.authenticate=false
+ -Dcom.sun.management.jmxremote.ssl=false"
+ </para>
+<!--h3--></section>
+
+ <section role="h3" id="ManagementConsoleSecurity-JMXManagementConsoleConfiguration-2"><title>
+ JMX
+ Management Console Configuration
+ </title>
+
+ <para>
+ If you wish to connect to a broker configured to use JMXMP then
+ the console also requires provision of the Optional sections of
+ the JMX Remote API that are not included within the JavaSE
+ platform.
+ </para><para>
+ In order to make it available to the console, place the
+ 'jmxremote_optional.jar' (rename the file if any additional
+ information is present in the file name) jar file within the
+ 'plugins/jmxremote.sasl_1.0.1/' folder of the console release (on
+ Mac OS X you will need to select 'Show package contents' from the
+ context menu whilst selecting the management console bundle in
+ order to reveal the inner file tree).
+ </para><para>
+ Following the the console will automatically load the JMX Remote
+ Optional classes and attempt the JMXMP connection when connecting
+ to a JMXMP enabled broker.
+ </para>
+<!--h3--></section>
+<!--h2--></section>
+
+ <section role="h2" id="ManagementConsoleSecurity-UserAccounts-26AccessRights"><title>
+ User
+ Accounts &amp; Access Rights
+ </title>
+
+ <para>
+ In order to access the management operations via JMX, users must
+ have an account and have been assigned appropriate access rights.
+ See <xref linkend="qpid_Configuring-Management-Users"/>
+ </para>
+<!--h2--></section>
+<!--h1--></section>
+
+
+</section>
diff --git a/qpid/doc/book/src/Management-Design-notes.xml b/qpid/doc/book/src/Management-Design-notes.xml
new file mode 100644
index 0000000000..76f0dac926
--- /dev/null
+++ b/qpid/doc/book/src/Management-Design-notes.xml
@@ -0,0 +1,2136 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+
+ 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.
+
+-->
+
+<section><title>
+ Management Design notes
+ </title><section role="h2" id="ManagementDesignnotes-StatusofThisDocument"><title>
+ Status
+ of This Document
+ </title>
+
+ <para>
+ This document does not track any current development activity. It
+ is the specification of the management framework implemented in
+ the M3 release of the C++ broker and will be left here for user
+ and developer reference.
+ </para><para>
+ Development continues on the Qpid Management Framework (QMF) for
+ M4. If you are using M3, this is the document you need. If you
+ are using the SVN trunk, please refer to <xref linkend="qpid_Qpid-Management-Framework"/> for
+ up-to-date information.
+ </para>
+ <!--h2--></section>
+
+ <section role="h2" id="ManagementDesignnotes-Introduction"><title>
+ Introduction
+ </title>
+
+ <para>
+ This document describes the management features that are used in
+ the QPID C++ broker as of the M3 milestone. These features do not
+ appear in earlier milestones nor are they implemented in the Java
+ broker.
+ </para><para>
+ This specification is <emphasis>not</emphasis> a standard and is not endorsed
+ by the AMQP working group. When such a standard is adopted, the
+ QPID implementation will be brought into compliance with that
+ standard.
+ </para>
+ <!--h2--></section>
+
+ <section role="h2" id="ManagementDesignnotes-Links"><title>
+ Links
+ </title>
+
+ <itemizedlist>
+ <listitem><para>The schema is checked into <xref linkend="qpid_management-schema.xml"/>.
+ </para></listitem>
+ </itemizedlist><section role="h3" id="ManagementDesignnotes-DesignnoteforgettinginfoinandoutviaJMX"><title>
+ Design
+ note for getting info in and out via JMX
+ </title>
+
+ <para>
+ <xref linkend="qpid_JMX-Gateway"/>
+ </para>
+ <!--h3--></section>
+
+ <!--h2--></section>
+
+ <section role="h2" id="ManagementDesignnotes-ManagementRequirements"><title>
+ Management
+ Requirements
+ </title>
+
+ <itemizedlist>
+ <listitem><para>Must operate from a formally defined management schema.
+ </para></listitem>
+ <listitem><para>Must natively use the AMQP protocol and its type system.
+ </para></listitem>
+ <listitem><para>Must support the following operations
+ <itemizedlist>
+ <listitem><para>SET operation on configurable (persistent) aspects of
+ objects
+ </para></listitem>
+ <listitem><para>GET operation on all aspects of objects
+ </para></listitem>
+ <listitem><para>METHOD invocation on schema-defined object-specific
+ methods
+ </para></listitem>
+ <listitem><para>Distribution of unsolicited periodic updates of
+ instrumentation data
+ <itemizedlist>
+ <listitem><para>Data updates shall carry an accurate sample timestamp
+ for rate calculation
+ </para></listitem>
+ <listitem><para>Updates shall carry object create/delete timestamps.
+ </para></listitem>
+ <listitem><para>Transient objects shall be fully accounted for via
+ updates. Note that short-lived transient objects may come
+ and go within a single update interval. All of the
+ information pertaining to such an object must be captured
+ and transmitted.
+ </para></listitem>
+ </itemizedlist>
+ </para></listitem>
+ <listitem><para>Distribution of unsolicited event and/or alert
+ indications (schema defined)
+ </para></listitem>
+ </itemizedlist>
+ </para></listitem>
+ <listitem><para>Role-based access control at object, operation, and method
+ granularity
+ </para></listitem>
+ <listitem><para>End-to-end encryption and signing of management content
+ </para></listitem>
+ <listitem><para>Schema must be self-describing so the management client need
+ not have prior knowledge of the management model of the system
+ under management.
+ </para></listitem>
+ <listitem><para>Must be extensible to support the management of objects
+ beyond the QPID component set. This allows AMQP to be used as a
+ general-purpose management protocol.
+ </para></listitem>
+ </itemizedlist>
+ <!--h2--></section>
+
+ <section role="h2" id="ManagementDesignnotes-DefinitionofTerms"><title>
+ Definition
+ of Terms
+ </title>
+
+ <table><title/><tgroup cols="2">
+ <tbody>
+ <row>
+ <entry>
+ class
+ </entry>
+ <entry>
+ A type definition for a manageable object.
+ </entry>
+ </row>
+ <row>
+ <entry>
+ package
+ </entry>
+ <entry>
+ A grouping of class definitions that are related to a
+ single software component. The package concept is used to
+ extend the management schema beyond just the QPID software
+ components.
+ </entry>
+ </row>
+ <row>
+ <entry>
+ object
+ </entry>
+ <entry>
+ Also "manageable object". An instantiation of a class. An
+ object represents a physical or logical component in the
+ core function of the system under management.
+ </entry>
+ </row>
+ <row>
+ <entry>
+ property
+ </entry>
+ <entry>
+ A typed member of a class which represents a configurable
+ attribute of the class. In general, properties don't change
+ frequently or may not change at all.
+ </entry>
+ </row>
+ <row>
+ <entry>
+ statistic
+ </entry>
+ <entry>
+ A typed member of a class which represents an
+ instrumentation attribute of the class. Statistics are
+ always read-only in nature and tend to change rapidly.
+ </entry>
+ </row>
+ <row>
+ <entry>
+ method
+ </entry>
+ <entry>
+ A member of a class which represents a callable procedure
+ on an object of the class. Methods may have an arbitrary
+ set of typed arguments and may supply a return code.
+ Methods typically have side effects on the associated
+ object.
+ </entry>
+ </row>
+ <row>
+ <entry>
+ event
+ </entry>
+ <entry>
+ A member of a class which represents the occurence of an
+ event of interest within the system under management.
+ </entry>
+ </row>
+ <row>
+ <entry>
+ management broker
+ </entry>
+ <entry>
+ A software component built into the messaging broker that
+ handles management traffic and distributes management data.
+ </entry>
+ </row>
+ <row>
+ <entry>
+ management agent
+ </entry>
+ <entry>
+ A software component that is separate from the messaging
+ broker, connected to the management broker via an AMQP
+ connection, which allows any software component to be
+ managed remotely by QPID.
+ </entry>
+ </row>
+ </tbody>
+ </tgroup></table>
+ <!--h2--></section>
+
+
+ <section role="h2" id="ManagementDesignnotes-OperationalScenarios-3ABasicvs.Extended"><title>
+ Operational
+ Scenarios: Basic vs. Extended
+ </title>
+
+ <para>
+ The extensibility requirement introduces complexity to the
+ management protocol that is unnecessary and undesirable for the
+ user/developer that wishes only to manage QPID message brokers.
+ For this reason, the protocol is partitioned into two parts: The
+ <emphasis>basic protocol</emphasis>, which contains only the capability to
+ manage a single broker; and the <emphasis>extended protocol</emphasis>, which
+ provides the hooks for managing an extended set of components. A
+ management console can be implemented using only the basic
+ protocol if the extended capabilities are not needed.
+ </para>
+<!--h2--></section>
+
+
+ <section role="h2" id="ManagementDesignnotes-ArchitecturalFramework"><title>
+ Architectural
+ Framework
+ </title>
+
+ <para>
+ <xref linkend="qpid_qmf_architecture"/>
+ </para>
+ <!--h2--></section>
+
+ <section role="h2" id="ManagementDesignnotes-TheManagementExchange"><title>
+ The
+ Management Exchange
+ </title>
+
+ <para>
+ The management exchange (called "qpid.management" currently) is a
+ special type of exchange used for remote management access to the
+ Qpid broker. The management exchange is an extension of the
+ standard "Topic" exchange. It behaves like a topic exchange with
+ the following exceptions:
+ </para><orderedlist>
+ <listitem><para>When a queue is successfully bound to the exchange, a method
+ is invoked on the broker's management agent to notify it of the
+ presence of a new remote managment client.
+ </para></listitem>
+ <listitem><para>When messages arrive at the exchange for routing, the
+ exchange examines the message's routing key and if the key
+ represents a management command or method, it routes it directly
+ to the management agent rather than routing it to queues using
+ the topic algorithm.
+ The management exchange is used by the management agent to
+ distribute unsolicited management data. Such data is classified
+ by the routing key allowing management clients to register for
+ only the data they need.
+ </para></listitem>
+ </orderedlist><section role="h3" id="ManagementDesignnotes-RoutingKeyStructure"><title>
+ Routing
+ Key Structure
+ </title>
+
+ <para>
+ As noted above, the structure of the binding and routing keys
+ used on the management exchange is important to the function of
+ the management architecture. The routing key of a management
+ message determines:
+ </para><orderedlist>
+ <listitem><para>The type of message (i.e. operation request or unsolicited
+ update).
+ </para></listitem>
+ <listitem><para>The class of the object that the message pertains to.
+ </para></listitem>
+ <listitem><para>The specific operation or update type.
+ </para></listitem>
+ <listitem><para>The namespace in which the class belongs. This allows for
+ plug-in expansion of the management schema for manageable objects
+ that are outside of the broker itself.
+ </para></listitem>
+ </orderedlist><para>
+ Placing this information in the routing key provides the ability
+ to enforce access control at class, operation, and method
+ granularity. It also separates the command structure from the
+ content of the management message (i.e. element values) allowing
+ the content to be encrypted and signed end-to-end while still
+ allowing access control at the message-transport level. This
+ means that special access control code need not be written for
+ the management agent.
+ There are two general types of routing/binding key:
+ </para><itemizedlist>
+ <listitem><para>
+ <emphasis>Command</emphasis> messages use the key:
+ agent.&lt;bank#&gt; or broker
+ </para></listitem>
+ <listitem><para>
+ <emphasis>Unsolicited</emphasis> keys have the structure:
+ mgmt.&lt;agent&gt;.&lt;type&gt;.&lt;package&gt;.&lt;class&gt;.&lt;severity&gt;
+ where
+ <itemizedlist>
+ <listitem><para>
+ &lt;agent&gt; is the uuid of the originating
+ management agent,
+ </para></listitem>
+ <listitem><para>
+ &lt;type&gt; is one of "schema", "prop", "stat",
+ or "event",
+ </para></listitem>
+ <listitem><para>
+ &lt;package&gt; is the namespace in which the
+ &lt;class&gt; name is valid, and
+ </para></listitem>
+ <listitem><para>
+ &lt;class&gt; is the name of the class as defined
+ in the schema.
+ </para></listitem>
+ <listitem><para>
+ &lt;severity&gt; is relevant for events only. It
+ is one of "critical", "error", "warning", or "info".
+ </para></listitem>
+ </itemizedlist>
+ </para></listitem>
+ </itemizedlist><para>
+ In both cases, the content of the message (i.e. method arguments,
+ element values, etc.) is carried in the body segment of the
+ message.
+ </para><para>
+ The &lt;package&gt; namespace allows this management
+ framework to be extended with the addition of other software
+ packages.
+ </para>
+ <!--h3--></section>
+ <!--h2--></section>
+
+ <section role="h2" id="ManagementDesignnotes-TheProtocol"><title>
+ The Protocol
+ </title>
+
+ <section role="h3" id="ManagementDesignnotes-ProtocolHeader"><title>
+ Protocol
+ Header
+ </title>
+
+ <para>
+ The body segments of management messages are composed of
+ sequences of binary-encoded data fields, in a manner consistent
+ with the 0-10 version of the AMQP specification.
+ </para><para>
+ All management messages begin with a message header:
+ </para>
+ <programlisting>
+ octet 0 1 2 3 4 5 6 7
+ +---------+---------+---------+---------+---------+---------+---------+---------+
+ | 'A' | 'M' | '1' | op-code | sequence |
+ +---------+---------+---------+---------+---------+---------+---------+---------+
+</programlisting>
+ <para>
+ The first three octets contain the protocol <emphasis>magic number</emphasis>
+ "AM1" which is used to identify the type and version of the
+ message.
+ </para><para>
+ The <emphasis>opcode</emphasis> field identifies the operation represented by
+ the message
+ </para>
+ <!--h3--></section>
+
+ <section role="h3" id="ManagementDesignnotes-ProtocolExchangePatterns"><title>
+ Protocol
+ Exchange Patterns
+ </title>
+
+ <para>
+ The following patterns are followed in the design of the
+ protocol:
+ </para><itemizedlist>
+ <listitem><para>Request-Response
+ </para></listitem>
+ <listitem><para>Query-Indication
+ </para></listitem>
+ <listitem><para>Unsolicited Indication
+ </para></listitem>
+ </itemizedlist><section role="h4" id="ManagementDesignnotes-TheRequestResponsePattern"><title>
+ The
+ Request-Response Pattern
+ </title>
+
+ <para>
+ In the request-response pattern, a requestor sends a
+ <emphasis>request</emphasis> message to one of its peers. The peer then does
+ one of two things: If the request can be successfully processed,
+ a single <emphasis>response</emphasis> message is sent back to the requestor.
+ This response contains the requested results and serves as the
+ positive acknowledgement that the request was successfully
+ completed.
+ </para><para>
+ If the request cannot be successfully completed, the peer sends a
+ <emphasis>command complete</emphasis> message back to the requestor with an
+ error code and error text describing what went wrong.
+ </para><para>
+ The sequence number in the <emphasis>response</emphasis> or <emphasis>command
+ complete</emphasis> message is the same as the sequence number in the
+ <emphasis>request</emphasis>.
+ </para>
+ <programlisting>
+ Requestor Peer
+ | |
+ | --- Request (seq) ------------------------------------------&gt; |
+ | |
+ | &lt;----------------------------------------- Response (seq) --- |
+ | |
+</programlisting>
+
+ <programlisting>
+ Requestor Peer
+ | |
+ | --- Request (seq) ------------------------------------------&gt; |
+ | |
+ | &lt;-------------------------- Command Complete (seq, error) --- |
+ | |
+</programlisting>
+<!--h4--></section>
+
+ <section role="h4" id="ManagementDesignnotes-TheQueryIndicationPattern"><title>
+ The
+ Query-Indication Pattern
+ </title>
+
+ <para>
+ The query-indication pattern is used when there may be zero or
+ more answers to a question. In this case, the requestor sends a
+ <emphasis>query</emphasis> message to its peer. The peer processes the query,
+ sending as many <emphasis>indication</emphasis> messages as needed back to the
+ requestor (zero or more). Once the last <emphasis>indication</emphasis> has
+ been sent, the peer then sends a <emphasis>command complete</emphasis> message
+ with a success code indicating that the query is complete.
+ </para><para>
+ If there is an error in the <emphasis>query</emphasis>, the peer may reply with
+ a <emphasis>command complete</emphasis> message containg an error code. In this
+ case, no <emphasis>indication</emphasis> messages may be sent.
+ </para><para>
+ All <emphasis>indication</emphasis> and <emphasis>command complete</emphasis> messages shall
+ have the same sequence number that appeared in the <emphasis>query</emphasis>
+ message.
+ </para>
+ <programlisting>
+ Requestor Peer
+ | |
+ | --- Query (seq) --------------------------------------------&gt; |
+ | |
+ | &lt;--------------------------------------- Indication (seq) --- |
+ | &lt;--------------------------------------- Indication (seq) --- |
+ | &lt;--------------------------------------- Indication (seq) --- |
+ | &lt;--------------------------------------- Indication (seq) --- |
+ | &lt;--------------------------------------- Indication (seq) --- |
+ | |
+ | &lt;------------------------ Command Complete (seq, success) --- |
+ | |
+</programlisting>
+
+ <programlisting>
+ Requestor Peer
+ | |
+ | --- Query (seq) --------------------------------------------&gt; |
+ | |
+ | &lt;-------------------------- Command Complete (seq, error) --- |
+ | |
+</programlisting>
+<!--h4--></section>
+
+ <section role="h4" id="ManagementDesignnotes-TheUnsolicitedIndicationPattern"><title>
+ The
+ Unsolicited-Indication Pattern
+ </title>
+
+ <para>
+ The unsolicited-indication pattern is used when one peer needs to
+ send unsolicited information to another peer, or to broadcast
+ information to multiple peers via a topic exchange. In this case,
+ indication messages are sent with the sequence number field set
+ to zero.
+ </para>
+ <programlisting>
+ Peer Peer
+ | |
+ | &lt;----------------------------------- Indication (seq = 0) --- |
+ | &lt;----------------------------------- Indication (seq = 0) --- |
+ | &lt;----------------------------------- Indication (seq = 0) --- |
+ | &lt;----------------------------------- Indication (seq = 0) --- |
+ | |
+</programlisting>
+<!--h4--></section>
+<!--h3--></section>
+
+ <section role="h3" id="ManagementDesignnotes-ObjectIdentifiers"><title>
+ Object
+ Identifiers
+ </title>
+
+ <para>
+ Manageable objects are tagged with a unique 64-bit object
+ identifier. The object identifier space is owned and managed by
+ the management broker. Objects managed by a single management
+ broker shall have unique object identifiers. Objects managed by
+ separate management brokers may have the same object identifier.
+ </para><para>
+ If a management console is designed to manage multiple management
+ brokers, it must use the broker identifier as well as the object
+ identifier to ensure global uniqueness.
+ </para>
+ <programlisting>
+ 62 48 47 24 23 0
+ +-+-------------+-----------------------+-----------------------+
+ |0| sequence | bank | object |
+ +-+-------------+-----------------------+-----------------------+
+
+ bit 63 - reserved, must be zero
+ bits 63 .. 48 - broker boot sequence (32K)
+ bits 47 .. 24 - bank (16M)
+ bits 23 .. 0 - object (16M)
+</programlisting>
+ <itemizedlist>
+ <listitem><para>For persistent IDs, boot-sequence is zero
+ </para></listitem>
+ <listitem><para>For non-persistent IDs, boot sequence is a constant number
+ which increments each time the management broker is restarted.
+ </para></listitem>
+ <listitem><para>Bank number:
+ <itemizedlist>
+ <listitem><para>0 - reserved
+ </para></listitem>
+ <listitem><para>1 - broker-persistent objects
+ </para></listitem>
+ <listitem><para>2..4 - store-persistent objects
+ </para></listitem>
+ <listitem><para>&gt; 4 - transient objects
+ </para></listitem>
+ </itemizedlist>
+ </para></listitem>
+ </itemizedlist>
+<!--h3--></section>
+
+
+ <section role="h3" id="ManagementDesignnotes-EstablishingCommunicationBetweenClientandAgent"><title>
+ Establishing Communication Between Client and Agent
+ </title>
+
+ <para>
+ Communication is established between the management client and
+ management agent using normal AMQP procedures. The client creates
+ a connection to the broker and then establishes a session with
+ its corresponding channel.
+ </para><para>
+ Two private queues are then declared (only one if method
+ invocation is not needed). A management queue is declared and
+ bound to the qpid.management exchange. If the binding key is
+ "mgmt.#", all management-related messages sent to the exchange
+ will be received by this client. A more specific binding key will
+ result in a more restricted set of messages being received (see
+ the section on Routing Key Structure below).
+ </para><para>
+ If methods are going to be invoked on managed objects, a second
+ private queue must be declared so the client can receive method
+ replies. This queue is bound to the amq.direct exchange using a
+ routing key equal to the name of the queue.
+ </para><para>
+ When a client successfully binds to the qpid.management exchange,
+ the management agent schedules a schema broadcast to be sent to
+ the exchange. The agent will publish, via the exchange, a
+ description of the schema for all manageable objects in its
+ control.
+ </para>
+ <programlisting>
+ Client Broker
+ | |
+ | --- AMQP Connection and Session Setup ----------------------&gt; |
+ | |
+ | --- Queue.declare (private data queue) ---------------------&gt; |
+ | --- Bind queue to exchange 'qpid.management' key 'mgmt.#' --&gt; |
+ | |
+ | --- Queue.declare (private method-reply queue) -------------&gt; |
+ | --- Bind queue to exchange 'amq.direct' --------------------&gt; |
+ | |
+ | --- Broker Request -----------------------------------------&gt; |
+ | &lt;---------------------------------------- Broker Response --- |
+ | |
+ | |
+ | |
+ | &lt;------- Management schema via exchange 'qpid.management' --- |
+ | |
+</programlisting>
+<!--h3--></section>
+
+ <section role="h3" id="ManagementDesignnotes-BroadcastofConfigurationandInstrumentationUpdates"><title>
+ Broadcast of Configuration and Instrumentation Updates
+ </title>
+
+ <para>
+ The management agent will periodically publish updates to the
+ configuration and instrumentation of management objects under its
+ control. Under normal circumstances, these updates are published
+ only if they have changed since the last time they were
+ published. Configuration updates are only published if
+ configuration has changed and instrumentation updates are only
+ published if instrumentation has changed. The exception to this
+ rule is that after a management client binds to the
+ qpid.management exchange, all configuration and instrumentation
+ records are published as though they had changed whether or not
+ they actually did.
+ </para>
+ <programlisting>
+ Client Broker
+ | |
+ | &lt;------------------ Object properties via 'mgmt.*.prop.#' --- | |
+ | &lt;------------------ Object statistics via 'mgmt.*.stat.#' --- | |
+ | | |
+ | | | Publish Interval
+ | | |
+ | | |
+ | | V
+ | &lt;------------------ Object properties via 'mgmt.*.prop.#' --- |
+ | &lt;------------------ Object statistics via 'mgmt.*.stat.#' --- |
+ | |
+</programlisting>
+<!--h3--></section>
+
+ <section role="h3" id="ManagementDesignnotes-InvokingaMethodonaManagedObject"><title>
+ Invoking
+ a Method on a Managed Object
+ </title>
+
+ <para>
+ When the management client wishes to invoke a method on a managed
+ object, it sends a method request message to the qpid.management
+ exchange. The routing key contains the object class and method
+ name (refer to Routing Key Structure below). The method request
+ must have a header entry (reply-to) that contains the name of the
+ method-reply queue so that the method response can be properly
+ routed back to the requestor.
+ </para><para>
+ The method request contains a sequence number that is copied to
+ the method reply. This number is opaque to the management agent
+ and may be used by the management client to correlate the reply
+ to the request. The asynchronous nature of requests and replies
+ allows any number of methods to be in-flight at a time. Note that
+ there is no guarantee that methods will be replied to in the
+ order in which they were requested.
+ </para>
+ <programlisting>
+ Client Broker
+ | |
+ | --- Method Request (to exchange 'qpid.management') ---------&gt; |
+ | |
+ | |
+ | &lt;--------------- Method Reply (via exchange 'amq.direct') --- |
+ | |
+</programlisting>
+<!--h3--></section>
+
+
+ <section role="h3" id="ManagementDesignnotes-MessagesfortheBasicScenario"><title>
+ Messages
+ for the Basic Scenario
+ </title>
+
+ <para>
+ The principals in a management exchange are the <emphasis>management
+ client</emphasis> and the <emphasis>management agent</emphasis>. The management
+ agent is integrated into the QPID broker and the management
+ client is a remote entity. A management agent may be managed by
+ zero or more management clients at any given time. Additionally,
+ a management client may manage multiple management agents at the
+ same time.
+ </para><para>
+ For authentication and access control, management relies on the
+ mechanisms supplied by the AMQP protocol.
+ </para><section role="h4" id="ManagementDesignnotes-BasicOpcodes"><title>
+ Basic Opcodes
+ </title>
+
+ <table><title/><tgroup cols="3">
+ <tbody>
+ <row>
+ <entry>
+ <emphasis>opcode</emphasis>
+ </entry>
+ <entry>
+ <emphasis>message</emphasis>
+ </entry>
+ <entry>
+ <emphasis>description</emphasis>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ 'B'
+ </entry>
+ <entry>
+ Broker Request
+ </entry>
+ <entry>
+ This message contains a broker request, sent from the
+ management console to the broker to initiate a management
+ session.
+ </entry>
+ </row>
+ <row>
+ <entry>
+ 'b'
+ </entry>
+ <entry>
+ Broker Response
+ </entry>
+ <entry>
+ This message contains a broker response, sent from the
+ broker in response to a broker request message.
+ </entry>
+ </row>
+ <row>
+ <entry>
+ 'z'
+ </entry>
+ <entry>
+ Command Completion
+ </entry>
+ <entry>
+ This message is sent to indicate the completion of a
+ request.
+ </entry>
+ </row>
+ <row>
+ <entry>
+ 'Q'
+ </entry>
+ <entry>
+ Class Query
+ </entry>
+ <entry>
+ Class query messages are used by a management console to
+ request a list of schema classes that are known by the
+ management broker.
+ </entry>
+ </row>
+ <row>
+ <entry>
+ 'q'
+ </entry>
+ <entry>
+ Class Indication
+ </entry>
+ <entry>
+ Sent by the management broker, a class indication notifies
+ the peer of the existence of a schema class.
+ </entry>
+ </row>
+ <row>
+ <entry>
+ 'S'
+ </entry>
+ <entry>
+ Schema Request
+ </entry>
+ <entry>
+ Schema request messages are used to request the full schema
+ details for a class.
+ </entry>
+ </row>
+ <row>
+ <entry>
+ 's'
+ </entry>
+ <entry>
+ Schema Response
+ </entry>
+ <entry>
+ Schema response message contain a full description of the
+ schema for a class.
+ </entry>
+ </row>
+ <row>
+ <entry>
+ 'h'
+ </entry>
+ <entry>
+ Heartbeat Indication
+ </entry>
+ <entry>
+ This message is published once per publish-interval. It can
+ be used by a client to positively determine which objects
+ did not change during the interval (since updates are not
+ published for objects with no changes).
+ </entry>
+ </row>
+ <row>
+ <entry>
+ 'c', 'i', 'g'
+ </entry>
+ <entry>
+ Content Indication
+ </entry>
+ <entry>
+ This message contains a content record. Content records
+ contain the values of all properties or statistics in an
+ object. Such records are broadcast on a periodic interval
+ if 1) a change has been made in the value of one of the
+ elements, or 2) if a new management client has bound a
+ queue to the management exchange.
+ </entry>
+ </row>
+ <row>
+ <entry>
+ 'G'
+ </entry>
+ <entry>
+ Get Query
+ </entry>
+ <entry>
+ Sent by a management console, a get query requests that the
+ management broker provide content indications for all
+ objects that match the query criteria.
+ </entry>
+ </row>
+ <row>
+ <entry>
+ 'M'
+ </entry>
+ <entry>
+ Method Request
+ </entry>
+ <entry>
+ This message contains a method request.
+ </entry>
+ </row>
+ <row>
+ <entry>
+ 'm'
+ </entry>
+ <entry>
+ Method Response
+ </entry>
+ <entry>
+ This message contains a method result.
+ </entry>
+ </row>
+ </tbody>
+ </tgroup></table>
+<!--h4--></section>
+
+ <section role="h4" id="ManagementDesignnotes-BrokerRequestMessage"><title>
+ Broker
+ Request Message
+ </title>
+
+ <para>
+ When a management client first establishes contact with the
+ broker, it sends a Hello message to initiate the exchange.
+ </para>
+ <programlisting>
+ +-----+-----+-----+-----+-----------------------+
+ | 'A' | 'M' | '1' | 'B' | 0 |
+ +-----+-----+-----+-----+-----------------------+
+</programlisting>
+ <para>
+ The Broker Request message has no payload.
+ </para>
+<!--h4--></section>
+
+ <section role="h4" id="ManagementDesignnotes-BrokerResponseMessage"><title>
+ Broker
+ Response Message
+ </title>
+
+ <para>
+ When the broker receives a Broker Request message, it responds
+ with a Broker Response message. This message contains an
+ identifier unique to the broker.
+ </para>
+ <programlisting>
+ +-----+-----+-----+-----+-----------------------+
+ | 'A' | 'M' | '1' | 'b' | 0 |
+ +-----+-----+-----+-----+-----------------------+----------------------------+
+ | brokerId (uuid) |
+ +----------------------------------------------------------------------------+
+</programlisting>
+<!--h4--></section>
+
+ <section role="h4" id="ManagementDesignnotes-CommandCompletionMessage"><title>
+ Command
+ Completion Message
+ </title>
+
+
+ <programlisting>
+ +-----+-----+-----+-----+-----------------------+
+ | 'A' | 'M' | '1' | 'z' | seq |
+ +-----+-----+-----+-----+-----------------------+
+ | Completion Code |
+ +-----------------------+-----------------------------------------+
+ | Completion Text |
+ +-----------------------------------------------------------------+
+</programlisting>
+<!--h4--></section>
+
+
+ <section role="h4" id="ManagementDesignnotes-ClassQuery"><title>
+ Class Query
+ </title>
+
+ <programlisting>
+ +-----+-----+-----+-----+-----------------------+
+ | 'A' | 'M' | '1' | 'Q' | seq |
+ +-----+-----+-----+-----+-----------------------+----------+
+ | package name (str8) |
+ +----------------------------------------------------------+
+</programlisting>
+<!--h4--></section>
+
+
+ <section role="h4" id="ManagementDesignnotes-ClassIndication"><title>
+ Class
+ Indication
+ </title>
+
+
+ <programlisting>
+ +-----+-----+-----+-----+-----------------------+
+ | 'A' | 'M' | '1' | 'q' | seq |
+ +-----+-----+-----+-----+-----------------------+----------+
+ | package name (str8) |
+ +----------------------------------------------------------+
+ | class name (str8) |
+ +----------------------------------------------------------+
+ | schema hash (bin128) |
+ +----------------------------------------------------------+
+</programlisting>
+<!--h4--></section>
+
+
+ <section role="h4" id="ManagementDesignnotes-SchemaRequest"><title>
+ Schema Request
+ </title>
+
+
+ <programlisting>
+ +-----+-----+-----+-----+-----------------------+
+ | 'A' | 'M' | '1' | 'S' | seq |
+ +-----+-----+-----+-----+-----------------------+----------+
+ | packageName (str8) |
+ +----------------------------------------------------------+
+ | className (str8) |
+ +----------------------------------------------------------+
+ | schema-hash (bin128) |
+ +----------------------------------------------------------+
+</programlisting>
+<!--h4--></section>
+
+ <section role="h4" id="ManagementDesignnotes-SchemaResponse"><title>
+ Schema
+ Response
+ </title>
+
+ <programlisting>
+ +-----+-----+-----+-----+-----------------------+
+ | 'A' | 'M' | '1' | 's' | seq |
+ +-----+-----+-----+-----+-----------------------+----------+
+ | packageName (str8) |
+ +----------------------------------------------------------+
+ | className (str8) |
+ +----------------------------------------------------------+
+ | schema-hash (bin128) |
+ +-----------+-----------+-----------+-----------+----------+
+ | propCnt | statCnt | methodCnt | eventCnt |
+ +-----------+-----------+-----------+-----------+----------------------------+
+ | propCnt property records |
+ +----------------------------------------------------------------------------+
+ | statCnt statistic records |
+ +----------------------------------------------------------------------------+
+ | methodCnt method records |
+ +----------------------------------------------------------------------------+
+ | eventCnt event records |
+ +----------------------------------------------------------------------------+
+</programlisting>
+ <para>
+ Each <emphasis>property</emphasis> record is an AMQP map with the following
+ fields. Optional fields may optionally be omitted from the map.
+ </para><table><title/><tgroup cols="3">
+ <tbody>
+ <row>
+ <entry>
+ <emphasis>field name</emphasis>
+ </entry>
+ <entry>
+ <emphasis>optional</emphasis>
+ </entry>
+ <entry>
+ <emphasis>description</emphasis>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ name
+ </entry>
+ <entry>
+ no
+ </entry>
+ <entry>
+ Name of the property
+ </entry>
+ </row>
+ <row>
+ <entry>
+ type
+ </entry>
+ <entry>
+ no
+ </entry>
+ <entry>
+ Type code for the property
+ </entry>
+ </row>
+ <row>
+ <entry>
+ access
+ </entry>
+ <entry>
+ no
+ </entry>
+ <entry>
+ Access code for the property
+ </entry>
+ </row>
+ <row>
+ <entry>
+ index
+ </entry>
+ <entry>
+ no
+ </entry>
+ <entry>
+ 1 = index element, 0 = not an index element
+ </entry>
+ </row>
+ <row>
+ <entry>
+ optional
+ </entry>
+ <entry>
+ no
+ </entry>
+ <entry>
+ 1 = optional element (may be not present), 0 = mandatory
+ (always present)
+ </entry>
+ </row>
+ <row>
+ <entry>
+ unit
+ </entry>
+ <entry>
+ yes
+ </entry>
+ <entry>
+ Units for numeric values (i.e. seconds, bytes, etc.)
+ </entry>
+ </row>
+ <row>
+ <entry>
+ min
+ </entry>
+ <entry>
+ yes
+ </entry>
+ <entry>
+ Minimum value for numerics
+ </entry>
+ </row>
+ <row>
+ <entry>
+ max
+ </entry>
+ <entry>
+ yes
+ </entry>
+ <entry>
+ Maximum value for numerics
+ </entry>
+ </row>
+ <row>
+ <entry>
+ maxlen
+ </entry>
+ <entry>
+ yes
+ </entry>
+ <entry>
+ Maximum length for strings
+ </entry>
+ </row>
+ <row>
+ <entry>
+ desc
+ </entry>
+ <entry>
+ yes
+ </entry>
+ <entry>
+ Description of the property
+ </entry>
+ </row>
+ </tbody>
+ </tgroup></table><para>
+ Each <emphasis>statistic</emphasis> record is an AMQP map with the following
+ fields:
+ </para><table><title/><tgroup cols="3">
+ <tbody>
+ <row>
+ <entry>
+ <emphasis>field name</emphasis>
+ </entry>
+ <entry>
+ <emphasis>optional</emphasis>
+ </entry>
+ <entry>
+ <emphasis>description</emphasis>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ name
+ </entry>
+ <entry>
+ no
+ </entry>
+ <entry>
+ Name of the statistic
+ </entry>
+ </row>
+ <row>
+ <entry>
+ type
+ </entry>
+ <entry>
+ no
+ </entry>
+ <entry>
+ Type code for the statistic
+ </entry>
+ </row>
+ <row>
+ <entry>
+ unit
+ </entry>
+ <entry>
+ yes
+ </entry>
+ <entry>
+ Units for numeric values (i.e. seconds, bytes, etc.)
+ </entry>
+ </row>
+ <row>
+ <entry>
+ desc
+ </entry>
+ <entry>
+ yes
+ </entry>
+ <entry>
+ Description of the statistic
+ </entry>
+ </row>
+ </tbody>
+ </tgroup></table><para>
+ <emphasis>method</emphasis> and <emphasis>event</emphasis> records contain a main map that
+ describes the method or header followed by zero or more maps
+ describing arguments. The main map contains the following fields:
+ </para><table><title/><tgroup cols="3">
+ <tbody>
+ <row>
+ <entry>
+ <emphasis>field name</emphasis>
+ </entry>
+ <entry>
+ <emphasis>optional</emphasis>
+ </entry>
+ <entry>
+ <emphasis>description</emphasis>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ name
+ </entry>
+ <entry>
+ no
+ </entry>
+ <entry>
+ Name of the method or event
+ </entry>
+ </row>
+ <row>
+ <entry>
+ argCount
+ </entry>
+ <entry>
+ no
+ </entry>
+ <entry>
+ Number of argument records to follow
+ </entry>
+ </row>
+ <row>
+ <entry>
+ desc
+ </entry>
+ <entry>
+ yes
+ </entry>
+ <entry>
+ Description of the method or event
+ </entry>
+ </row>
+ </tbody>
+ </tgroup></table><para>
+ Argument maps contain the following fields:
+ </para><table><title/><tgroup cols="5">
+ <tbody>
+ <row>
+ <entry>
+ <emphasis>field name</emphasis>
+ </entry>
+ <entry>
+ <emphasis>method</emphasis>
+ </entry>
+ <entry>
+ <emphasis>event</emphasis>
+ </entry>
+ <entry>
+ <emphasis>optional</emphasis>
+ </entry>
+ <entry>
+ <emphasis>description</emphasis>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ name
+ </entry>
+ <entry>
+ yes
+ </entry>
+ <entry>
+ yes
+ </entry>
+ <entry>
+ no
+ </entry>
+ <entry>
+ Argument name
+ </entry>
+ </row>
+ <row>
+ <entry>
+ type
+ </entry>
+ <entry>
+ yes
+ </entry>
+ <entry>
+ yes
+ </entry>
+ <entry>
+ no
+ </entry>
+ <entry>
+ Type code for the argument
+ </entry>
+ </row>
+ <row>
+ <entry>
+ dir
+ </entry>
+ <entry>
+ yes
+ </entry>
+ <entry>
+ no
+ </entry>
+ <entry>
+ yes
+ </entry>
+ <entry>
+ Direction code for method arguments
+ </entry>
+ </row>
+ <row>
+ <entry>
+ unit
+ </entry>
+ <entry>
+ yes
+ </entry>
+ <entry>
+ yes
+ </entry>
+ <entry>
+ yes
+ </entry>
+ <entry>
+ Units for numeric values (i.e. seconds, bytes, etc.)
+ </entry>
+ </row>
+ <row>
+ <entry>
+ min
+ </entry>
+ <entry>
+ yes
+ </entry>
+ <entry>
+ no
+ </entry>
+ <entry>
+ yes
+ </entry>
+ <entry>
+ Minimum value for numerics
+ </entry>
+ </row>
+ <row>
+ <entry>
+ max
+ </entry>
+ <entry>
+ yes
+ </entry>
+ <entry>
+ no
+ </entry>
+ <entry>
+ yes
+ </entry>
+ <entry>
+ Maximum value for numerics
+ </entry>
+ </row>
+ <row>
+ <entry>
+ maxlen
+ </entry>
+ <entry>
+ yes
+ </entry>
+ <entry>
+ no
+ </entry>
+ <entry>
+ yes
+ </entry>
+ <entry>
+ Maximum length for strings
+ </entry>
+ </row>
+ <row>
+ <entry>
+ desc
+ </entry>
+ <entry>
+ yes
+ </entry>
+ <entry>
+ yes
+ </entry>
+ <entry>
+ yes
+ </entry>
+ <entry>
+ Description of the argument
+ </entry>
+ </row>
+ <row>
+ <entry>
+ default
+ </entry>
+ <entry>
+ yes
+ </entry>
+ <entry>
+ no
+ </entry>
+ <entry>
+ yes
+ </entry>
+ <entry>
+ Default value for the argument
+ </entry>
+ </row>
+ </tbody>
+ </tgroup></table><para>
+ <emphasis>type codes</emphasis> are numerics with the following values:
+ </para><table><title/><tgroup cols="2">
+ <tbody>
+ <row>
+ <entry>
+ <emphasis>value</emphasis>
+ </entry>
+ <entry>
+ <emphasis>type</emphasis>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ 1
+ </entry>
+ <entry>
+ uint8
+ </entry>
+ </row>
+ <row>
+ <entry>
+ 2
+ </entry>
+ <entry>
+ uint16
+ </entry>
+ </row>
+ <row>
+ <entry>
+ 3
+ </entry>
+ <entry>
+ uint32
+ </entry>
+ </row>
+ <row>
+ <entry>
+ 4
+ </entry>
+ <entry>
+ uint64
+ </entry>
+ </row>
+ <row>
+ <entry>
+ 6
+ </entry>
+ <entry>
+ str8
+ </entry>
+ </row>
+ <row>
+ <entry>
+ 7
+ </entry>
+ <entry>
+ str16
+ </entry>
+ </row>
+ <row>
+ <entry>
+ 8
+ </entry>
+ <entry>
+ absTime(uint64)
+ </entry>
+ </row>
+ <row>
+ <entry>
+ 9
+ </entry>
+ <entry>
+ deltaTime(uint64)
+ </entry>
+ </row>
+ <row>
+ <entry>
+ 10
+ </entry>
+ <entry>
+ objectReference(uint64)
+ </entry>
+ </row>
+ <row>
+ <entry>
+ 11
+ </entry>
+ <entry>
+ boolean(uint8)
+ </entry>
+ </row>
+ <row>
+ <entry>
+ 12
+ </entry>
+ <entry>
+ float
+ </entry>
+ </row>
+ <row>
+ <entry>
+ 13
+ </entry>
+ <entry>
+ double
+ </entry>
+ </row>
+ <row>
+ <entry>
+ 14
+ </entry>
+ <entry>
+ uuid
+ </entry>
+ </row>
+ <row>
+ <entry>
+ 15
+ </entry>
+ <entry>
+ map
+ </entry>
+ </row>
+ <row>
+ <entry>
+ 16
+ </entry>
+ <entry>
+ int8
+ </entry>
+ </row>
+ <row>
+ <entry>
+ 17
+ </entry>
+ <entry>
+ int16
+ </entry>
+ </row>
+ <row>
+ <entry>
+ 18
+ </entry>
+ <entry>
+ int32
+ </entry>
+ </row>
+ <row>
+ <entry>
+ 19
+ </entry>
+ <entry>
+ int64
+ </entry>
+ </row>
+ </tbody>
+ </tgroup></table><para>
+ <emphasis>access codes</emphasis> are numerics with the following values:
+ </para><table><title/><tgroup cols="2">
+ <tbody>
+ <row>
+ <entry>
+ <emphasis>value</emphasis>
+ </entry>
+ <entry>
+ <emphasis>access</emphasis>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ 1
+ </entry>
+ <entry>
+ Read-Create access
+ </entry>
+ </row>
+ <row>
+ <entry>
+ 2
+ </entry>
+ <entry>
+ Read-Write access
+ </entry>
+ </row>
+ <row>
+ <entry>
+ 3
+ </entry>
+ <entry>
+ Read-Only access
+ </entry>
+ </row>
+ </tbody>
+ </tgroup></table><para>
+ <emphasis>direction codes</emphasis> are numerics with the following values:
+ </para><table><title/><tgroup cols="2">
+ <tbody>
+ <row>
+ <entry>
+ <emphasis>value</emphasis>
+ </entry>
+ <entry>
+ <emphasis>direction</emphasis>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ 1
+ </entry>
+ <entry>
+ Input (from client to broker)
+ </entry>
+ </row>
+ <row>
+ <entry>
+ 2
+ </entry>
+ <entry>
+ Output (from broker to client)
+ </entry>
+ </row>
+ <row>
+ <entry>
+ 3
+ </entry>
+ <entry>
+ IO (bidirectional)
+ </entry>
+ </row>
+ </tbody>
+ </tgroup></table>
+<!--h4--></section>
+
+
+ <section role="h4" id="ManagementDesignnotes-HeartbeatIndication"><title>
+ Heartbeat
+ Indication
+ </title>
+
+
+ <programlisting>
+ +-----+-----+-----+-----+-----------------------+
+ | 'A' | 'M' | '1' | 'h' | 0 |
+ +-----+-----+-----+-----+-----------------------+
+ | timestamp of current interval (datetime) |
+ +-----------------------------------------------+
+</programlisting>
+<!--h4--></section>
+
+ <section role="h4" id="ManagementDesignnotes-ConfigurationandInstrumentationContentMessages"><title>
+ Configuration and Instrumentation Content Messages
+ </title>
+
+ <para>
+ Content messages are published when changes are made to the
+ values of properties or statistics or when new management clients
+ bind a queue to the management exchange.
+ </para>
+ <programlisting>
+ +-----+-----+-----+-------+-----------------------+
+ | 'A' | 'M' | '1' |'g/c/i'| seq |
+ +-----+-----+-----+-------+-----------------------+--------+
+ | packageName (str8) |
+ +----------------------------------------------------------+
+ | className (str8) |
+ +----------------------------------------------------------+
+ | class hash (bin128) |
+ +-----+-----+-----+-----+-----+-----+-----+-----+----------+
+ | timestamp of current sample (datetime) |
+ +-----+-----+-----+-----+-----+-----+-----+-----+
+ | time object was created (datetime) |
+ +-----+-----+-----+-----+-----+-----+-----+-----+
+ | time object was deleted (datetime) |
+ +-----+-----+-----+-----+-----+-----+-----+-----+
+ | objectId (uint64) |
+ +-----+-----+-----+-----+-----+-----+-----+-----+
+ | presence bitmasks (0 or more uint8 fields) |
+ +-----+-----+-----+-----+-----+-----+-----+-----+------------------------+
+ | config/inst values (in schema order) |
+ +------------------------------------------------------------------------+
+</programlisting>
+ <para>
+ All timestamps are uint64 values representing nanoseconds since
+ the epoch (January 1, 1970). The objectId is a uint64 value that
+ uniquely identifies this object instance.
+ </para><para>
+ If any of the properties in the object are defined as optional,
+ there will be 1 or more "presence bitmask" octets. There are as
+ many octets as are needed to provide one bit per optional
+ property. The bits are assigned to the optional properties in
+ schema order (first octet first, lowest order bit first).
+ </para><para>
+ For example: If there are two optional properties in the schema
+ called "option1" and "option2" (defined in that order), there
+ will be one presence bitmask octet and the bits will be assigned
+ as bit 0 controls option1 and bit 1 controls option2.
+ </para><para>
+ If the bit for a particular optional property is set (1), the
+ property will be encoded normally in the "values" portion of the
+ message. If the bit is clear (0), the property will be omitted
+ from the list of encoded values and will be considered "NULL" or
+ "not present".
+ </para><para>
+ The element values are encoded by their type into the message in
+ the order in which they appeared in the schema message.
+ </para>
+<!--h4--></section>
+
+ <section role="h4" id="ManagementDesignnotes-GetQueryMessage"><title>
+ Get Query
+ Message
+ </title>
+
+ <para>
+ A Get Request may be sent by the management console to cause a
+ management agent to immediately send content information for
+ objects of a class.
+ </para>
+ <programlisting>
+ +-----+-----+-----+-----+-----------------------+
+ | 'A' | 'M' | '1' | 'G' | seq |
+ +-----+-----+-----+-----+-----------------------+----------+
+ | Get request field table |
+ +----------------------------------------------------------+
+</programlisting>
+ <para>
+ The content of a get request is a field table that specifies what
+ objects are being requested. Most of the fields are optional and
+ are available for use in more extensive deployments.
+ </para><table><title/><tgroup cols="4">
+ <tbody>
+ <row>
+ <entry>
+ <emphasis>Field Key</emphasis>
+ </entry>
+ <entry>
+ <emphasis>Mandatory</emphasis>
+ </entry>
+ <entry>
+ <emphasis>Type</emphasis>
+ </entry>
+ <entry>
+ <emphasis>Description</emphasis>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ "_class"
+ </entry>
+ <entry>
+ yes
+ </entry>
+ <entry>
+ short-string
+ </entry>
+ <entry>
+ The name of the class of objects being requested.
+ </entry>
+ </row>
+ <row>
+ <entry>
+ "_package"
+ </entry>
+ <entry>
+ no
+ </entry>
+ <entry>
+ short-string
+ </entry>
+ <entry>
+ The name of the extension package the class belongs to. If
+ omitted, the package defaults to "qpid" for access to
+ objects in the connected broker.
+ </entry>
+ </row>
+ <row>
+ <entry>
+ "_agent"
+ </entry>
+ <entry>
+ no
+ </entry>
+ <entry>
+ uuid
+ </entry>
+ <entry>
+ The management agent that is the target of the request. If
+ omitted, agent defaults to the connected broker.
+ </entry>
+ </row>
+ </tbody>
+ </tgroup></table><para>
+ When the management agent receives a get request, it sends
+ content messages describing the requested objects. Once the last
+ content message is sent, it then sends a Command Completion
+ message with the same sequence number supplied in the request to
+ indicate to the requestor that there are no more messages coming.
+ </para>
+<!--h4--></section>
+
+
+ <section role="h4" id="ManagementDesignnotes-MethodRequest"><title>
+ Method Request
+ </title>
+
+ <para>
+ Method request messages have the following structure. The
+ sequence number is opaque to the management agent. It is returned
+ unchanged in the method reply so the calling client can correctly
+ associate the reply to the request. The objectId is the unique ID
+ of the object on which the method is to be executed.
+ </para>
+ <programlisting>
+ +-----+-----+-----+-----+-----------------------+
+ | 'A' | 'M' | '1' | 'M' | seq |
+ +-----+-----+-----+-----+-----------------------+
+ | objectId (uint64) |
+ +-----------------------------------------------+
+ | methodName (str8) |
+ +-----------------------------------------------+------------------------+
+ | input and bidirectional argument values (in schema order) |
+ +------------------------------------------------------------------------+
+</programlisting>
+<!--h4--></section>
+
+ <section role="h4" id="ManagementDesignnotes-MethodResponse"><title>
+ Method
+ Response
+ </title>
+
+ <para>
+ Method reply messages have the following structure. The sequence
+ number is identical to that supplied in the method request. The
+ status code (and text) indicate whether or not the method was
+ successful and if not, what the error was. Output and
+ bidirectional arguments are only included if the status code was
+ 0 (STATUS_OK).
+ </para>
+ <programlisting>
+ +-----+-----+-----+-----+-----------------------+
+ | 'A' | 'M' | '1' | 'm' | seq |
+ +-----+-----+-----+-----+-----------------------+
+ | status code |
+ +-----------------------+----------------------------------+
+ | status text (str8) |
+ +-----------------------+----------------------------------+-------------+
+ | output and bidirectional argument values (in schema order) |
+ +------------------------------------------------------------------------+
+</programlisting>
+ <para>
+ <emphasis>status code</emphasis> values are:
+ </para><table><title/><tgroup cols="2">
+ <tbody>
+ <row>
+ <entry>
+ <emphasis>value</emphasis>
+ </entry>
+ <entry>
+ <emphasis>description</emphasis>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ 0
+ </entry>
+ <entry>
+ STATUS_OK - successful completion
+ </entry>
+ </row>
+ <row>
+ <entry>
+ 1
+ </entry>
+ <entry>
+ STATUS_UNKNOWN_OBJECT - objectId not found in the agent
+ </entry>
+ </row>
+ <row>
+ <entry>
+ 2
+ </entry>
+ <entry>
+ STATUS_UNKNOWN_METHOD - method is not known by the object
+ type
+ </entry>
+ </row>
+ <row>
+ <entry>
+ 3
+ </entry>
+ <entry>
+ STATUS_NOT_IMPLEMENTED - method is not currently
+ implemented
+ </entry>
+ </row>
+ </tbody>
+ </tgroup></table>
+<!--h4--></section>
+<!--h3--></section>
+
+ <section role="h3" id="ManagementDesignnotes-MessagesforExtendedScenario"><title>
+ Messages
+ for Extended Scenario
+ </title>
+
+ <section role="h4" id="ManagementDesignnotes-ExtendedManagementProtocol"><title>
+ Extended
+ Management Protocol
+ </title>
+
+ <para>
+ Qpid supports management extensions that allow the management
+ broker to be a central point for the management of multiple
+ external entities with their own management schemas.
+ </para>
+ <programlisting>
+ Broker Remote Agent
+ | |
+ | &lt;----------------------------------------- Attach Request --- |
+ | --- Attach Response ----------------------------------------&gt; |
+ | |
+ | &lt;------------------------------------- Package Indication --- |
+ | &lt;------------------------------------- Package Indication --- |
+ | |
+ | &lt;--------------------------------------- Class Indication --- |
+ | &lt;--------------------------------------- Class Indication --- |
+ | &lt;--------------------------------------- Class Indication --- |
+ | &lt;--------------------------------------- Class Indication --- |
+ | &lt;--------------------------------------- Class Indication --- |
+ | |
+ | --- Schema Request (class key) -----------------------------&gt; |
+ | &lt;---------------------------------------- Schema Response --- |
+ | |
+ | --- Schema Request (class key) -----------------------------&gt; |
+ | &lt;---------------------------------------- Schema Response --- |
+ | |
+ | |
+</programlisting>
+<!--h4--></section>
+
+ <section role="h4" id="ManagementDesignnotes-ExtendedOpcodes"><title>
+ Extended
+ Opcodes
+ </title>
+
+ <table><title/><tgroup cols="3">
+ <tbody>
+ <row>
+ <entry>
+ <emphasis>opcode</emphasis>
+ </entry>
+ <entry>
+ <emphasis>message</emphasis>
+ </entry>
+ <entry>
+ <emphasis>description</emphasis>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ 'P'
+ </entry>
+ <entry>
+ Package Query
+ </entry>
+ <entry>
+ This message contains a schema package query request,
+ requesting that the broker dump the list of known packages
+ </entry>
+ </row>
+ <row>
+ <entry>
+ 'p'
+ </entry>
+ <entry>
+ Package Indication
+ </entry>
+ <entry>
+ This message contains a schema package indication,
+ identifying a package known by the broker
+ </entry>
+ </row>
+ <row>
+ <entry>
+ 'A'
+ </entry>
+ <entry>
+ Agent Attach Request
+ </entry>
+ <entry>
+ This message is sent by a remote agent when it wishes to
+ attach to a management broker
+ </entry>
+ </row>
+ <row>
+ <entry>
+ 'a'
+ </entry>
+ <entry>
+ Agent Attach Response
+ </entry>
+ <entry>
+ The management broker sends this response if an attaching
+ remote agent is permitted to join
+ </entry>
+ </row>
+ <row>
+ <entry>
+ 'x'
+ </entry>
+ <entry>
+ Console Added Indication
+ </entry>
+ <entry>
+ This message is sent to all remote agents by the management
+ broker when a new console binds to the management exchange
+ </entry>
+ </row>
+ </tbody>
+ </tgroup></table>
+<!--h4--></section>
+
+
+ <section role="h4" id="ManagementDesignnotes-PackageQuery"><title>
+ Package Query
+ </title>
+
+
+ <programlisting>
+ +-----+-----+-----+-----+-----------------------+
+ | 'A' | 'M' | '1' | 'P' | seq |
+ +-----+-----+-----+-----+-----------------------+
+</programlisting>
+<!--h4--></section>
+
+ <section role="h4" id="ManagementDesignnotes-PackageIndication"><title>
+ Package
+ Indication
+ </title>
+
+
+ <programlisting>
+ +-----+-----+-----+-----+-----------------------+
+ | 'A' | 'M' | '1' | 'p' | seq |
+ +-----+-----+-----+-----+-----------------------+----------+
+ | package name (str8) |
+ +----------------------------------------------------------+
+</programlisting>
+<!--h4--></section>
+
+ <section role="h4" id="ManagementDesignnotes-AttachRequest"><title>
+ Attach Request
+ </title>
+
+ <programlisting>
+ +-----+-----+-----+-----+-----------------------+
+ | 'A' | 'M' | '1' | 'A' | seq |
+ +-----+-----+-----+-----+-----------------------+----------+
+ | label (str8) |
+ +-----------------------+----------------------------------+
+ | system-id (uuid) |
+ +-----------------------+----------------------------------+
+ | requested objId bank |
+ +-----------------------+
+</programlisting>
+<!--h4--></section>
+
+ <section role="h4" id="ManagementDesignnotes-AttachResponse-28success-29"><title>
+ Attach
+ Response (success)
+ </title>
+
+
+ <programlisting>
+ +-----+-----+-----+-----+-----------------------+
+ | 'A' | 'M' | '1' | 'a' | seq |
+ +-----+-----+-----+-----+-----------------------+
+ | assigned broker bank |
+ +-----------------------+
+ | assigned objId bank |
+ +-----------------------+
+</programlisting>
+<!--h4--></section>
+
+ <section role="h4" id="ManagementDesignnotes-ConsoleAddedIndication"><title>
+ Console Added
+ Indication
+ </title>
+
+
+ <programlisting>
+ +-----+-----+-----+-----+-----------------------+
+ | 'A' | 'M' | '1' | 'x' | seq |
+ +-----+-----+-----+-----+-----------------------+
+</programlisting>
+
+
+
+ <!--h4--></section>
+ <!--h3--></section>
+ <!--h2--></section>
+
+
+</section>
+
diff --git a/qpid/doc/book/src/Managing-CPP-Broker.xml b/qpid/doc/book/src/Managing-CPP-Broker.xml
new file mode 100644
index 0000000000..2cb4def764
--- /dev/null
+++ b/qpid/doc/book/src/Managing-CPP-Broker.xml
@@ -0,0 +1,462 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+
+ 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.
+
+-->
+
+<section id="section-Managing-CPP-Broker">
+ <title> Managing the C++ Broker </title>
+ <para>
+ There are quite a few ways to interact with the C++ broker. The
+ command line tools
+ include:
+ </para><itemizedlist>
+ <listitem><para>qpid-route - used to configure federation (a set of federated
+ brokers)
+ </para></listitem>
+ <listitem><para>qpid-config - used to configure queues, exchanges, bindings
+ and list them etc
+ </para></listitem>
+ <listitem><para>qpid-tool - used to view management information/statistics
+ and call any management actions on the broker
+ </para></listitem>
+ <listitem><para>qpid-printevents - used to receive and print QMF events
+ </para></listitem>
+ </itemizedlist>
+
+ <section role="h3" id="MgmtC-2B-2B-Usingqpidconfig"><title>
+ Using qpid-config
+ </title>
+ <para>
+ This utility can be used to create queues exchanges and bindings,
+ both durable and transient. Always check for latest options by
+ running --help command.
+ </para>
+ <programlisting>
+$ qpid-config --help
+Usage: qpid-config [OPTIONS]
+ qpid-config [OPTIONS] exchanges [filter-string]
+ qpid-config [OPTIONS] queues [filter-string]
+ qpid-config [OPTIONS] add exchange &lt;type&gt; &lt;name&gt; [AddExchangeOptions]
+ qpid-config [OPTIONS] del exchange &lt;name&gt;
+ qpid-config [OPTIONS] add queue &lt;name&gt; [AddQueueOptions]
+ qpid-config [OPTIONS] del queue &lt;name&gt;
+ qpid-config [OPTIONS] bind &lt;exchange-name&gt; &lt;queue-name&gt; [binding-key]
+ qpid-config [OPTIONS] unbind &lt;exchange-name&gt; &lt;queue-name&gt; [binding-key]
+
+Options:
+ -b [ --bindings ] Show bindings in queue or exchange list
+ -a [ --broker-addr ] Address (localhost) Address of qpidd broker
+ broker-addr is in the form: [username/password@] hostname | ip-address [:&lt;port&gt;]
+ ex: localhost, 10.1.1.7:10000, broker-host:10000, guest/guest@localhost
+
+Add Queue Options:
+ --durable Queue is durable
+ --cluster-durable Queue becomes durable if there is only one functioning cluster node
+ --file-count N (8) Number of files in queue's persistence journal
+ --file-size N (24) File size in pages (64Kib/page)
+ --max-queue-size N Maximum in-memory queue size as bytes
+ --max-queue-count N Maximum in-memory queue size as a number of messages
+ --limit-policy [none | reject | flow-to-disk | ring | ring-strict]
+ Action taken when queue limit is reached:
+ none (default) - Use broker's default policy
+ reject - Reject enqueued messages
+ flow-to-disk - Page messages to disk
+ ring - Replace oldest unacquired message with new
+ ring-strict - Replace oldest message, reject if oldest is acquired
+ --order [fifo | lvq | lvq-no-browse]
+ Set queue ordering policy:
+ fifo (default) - First in, first out
+ lvq - Last Value Queue ordering, allows queue browsing
+ lvq-no-browse - Last Value Queue ordering, browsing clients may lose data
+ --generate-queue-events N
+ If set to 1, every enqueue will generate an event that can be processed by
+ registered listeners (e.g. for replication). If set to 2, events will be
+ generated for enqueues and dequeues
+
+Add Exchange Options:
+ --durable Exchange is durable
+ --sequence Exchange will insert a 'qpid.msg_sequence' field in the message header
+ with a value that increments for each message forwarded.
+ --ive Exchange will behave as an 'initial-value-exchange', keeping a reference
+ to the last message forwarded and enqueuing that message to newly bound
+ queues.
+</programlisting>
+ <para>
+ Get the summary page
+ </para>
+ <programlisting>
+$ qpid-config
+Total Exchanges: 6
+ topic: 2
+ headers: 1
+ fanout: 1
+ direct: 2
+ Total Queues: 7
+ durable: 0
+ non-durable: 7
+</programlisting>
+ <para>
+ List the queues
+ </para>
+ <programlisting>
+$ qpid-config queues
+Queue Name Attributes
+=================================================================
+pub_start
+pub_done
+sub_ready
+sub_done
+perftest0 --durable
+reply-dhcp-100-18-254.bos.redhat.com.20713 auto-del excl
+topic-dhcp-100-18-254.bos.redhat.com.20713 auto-del excl
+
+</programlisting>
+ <para>
+ List the exchanges with bindings
+ </para>
+ <programlisting>
+$ ./qpid-config -b exchanges
+Exchange '' (direct)
+ bind pub_start =&gt; pub_start
+ bind pub_done =&gt; pub_done
+ bind sub_ready =&gt; sub_ready
+ bind sub_done =&gt; sub_done
+ bind perftest0 =&gt; perftest0
+ bind mgmt-3206ff16-fb29-4a30-82ea-e76f50dd7d15 =&gt; mgmt-3206ff16-fb29-4a30-82ea-e76f50dd7d15
+ bind repl-3206ff16-fb29-4a30-82ea-e76f50dd7d15 =&gt; repl-3206ff16-fb29-4a30-82ea-e76f50dd7d15
+Exchange 'amq.direct' (direct)
+ bind repl-3206ff16-fb29-4a30-82ea-e76f50dd7d15 =&gt; repl-3206ff16-fb29-4a30-82ea-e76f50dd7d15
+ bind repl-df06c7a6-4ce7-426a-9f66-da91a2a6a837 =&gt; repl-df06c7a6-4ce7-426a-9f66-da91a2a6a837
+ bind repl-c55915c2-2fda-43ee-9410-b1c1cbb3e4ae =&gt; repl-c55915c2-2fda-43ee-9410-b1c1cbb3e4ae
+Exchange 'amq.topic' (topic)
+Exchange 'amq.fanout' (fanout)
+Exchange 'amq.match' (headers)
+Exchange 'qpid.management' (topic)
+ bind mgmt.# =&gt; mgmt-3206ff16-fb29-4a30-82ea-e76f50dd7d15
+</programlisting>
+<!--h3--></section>
+
+ <section role="h3" id="MgmtC-2B-2B-Usingqpidroute"><title>
+ Using qpid-route
+ </title>
+ <para>
+ This utility is to create federated networks of brokers, This
+ allows you for forward messages between brokers in a network.
+ Messages can be routed statically (using "qpid-route route add")
+ where the bindings that control message forwarding are supplied
+ in the route. Message routing can also be dynamic (using
+ "qpid-route dynamic add") where the messages are automatically
+ forwarded to clients based on their bindings to the local broker.
+ </para>
+ <programlisting>
+$ qpid-route
+Usage: qpid-route [OPTIONS] dynamic add &lt;dest-broker&gt; &lt;src-broker&gt; &lt;exchange&gt; [tag] [exclude-list]
+ qpid-route [OPTIONS] dynamic del &lt;dest-broker&gt; &lt;src-broker&gt; &lt;exchange&gt;
+
+ qpid-route [OPTIONS] route add &lt;dest-broker&gt; &lt;src-broker&gt; &lt;exchange&gt; &lt;routing-key&gt; [tag] [exclude-list]
+ qpid-route [OPTIONS] route del &lt;dest-broker&gt; &lt;src-broker&gt; &lt;exchange&gt; &lt;routing-key&gt;
+ qpid-route [OPTIONS] queue add &lt;dest-broker&gt; &lt;src-broker&gt; &lt;exchange&gt; &lt;queue&gt;
+ qpid-route [OPTIONS] queue del &lt;dest-broker&gt; &lt;src-broker&gt; &lt;exchange&gt; &lt;queue&gt;
+ qpid-route [OPTIONS] route list [&lt;dest-broker&gt;]
+ qpid-route [OPTIONS] route flush [&lt;dest-broker&gt;]
+ qpid-route [OPTIONS] route map [&lt;broker&gt;]
+
+ qpid-route [OPTIONS] link add &lt;dest-broker&gt; &lt;src-broker&gt;
+ qpid-route [OPTIONS] link del &lt;dest-broker&gt; &lt;src-broker&gt;
+ qpid-route [OPTIONS] link list [&lt;dest-broker&gt;]
+
+Options:
+ -v [ --verbose ] Verbose output
+ -q [ --quiet ] Quiet output, don't print duplicate warnings
+ -d [ --durable ] Added configuration shall be durable
+ -e [ --del-empty-link ] Delete link after deleting last route on the link
+ -s [ --src-local ] Make connection to source broker (push route)
+ -t &lt;transport&gt; [ --transport &lt;transport&gt;]
+ Specify transport to use for links, defaults to tcp
+
+ dest-broker and src-broker are in the form: [username/password@] hostname | ip-address [:&lt;port&gt;]
+ ex: localhost, 10.1.1.7:10000, broker-host:10000, guest/guest@localhost
+</programlisting>
+ <para>
+ A few examples:
+ </para>
+ <programlisting>
+qpid-route dynamic add host1 host2 fed.topic
+qpid-route dynamic add host2 host1 fed.topic
+
+qpid-route -v route add host1 host2 hub1.topic hub2.topic.stock.buy
+qpid-route -v route add host1 host2 hub1.topic hub2.topic.stock.sell
+qpid-route -v route add host1 host2 hub1.topic 'hub2.topic.stock.#'
+qpid-route -v route add host1 host2 hub1.topic 'hub2.#'
+qpid-route -v route add host1 host2 hub1.topic 'hub2.topic.#'
+qpid-route -v route add host1 host2 hub1.topic 'hub2.global.#'
+</programlisting>
+ <para>
+ The link map feature can be used to display the entire federated
+ network configuration by supplying a single broker as an entry
+ point:
+ </para>
+ <programlisting>
+$ qpid-route route map localhost:10001
+
+Finding Linked Brokers:
+ localhost:10001... Ok
+ localhost:10002... Ok
+ localhost:10003... Ok
+ localhost:10004... Ok
+ localhost:10005... Ok
+ localhost:10006... Ok
+ localhost:10007... Ok
+ localhost:10008... Ok
+
+Dynamic Routes:
+
+ Exchange fed.topic:
+ localhost:10002 &lt;=&gt; localhost:10001
+ localhost:10003 &lt;=&gt; localhost:10002
+ localhost:10004 &lt;=&gt; localhost:10002
+ localhost:10005 &lt;=&gt; localhost:10002
+ localhost:10006 &lt;=&gt; localhost:10005
+ localhost:10007 &lt;=&gt; localhost:10006
+ localhost:10008 &lt;=&gt; localhost:10006
+
+ Exchange fed.direct:
+ localhost:10002 =&gt; localhost:10001
+ localhost:10004 =&gt; localhost:10003
+ localhost:10003 =&gt; localhost:10002
+ localhost:10001 =&gt; localhost:10004
+
+Static Routes:
+
+ localhost:10003(ex=amq.direct) &lt;= localhost:10005(ex=amq.direct) key=rkey
+ localhost:10003(ex=amq.direct) &lt;= localhost:10005(ex=amq.direct) key=rkey2
+</programlisting>
+<!--h3--></section>
+
+ <section role="h3" id="MgmtC-2B-2B-Usingqpidtool"><title>
+ Using qpid-tool
+ </title>
+ <para>
+ This utility provided a telnet style interface to be able to
+ view, list all stats and action
+ all the methods. Simple capture below. Best to just play with it
+ and mail the list if you have
+ questions or want features added.
+ </para>
+ <programlisting>
+qpid:
+qpid: help
+Management Tool for QPID
+Commands:
+ list - Print summary of existing objects by class
+ list &lt;className&gt; - Print list of objects of the specified class
+ list &lt;className&gt; all - Print contents of all objects of specified class
+ list &lt;className&gt; active - Print contents of all non-deleted objects of specified class
+ list &lt;list-of-IDs&gt; - Print contents of one or more objects (infer className)
+ list &lt;className&gt; &lt;list-of-IDs&gt; - Print contents of one or more objects
+ list is space-separated, ranges may be specified (i.e. 1004-1010)
+ call &lt;ID&gt; &lt;methodName&gt; &lt;args&gt; - Invoke a method on an object
+ schema - Print summary of object classes seen on the target
+ schema &lt;className&gt; - Print details of an object class
+ set time-format short - Select short timestamp format (default)
+ set time-format long - Select long timestamp format
+ quit or ^D - Exit the program
+qpid: list
+Management Object Types:
+ ObjectType Active Deleted
+ ================================
+ qpid.binding 21 0
+ qpid.broker 1 0
+ qpid.client 1 0
+ qpid.exchange 6 0
+ qpid.queue 13 0
+ qpid.session 4 0
+ qpid.system 1 0
+ qpid.vhost 1 0
+qpid: list qpid.system
+Objects of type qpid.system
+ ID Created Destroyed Index
+ ==================================
+ 1000 21:00:02 - host
+qpid: list 1000
+Object of type qpid.system: (last sample time: 21:26:02)
+ Type Element 1000
+ =======================================================
+ config sysId host
+ config osName Linux
+ config nodeName localhost.localdomain
+ config release 2.6.24.4-64.fc8
+ config version #1 SMP Sat Mar 29 09:15:49 EDT 2008
+ config machine x86_64
+qpid: schema queue
+Schema for class 'qpid.queue':
+ Element Type Unit Access Notes Description
+ ===================================================================================================================
+ vhostRef reference ReadCreate index
+ name short-string ReadCreate index
+ durable boolean ReadCreate
+ autoDelete boolean ReadCreate
+ exclusive boolean ReadCreate
+ arguments field-table ReadOnly Arguments supplied in queue.declare
+ storeRef reference ReadOnly Reference to persistent queue (if durable)
+ msgTotalEnqueues uint64 message Total messages enqueued
+ msgTotalDequeues uint64 message Total messages dequeued
+ msgTxnEnqueues uint64 message Transactional messages enqueued
+ msgTxnDequeues uint64 message Transactional messages dequeued
+ msgPersistEnqueues uint64 message Persistent messages enqueued
+ msgPersistDequeues uint64 message Persistent messages dequeued
+ msgDepth uint32 message Current size of queue in messages
+ msgDepthHigh uint32 message Current size of queue in messages (High)
+ msgDepthLow uint32 message Current size of queue in messages (Low)
+ byteTotalEnqueues uint64 octet Total messages enqueued
+ byteTotalDequeues uint64 octet Total messages dequeued
+ byteTxnEnqueues uint64 octet Transactional messages enqueued
+ byteTxnDequeues uint64 octet Transactional messages dequeued
+ bytePersistEnqueues uint64 octet Persistent messages enqueued
+ bytePersistDequeues uint64 octet Persistent messages dequeued
+ byteDepth uint32 octet Current size of queue in bytes
+ byteDepthHigh uint32 octet Current size of queue in bytes (High)
+ byteDepthLow uint32 octet Current size of queue in bytes (Low)
+ enqueueTxnStarts uint64 transaction Total enqueue transactions started
+ enqueueTxnCommits uint64 transaction Total enqueue transactions committed
+ enqueueTxnRejects uint64 transaction Total enqueue transactions rejected
+ enqueueTxnCount uint32 transaction Current pending enqueue transactions
+ enqueueTxnCountHigh uint32 transaction Current pending enqueue transactions (High)
+ enqueueTxnCountLow uint32 transaction Current pending enqueue transactions (Low)
+ dequeueTxnStarts uint64 transaction Total dequeue transactions started
+ dequeueTxnCommits uint64 transaction Total dequeue transactions committed
+ dequeueTxnRejects uint64 transaction Total dequeue transactions rejected
+ dequeueTxnCount uint32 transaction Current pending dequeue transactions
+ dequeueTxnCountHigh uint32 transaction Current pending dequeue transactions (High)
+ dequeueTxnCountLow uint32 transaction Current pending dequeue transactions (Low)
+ consumers uint32 consumer Current consumers on queue
+ consumersHigh uint32 consumer Current consumers on queue (High)
+ consumersLow uint32 consumer Current consumers on queue (Low)
+ bindings uint32 binding Current bindings
+ bindingsHigh uint32 binding Current bindings (High)
+ bindingsLow uint32 binding Current bindings (Low)
+ unackedMessages uint32 message Messages consumed but not yet acked
+ unackedMessagesHigh uint32 message Messages consumed but not yet acked (High)
+ unackedMessagesLow uint32 message Messages consumed but not yet acked (Low)
+ messageLatencySamples delta-time nanosecond Broker latency through this queue (Samples)
+ messageLatencyMin delta-time nanosecond Broker latency through this queue (Min)
+ messageLatencyMax delta-time nanosecond Broker latency through this queue (Max)
+ messageLatencyAverage delta-time nanosecond Broker latency through this queue (Average)
+Method 'purge' Discard all messages on queue
+qpid: list queue
+Objects of type qpid.queue
+ ID Created Destroyed Index
+ ===========================================================================
+ 1012 21:08:13 - 1002.pub_start
+ 1014 21:08:13 - 1002.pub_done
+ 1016 21:08:13 - 1002.sub_ready
+ 1018 21:08:13 - 1002.sub_done
+ 1020 21:08:13 - 1002.perftest0
+ 1038 21:09:08 - 1002.mgmt-3206ff16-fb29-4a30-82ea-e76f50dd7d15
+ 1040 21:09:08 - 1002.repl-3206ff16-fb29-4a30-82ea-e76f50dd7d15
+ 1046 21:09:32 - 1002.mgmt-df06c7a6-4ce7-426a-9f66-da91a2a6a837
+ 1048 21:09:32 - 1002.repl-df06c7a6-4ce7-426a-9f66-da91a2a6a837
+ 1054 21:10:01 - 1002.mgmt-c55915c2-2fda-43ee-9410-b1c1cbb3e4ae
+ 1056 21:10:01 - 1002.repl-c55915c2-2fda-43ee-9410-b1c1cbb3e4ae
+ 1063 21:26:00 - 1002.mgmt-8d621997-6356-48c3-acab-76a37081d0f3
+ 1065 21:26:00 - 1002.repl-8d621997-6356-48c3-acab-76a37081d0f3
+qpid: list 1020
+Object of type qpid.queue: (last sample time: 21:26:02)
+ Type Element 1020
+ ==========================================================================
+ config vhostRef 1002
+ config name perftest0
+ config durable False
+ config autoDelete False
+ config exclusive False
+ config arguments {'qpid.max_size': 0, 'qpid.max_count': 0}
+ config storeRef NULL
+ inst msgTotalEnqueues 500000 messages
+ inst msgTotalDequeues 500000
+ inst msgTxnEnqueues 0
+ inst msgTxnDequeues 0
+ inst msgPersistEnqueues 0
+ inst msgPersistDequeues 0
+ inst msgDepth 0
+ inst msgDepthHigh 0
+ inst msgDepthLow 0
+ inst byteTotalEnqueues 512000000 octets
+ inst byteTotalDequeues 512000000
+ inst byteTxnEnqueues 0
+ inst byteTxnDequeues 0
+ inst bytePersistEnqueues 0
+ inst bytePersistDequeues 0
+ inst byteDepth 0
+ inst byteDepthHigh 0
+ inst byteDepthLow 0
+ inst enqueueTxnStarts 0 transactions
+ inst enqueueTxnCommits 0
+ inst enqueueTxnRejects 0
+ inst enqueueTxnCount 0
+ inst enqueueTxnCountHigh 0
+ inst enqueueTxnCountLow 0
+ inst dequeueTxnStarts 0
+ inst dequeueTxnCommits 0
+ inst dequeueTxnRejects 0
+ inst dequeueTxnCount 0
+ inst dequeueTxnCountHigh 0
+ inst dequeueTxnCountLow 0
+ inst consumers 0 consumers
+ inst consumersHigh 0
+ inst consumersLow 0
+ inst bindings 1 binding
+ inst bindingsHigh 1
+ inst bindingsLow 1
+ inst unackedMessages 0 messages
+ inst unackedMessagesHigh 0
+ inst unackedMessagesLow 0
+ inst messageLatencySamples 0
+ inst messageLatencyMin 0
+ inst messageLatencyMax 0
+ inst messageLatencyAverage 0
+qpid:
+</programlisting>
+<!--h3--></section>
+
+ <section role="h3" id="MgmtC-2B-2B-Usingqpidprintevents"><title>
+ Using
+ qpid-printevents
+ </title>
+ <para>
+ This utility connects to one or more brokers and collects events,
+ printing out a line per event.
+ </para>
+ <programlisting>
+$ qpid-printevents --help
+Usage: qpid-printevents [options] [broker-addr]...
+
+Collect and print events from one or more Qpid message brokers. If no broker-
+addr is supplied, qpid-printevents will connect to 'localhost:5672'. broker-
+addr is of the form: [username/password@] hostname | ip-address [:&lt;port&gt;] ex:
+localhost, 10.1.1.7:10000, broker-host:10000, guest/guest@localhost
+
+Options:
+ -h, --help show this help message and exit
+</programlisting>
+ <para>
+ You get the idea... have fun!
+ </para>
+<!--h3--></section>
+</section>
diff --git a/qpid/doc/book/src/MessageStore-Tool.xml b/qpid/doc/book/src/MessageStore-Tool.xml
new file mode 100644
index 0000000000..fdcb3cd560
--- /dev/null
+++ b/qpid/doc/book/src/MessageStore-Tool.xml
@@ -0,0 +1,150 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+
+ 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.
+
+-->
+
+<section><title>
+ MessageStore Tool
+ </title><section role="h2" id="MessageStoreTool-MessageStoreTool"><title>
+ MessageStore Tool
+ </title>
+
+ <para>
+ We have a number of implementations of the Qpid MessageStore
+ interface. This tool allows the interrogation of these stores
+ while the broker is offline.
+ </para>
+
+ <section role="h3" id="MessageStoreTool-MessageStoreImplementations"><title>
+ MessageStore
+ Implementations
+ </title>
+
+ <itemizedlist>
+ <listitem><para>
+ <xref linkend="qpid_BDBMessageStore--3rd-Party-"/>
+ </para></listitem>
+ <listitem><para>
+ <xref linkend="qpid_JDBCStore"/>
+ </para></listitem>
+ <listitem><para>
+ <xref linkend="qpid_MemoryMessageStore"/>
+ </para></listitem>
+ </itemizedlist>
+<!--h3--></section>
+
+ <section role="h3" id="MessageStoreTool-Introduction"><title>
+ Introduction
+ </title>
+
+ <para>
+ Each of the MessageStore implementations provide different back
+ end storage for their messages and so would need a different tool
+ to be able to interrogate their contents at the back end.
+ </para><para>
+ What this tool does is to utilise the Java broker code base to
+ access the contents of the storage providing the user with a
+ consistent means to inspect the storage contents in broker
+ memory. The tool allows the current messages in the store to be
+ inspected and copied/moved between queues. The tool uses the
+ message instance in memory for all its access paths, but changes
+ made will be reflected in the physical store (if one exists).
+ </para>
+<!--h3--></section>
+
+ <section role="h3" id="MessageStoreTool-Usage"><title>
+ Usage
+ </title>
+
+ <para>
+ The tools-distribution currently includes a unix shell command
+ 'msTool.sh' this script will launch the java tool.
+ </para><para>
+ The tool loads $QPID_HOME/etc/config.xml by default. If an
+ alternative broker configuration is required this should be
+ provided on the command line as would be done for the broker.
+ </para>
+ <programlisting>
+msTool.sh -c &lt;path to different config.xml&gt;
+</programlisting>
+ <para>
+ On startup the user is present with a command prompt
+ </para>
+ <programlisting>
+$ msTool.sh
+MessageStoreTool - for examining Persistent Qpid Broker MessageStore instances
+bdb$
+</programlisting>
+<!--h3--></section>
+
+ <section role="h3" id="MessageStoreTool-AvailableCommands"><title>
+ Available
+ Commands
+ </title>
+
+ <para>
+ The available commands in the tool can be seen through the use of
+ the 'help' command.
+ </para>
+ <programlisting>
+bdb$ help
++----------------------------------------------------------------+
+| Available Commands |
++----------------------------------------------------------------+
+| Command | Description |
++----------------------------------------------------------------+
+| quit | Quit the tool. |
+| list | list available items. |
+| dump | Dump selected message content. Default: show=content |
+| load | Loads specified broker configuration file. |
+| clear | Clears any selection. |
+| show | Shows the messages headers. |
+| select | Perform a selection. |
+| help | Provides detailed help on commands. |
++----------------------------------------------------------------+
+bdb$
+</programlisting>
+ <para>
+ A brief description is displayed and further usage information is
+ shown with 'help &lt;command&gt;'
+ </para>
+ <programlisting>
+bdb$ help list
+list availble items.
+Usage:list queues [&lt;exchange&gt;] | exchanges | bindings [&lt;exchange&gt;] | all
+bdb$
+</programlisting>
+<!--h3--></section>
+
+
+ <section role="h3" id="MessageStoreTool-FutureWork"><title>
+ Future Work
+ </title>
+
+ <para>
+ Currently the tool only works whilst the broker is offline i.e.
+ it is up, but not accepting AMQP connections. This requires a
+ stop/start of the broker. If this functionality was incorporated
+ into the broker then a telnet functionality could be provided
+ allowing online management.
+ </para>
+<!--h3--></section>
+<!--h2--></section>
+</section>
diff --git a/qpid/doc/book/src/NET-User-Guide.xml b/qpid/doc/book/src/NET-User-Guide.xml
new file mode 100644
index 0000000000..7bfa20b8c8
--- /dev/null
+++ b/qpid/doc/book/src/NET-User-Guide.xml
@@ -0,0 +1,1383 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+
+ 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.
+
+-->
+
+<section>
+ <title>
+ Apache Qpid: Open Source AMQP Messaging - .NET User Guide
+ </title>
+ <section role="h1" id="NETUserGuide-Tutorial">
+ <title>
+ Tutorial
+ </title>
+ <para>
+ This tutorial consists of a series of examples using the three
+ most commonly used exchange types - Direct, Fanout and
+ Topic
+ exchanges. These examples show how to write applications that use
+ the most common messaging paradigms.
+ </para>
+ <itemizedlist>
+ <listitem>
+ <para>direct</para>
+ <para>In the direct examples, a message producer writes to the direct
+ exchange, specifying a routing key. A message consumer reads
+ messages from a named queue. This illustrates clean separation
+ of concerns - message producers need to know only the exchange
+ and the routing key, message consumers need to know only which
+ queue to use on the broker.
+ </para>
+ </listitem>
+ <listitem>
+ <para>fanout</para>
+ <para>The fanout examples use a fanout exchange and do not use
+ routing keys. Each binding specifies that all messages for a
+ given exchange should be delivered to a given queue.
+ </para>
+ </listitem>
+ <listitem>
+ <para>pub-sub</para>
+ <para>In the publish/subscribe examples, a publisher
+ application writes messages to an exchange, specifying a
+ multi-part key. A subscriber application subscribes to
+ messages that match the relevant parts of these keys, using a
+ private queue for each subscription.
+ </para>
+ </listitem>
+ <listitem>
+ <para>request-response</para>
+ <para>In the request/response examples, a simple service accepts
+ requests from clients and sends responses back to them. Clients
+ create their own private queues and corresponding routing keys.
+ When a client sends a request to the server, it specifies its
+ own routing key in the reply-to field of the request. The
+ server uses the client's reply-to field as the routing key for
+ the response.
+ </para>
+ </listitem>
+ </itemizedlist>
+ <section role="h2" id="NETUserGuide-RunningtheExamples">
+ <title>
+ Running the
+ Examples
+ </title>
+ <para>
+ Before running the examples, you need to unzip the file
+ Qpid.NET-net-2.0-M4.zip, the following tree is created:
+ </para>
+
+
+ <programlisting>
+&lt;home&gt;
+ |-qpid
+ |-lib (contains the required dlls)
+ |-examples
+ |- direct
+ | |-example-direct-Listener.exe
+ | |-example-direct-Producer.exe
+ |- fanout
+ | |-example-fanout-Listener.exe
+ | |-example-fanout-Producer.exe
+ |- pub-sub
+ | |-example-pub-sub-Listener.exe
+ | |-example-pub-sub-Publisher.exe
+ |- request-response
+ |-example-request-response-Client.exe
+ |-example-request-response-Server.exe
+ </programlisting>
+
+
+ <para>
+ Make sure your PATH contains the directory
+ &lt;home&gt;/qpid/lib
+ The examples can be run by executing the provided exe files:
+ </para>
+
+
+ <programlisting>
+$ cd &lt;home&gt;/qpid/examples/examplefolder
+$ example-...-.exe [hostname] [portnumber]
+ </programlisting>
+
+
+ <para>
+ where [hostname] is the qpid broker host name
+ (default is localhost) and [portnumber] is the port number on which the
+ qpid broker is accepting connection (default is 5672).
+ </para>
+ <!--h2-->
+ </section>
+
+ <section role="h2" id="NETUserGuide-CreatingandClosingSessions">
+ <title>
+ Creating
+ and Closing Sessions
+ </title>
+
+ <para>
+ All of the examples have been written using the Apache Qpid .NEt
+ 0.10 API. The examples use the same skeleton code to initialize
+ the program, create a session, and clean up before exiting:
+ </para>
+
+
+ <programlisting>
+using System;
+using System.IO;
+using System.Text;
+using System.Threading;
+using org.apache.qpid.client;
+using org.apache.qpid.transport;
+
+...
+
+ private static void Main(string[] args)
+ {
+ string host = args.Length &gt; 0 ? args[0] : "localhost";
+ int port = args.Length &gt; 1 ? Convert.ToInt32(args[1]) : 5672;
+ Client connection = new Client();
+ try
+ {
+ connection.connect(host, port, "test", "guest", "guest");
+ ClientSession session = connection.createSession(50000);
+
+ //--------- Main body of program --------------------------------------------
+
+ connection.close();
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine("Error: \n" + e.StackTrace);
+ }
+ }
+...
+ </programlisting>
+ <!--h2-->
+ </section>
+
+ <section role="h2" id="NETUserGuide-WritingDirectApplications">
+ <title>
+ Writing
+ Direct Applications
+ </title>
+
+ <para>
+ This section describes two programs that implement direct
+ messaging using a Direct exchange:
+ • org.apache.qpid.example.direct.Producer (from
+ example-direct-producer) publishes messages to the amq.direct
+ exchange, using the routing key routing_key.
+ •org.apache.qpid.example.direct.Listener (from
+ example-direct-Listener) uses a message listener to receive
+ messages from the queue named message_queue.
+ </para>
+ <section role="h3" id="NETUserGuide-RunningtheDirectExamples">
+ <title>
+ Running the
+ Direct Examples
+ </title>
+ <para>
+ 1) Make sure your PATH contains the directory
+ &lt;home&gt;/qpid/lib
+ </para>
+ <para>
+ 2) Make sure that a qpid broker is running:
+ </para>
+
+
+ <programlisting>
+$ ps -eaf | grep qpidd
+ </programlisting>
+
+
+ <para>
+ If a broker is running, you should see the qpidd process in the
+ output of the above
+ command.
+ </para>
+ <para>
+ 3) Read the messages from the message queue using direct
+ listener, as follows:
+ </para>
+
+
+ <programlisting>
+$ cd &lt;home&gt;/qpid/examples/direct
+ </programlisting>
+
+
+ <para>
+ With cygwin:
+ </para>
+
+
+ <programlisting>
+$ ./example-direct-Listener.exe [hostname] [portnumber]
+ </programlisting>
+
+
+ <para>
+ or with mono:
+ </para>
+
+
+ <programlisting>
+$ mono ./example-direct-Listener.exe [hostname] [portnumber]
+ </programlisting>
+
+
+ <para>
+ This program is waiting for messages to be published, see next
+ step:
+ </para>
+ <para>
+ 4) Publish a series of messages to the amq.direct exchange by
+ running direct producer, as follows:
+ </para>
+
+
+ <programlisting>
+$ cd &lt;home&gt;/qpid/examples/direct
+ </programlisting>
+
+
+ <para>
+ With cygwin:
+ </para>
+
+
+ <programlisting>
+$ ./example-direct-Producer.exe [hostname] [portnumber]
+ </programlisting>
+
+
+ <para>
+ or with mono:
+ </para>
+
+
+ <programlisting>
+$ mono ./example-direct-Producer.exe [hostname] [portnumber]
+ </programlisting>
+
+
+ <para>
+ This program has no output; the messages are routed to the
+ message queue, as instructed by the binding.
+ </para>
+ <para>
+ 5) Go to the windows where you are running your listener. You
+ should see the following output:
+ </para>
+
+
+ <programlisting>
+Message: Message 0
+Message: Message 1
+Message: Message 2
+Message: Message 3
+Message: Message 4
+Message: Message 5
+Message: Message 6
+Message: Message 7
+Message: Message 8
+Message: Message 9
+Message: That's all, folks!
+ </programlisting>
+
+
+ <para>
+ Now we will examine the code for each of these programs. In each
+ section, we will discuss only
+ the code that must be added to the skeleton shown in Section
+ "Creating and Closing Sessions".
+ </para>
+ <!--h3-->
+ </section>
+
+ <section role="h3" id="NETUserGuide-ReadingMessagesfromtheQueue">
+ <title>
+ Reading
+ Messages from the Queue
+ </title>
+
+ <para>
+ The program , listener.cs, is a message listener that receives
+ messages from a queue.
+ </para>
+ <para>
+ First it creates a queue named message_queue, then binds it to
+ the amq.direct exchange using the binding key routing_key.
+ </para>
+
+
+ <programlisting>
+//--------- Main body of program --------------------------------------------
+// Create a queue named "message_queue", and route all messages whose
+// routing key is "routing_key" to this newly created queue.
+session.queueDeclare("message_queue");
+session.exchangeBind("message_queue", "amq.direct", "routing_key");
+ </programlisting>
+
+
+ <para>
+ The queue created by this program continues to exist after the
+ program exits, and any message whose routing key matches the key
+ specified in the binding will be routed to the corresponding
+ queue by the broker. Note that the queue could have been be
+ deleted using the following code:
+ </para>
+
+
+ <programlisting>
+session.queueDelete("message_queue");
+ </programlisting>
+
+
+ <para>
+ To create a message listener, create a class derived from
+ IMessageListener, and override the messageTransfer method,
+ providing the code that should be executed when a message is
+ received.
+ </para>
+
+
+ <programlisting>
+public class MessageListener : IMessageListener
+{
+ ......
+ public void messageTransfer(IMessage m)
+ {
+ .....
+}
+ </programlisting>
+
+
+ <para>
+ The main body of the program creates a listener for the
+ subscription; attaches the listener to a message queue; and
+ subscribe to the queue to receive messages from the queue.
+ </para>
+
+
+ <programlisting>
+lock (session)
+{
+ // Create a listener and subscribe it to the queue named "message_queue"
+ IMessageListener listener = new MessageListener(session);
+ session.attachMessageListener(listener, "message_queue");
+ session.messageSubscribe("message_queue");
+ // Receive messages until all messages are received
+ Monitor.Wait(session);
+}
+ </programlisting>
+
+
+ <para>
+ The MessageListener's messageTransfer() function is called
+ whenever a message is received. In this example the message is
+ printed and tested to see if it is the final message. Once the
+ final message is received, the messages are acknowledged.
+ </para>
+
+
+ <programlisting>
+BinaryReader reader = new BinaryReader(m.Body, Encoding.UTF8);
+byte[] body = new byte[m.Body.Length - m.Body.Position];
+reader.Read(body, 0, body.Length);
+ASCIIEncoding enc = new ASCIIEncoding();
+string message = enc.GetString(body);
+ Console.WriteLine("Message: " + message);
+// Add this message to the list of message to be acknowledged
+_range.add(m.Id);
+if( message.Equals("That's all, folks!") )
+{
+ // Acknowledge all the received messages
+ _session.messageAccept(_range);
+ lock(_session)
+ {
+ Monitor.Pulse(_session);
+ }
+}
+ </programlisting>
+ <!--h3-->
+ </section>
+
+ <section role="h3" id="NETUserGuide-PublishingMessagestoaDirectExchange">
+ <title>
+ Publishing
+ Messages to a Direct Exchange
+ </title>
+ <para>
+ The second program in the direct example, Producer.cs, publishes
+ messages to the amq.direct exchange using the routing key
+ routing_key.
+ </para>
+ <para>
+ First, create a message and set a routing key. The same routing
+ key will be used for each message we send, so you only need to
+ set this property once.
+ </para>
+
+
+ <programlisting>
+IMessage message = new Message();
+// The routing key is a message property. We will use the same
+// routing key for each message, so we'll set this property
+// just once. (In most simple cases, there is no need to set
+// other message properties.)
+message.DeliveryProperties.setRoutingKey("routing_key");
+ </programlisting>
+
+
+ <para>
+ Now send some messages:
+ </para>
+
+
+ <programlisting>
+// Asynchronous transfer sends messages as quickly as
+// possible without waiting for confirmation.
+for (int i = 0; i &lt; 10; i++)
+{
+ message.clearData();
+ message.appendData(Encoding.UTF8.GetBytes("Message " + i));
+ session.messageTransfer("amq.direct", message);
+}
+ </programlisting>
+
+
+ <para>
+ Send a final synchronous message to indicate termination:
+ </para>
+
+
+ <programlisting>
+// And send a syncrhonous final message to indicate termination.
+message.clearData();
+message.appendData(Encoding.UTF8.GetBytes("That's all, folks!"));
+session.messageTransfer("amq.direct", "routing_key", message);
+session.sync();
+ </programlisting>
+ <!--h3-->
+ </section>
+
+ <!--h2-->
+ </section>
+
+
+ <section role="h2" id="NETUserGuide-WritingFanoutApplications">
+ <title>
+ Writing
+ Fanout Applications
+ </title>
+
+ <para>
+ This section describes two programs that illustrate the use of a
+ Fanout exchange.
+ </para>
+ <itemizedlist>
+ <listitem>
+ <para>Listener.cs makes a unique queue private for each instance of
+ the listener, and binds that queue to the fanout exchange. All
+ messages sent to the fanout exchange are delivered to each
+ listener's queue.
+ </para>
+ </listitem>
+ <listitem>
+ <para>Producer.cs publishes messages to the fanout exchange. It
+ does not use a routing key, which is not needed by the fanout
+ exchange.
+ </para>
+ </listitem>
+ </itemizedlist>
+ <section role="h3" id="NETUserGuide-RunningtheFanoutExamples">
+ <title>
+ Running the
+ Fanout Examples
+ </title>
+
+ <para>
+ 1) Make sure your PATH contains the directory
+ &lt;home&gt;/qpid/lib
+ </para>
+ <para>
+ 2) Make sure that a qpid broker is running:
+ </para>
+
+
+ <programlisting>
+$ ps -eaf | grep qpidd
+ </programlisting>
+
+
+ <para>
+ If a broker is running, you should see the qpidd process in the
+ output of the above
+ command.
+ </para>
+ <para>
+ 3) In separate windows, start one or more fanout listeners as
+ follows:
+ </para>
+
+
+ <programlisting>
+$ cd &lt;home&gt;/qpid/examples/direct
+ </programlisting>
+
+
+ <para>
+ With cygwin:
+ </para>
+
+
+ <programlisting>
+$ ./example-fanout-Listener.exe [hostname] [portnumber]
+ </programlisting>
+
+
+ <para>
+ or with mono:
+ </para>
+
+
+ <programlisting>
+$ mono ./example-fanout-Listener.exe [hostname] [portnumber]
+ </programlisting>
+
+
+ <para>
+ The listener creates a private queue, binds it to the amq.fanout
+ exchange, and waits for messages to arrive on the queue. When the
+ listener starts, you will see the following message:
+ </para>
+
+
+ <programlisting>
+Listening
+ </programlisting>
+
+
+ <para>
+ This program is waiting for messages to be published, see next
+ step:
+ </para>
+ <para>
+ 4) In a separate window, publish a series of messages to the
+ amq.fanout exchange by running fanout producer, as follows:
+ </para>
+
+
+ <programlisting>
+$ cd &lt;home&gt;/qpid/examples/direct
+ </programlisting>
+
+
+ <para>
+ With cygwin:
+ </para>
+
+
+ <programlisting>
+$ ./example-fanout-Producer.exe [hostname] [portnumber]
+ </programlisting>
+
+
+ <para>
+ or with mono:
+ </para>
+
+
+ <programlisting>
+$ mono ./example-fanout-Producer.exe [hostname] [portnumber]
+ </programlisting>
+
+
+ <para>
+ This program has no output; the messages are routed to the
+ message queue, as prescribed by the binding.
+ </para>
+ <para>
+ 5) Go to the windows where you are running listeners. You should
+ see the following output for each listener:
+ </para>
+
+
+ <programlisting>
+Message: Message 0
+Message: Message 1
+Message: Message 2
+Message: Message 3
+Message: Message 4
+Message: Message 5
+Message: Message 6
+Message: Message 7
+Message: Message 8
+Message: Message 9
+Message: That's all, folks!
+ </programlisting>
+
+
+ <para>
+ Now we will examine the code for each of these programs. In each
+ section, we will discuss only
+ the code that must be added to the skeleton shown in Section
+ "Creating and Closing Sessions".
+ </para>
+
+ <!--h3-->
+ </section>
+
+ <!--h2-->
+ </section>
+
+ <section role="h2" id="NETUserGuide-ConsumingfromaFanoutExchange">
+ <title>
+ Consuming from a
+ Fanout Exchange
+ </title>
+
+ <para>
+ The first program in the fanout example, Listener.cs, creates a
+ private queue, binds it to the amq.fanout exchange, and waits for
+ messages to arrive on the queue, printing them out as they
+ arrive. It uses a Listener that is identical to the one used in
+ the direct example:
+ </para>
+
+
+ <programlisting>
+ public class MessageListener : IMessageListener
+ {
+ private readonly ClientSession _session;
+ private readonly RangeSet _range = new RangeSet();
+ public MessageListener(ClientSession session)
+ {
+ _session = session;
+ }
+
+ public void messageTransfer(IMessage m)
+ {
+ BinaryReader reader = new BinaryReader(m.Body, Encoding.UTF8);
+ byte[] body = new byte[m.Body.Length - m.Body.Position];
+ reader.Read(body, 0, body.Length);
+ ASCIIEncoding enc = new ASCIIEncoding();
+ string message = enc.GetString(body);
+ Console.WriteLine("Message: " + message);
+ // Add this message to the list of message to be acknowledged
+ _range.add(m.Id);
+ if (message.Equals("That's all, folks!"))
+ {
+ // Acknowledge all the received messages
+ _session.messageAccept(_range);
+ lock (_session)
+ {
+ Monitor.Pulse(_session);
+ }
+ }
+ }
+ }
+ </programlisting>
+
+
+ <para>
+ The listener creates a private queue to receive its messages and
+ binds it to the fanout exchange:
+ </para>
+
+
+ <programlisting>
+string myQueue = session.Name;
+session.queueDeclare(myQueue, Option.EXCLUSIVE, Option.AUTO_DELETE);
+session.exchangeBind(myQueue, "amq.fanout", "my-key");
+ </programlisting>
+
+
+ <para>
+ Now we create a listener and subscribe it to the queue:
+ </para>
+
+
+ <programlisting>
+lock (session)
+{
+ Console.WriteLine("Listening");
+ // Create a listener and subscribe it to my queue.
+ IMessageListener listener = new MessageListener(session);
+ session.attachMessageListener(listener, myQueue);
+ session.messageSubscribe(myQueue);
+ // Receive messages until all messages are received
+ Monitor.Wait(session);
+}
+ </programlisting>
+
+
+ <section role="h3" id="NETUserGuide-PublishingMessagestotheFanoutExchange">
+ <title>
+ Publishing
+ Messages to the Fanout Exchange
+ </title>
+
+ <para>
+ The second program in this example, Producer.cs, writes messages
+ to the fanout queue.
+ </para>
+
+
+ <programlisting>
+// Unlike topic exchanges and direct exchanges, a fanout
+// exchange need not set a routing key.
+IMessage message = new Message();
+// Asynchronous transfer sends messages as quickly as
+// possible without waiting for confirmation.
+for (int i = 0; i &lt; 10; i++)
+{
+ message.clearData();
+ message.appendData(Encoding.UTF8.GetBytes("Message " + i));
+ session.messageTransfer("amq.fanout", message);
+}
+
+// And send a syncrhonous final message to indicate termination.
+message.clearData();
+message.appendData(Encoding.UTF8.GetBytes("That's all, folks!"));
+session.messageTransfer("amq.fanout", message);
+session.sync();
+ </programlisting>
+
+ <!--h3-->
+ </section>
+
+ <!--h2-->
+ </section>
+
+ <section role="h2" id="NETUserGuide-WritingPublish-2FSubscribeApplications">
+ <title>
+ Writing
+ Publish/Subscribe Applications
+ </title>
+
+ <para>
+ This section describes two programs that implement
+ Publish/Subscribe messaging using a topic exchange.
+ </para>
+ <para>
+ • Publisher.cS sends messages to the amq.topic exchange,
+ using the multipart routing keys usa.news, usa.weather,
+ europe.news, and europe.weather.
+ • Listener.cs creates private queues for news, weather,
+ usa, and europe, binding them to the amq.topic exchange using
+ bindings that match the corresponding parts of the multipart
+ routing keys.
+ </para>
+ <para>
+ In this example, the publisher creates messages for topics like
+ news, weather, and sports that happen in regions like Europe,
+ Asia, or the United States. A given consumer may be interested in
+ all weather messages, regardless of region, or it may be
+ interested in news and weather for the United States, but
+ uninterested in items for other regions. In this example, each
+ consumer sets up its own private queues, which receive precisely
+ the messages that particular consumer is interested in.
+ </para>
+ <section role="h3" id="NETUserGuide-RunningthePublishSubscribeExamples">
+ <title>
+ Running
+ the Publish-Subscribe Examples
+ </title>
+ <para>
+ 1) Make sure your PATH contains the directory
+ &lt;home&gt;/qpid/lib
+ </para>
+ <para>
+ 2) Make sure that a qpid broker is running:
+ </para>
+
+
+ <programlisting>
+$ ps -eaf | grep qpidd
+ </programlisting>
+
+
+ <para>
+ If a broker is running, you should see the qpidd process in the
+ output of the above
+ command.
+ </para>
+ <para>
+ 3) In separate windows, start one or more topic subscribers as
+ follows:
+ </para>
+
+
+ <programlisting>
+$ cd &lt;home&gt;/qpid/examples/direct
+ </programlisting>
+
+
+ <para>
+ With cygwin:
+ </para>
+
+
+ <programlisting>
+$ ./example-pub-sub--Listener.exe [hostname] [portnumber]
+ </programlisting>
+
+
+ <para>
+ or with mono:
+ </para>
+
+
+ <programlisting>
+$ mono ./example-pub-sub-Listener.exe [hostname] [portnumber]
+ </programlisting>
+
+
+ <para>
+ You will see output similar to this:
+ </para>
+
+
+ <programlisting>
+Listening for messages ...
+Declaring queue: usa
+Declaring queue: europe
+Declaring queue: news
+Declaring queue: weather
+ </programlisting>
+
+
+ <para>
+ Each topic consumer creates a set of private queues, and binds
+ each queue to the amq.topic exchange together with a binding that
+ indicates which messages should be routed to the queue.
+ </para>
+ <para>
+ 4) In another window, start the topic publisher, which publishes
+ messages to the amq.topic exchange, as follows:
+ </para>
+
+
+ <programlisting>
+$ cd &lt;home&gt;/qpid/examples/direct
+ </programlisting>
+
+
+ <para>
+ With cygwin:
+ </para>
+
+
+ <programlisting>
+$ ./example-pub-sub-Producer.exe [hostname] [portnumber]
+ </programlisting>
+
+
+ <para>
+ or with mono:
+ </para>
+
+
+ <programlisting>
+$ mono ./example-pub-sub-Producer.exe [hostname] [portnumber]
+ </programlisting>
+
+
+ <para>
+ This program has no output; the messages are routed to the
+ message queues for each topic_consumer as specified by the
+ bindings the consumer created.
+ </para>
+ <para>
+ 5) Go back to the window for each topic consumer. You should see
+ output like this:
+ </para>
+
+
+ <programlisting>
+Message: Message 0 from usa
+Message: Message 0 from news
+Message: Message 0 from weather
+Message: Message 1 from usa
+Message: Message 1 from news
+Message: Message 2 from usa
+Message: Message 2 from news
+Message: Message 3 from usa
+Message: Message 3 from news
+Message: Message 4 from usa
+Message: Message 4 from news
+Message: Message 5 from usa
+Message: Message 5 from news
+Message: Message 6 from usa
+Message: Message 6 from news
+Message: Message 7 from usa
+Message: Message 7 from news
+Message: Message 8 from usa
+Message: Message 8 from news
+Message: Message 9 from usa
+....
+Message: That's all, folks! from weather
+Shutting down listener for control
+Message: That's all, folks! from europe
+Shutting down listener for control
+ </programlisting>
+
+
+ <para>
+ Now we will examine the code for each of these programs. In each
+ section, we will discuss only
+ the code that must be added to the skeleton shown in Section
+ "Creating and Closing Sessions".
+ </para>
+ <!--h3-->
+ </section>
+
+
+ <section role="h3" id="NETUserGuide-PublishingMessagestoaTopicExchange">
+ <title>
+ Publishing
+ Messages to a Topic Exchange
+ </title>
+
+ <para>
+ The first program in the publish/subscribe example, Publisher.cs,
+ defines two new functions: one that publishes messages to the
+ topic exchange, and one that indicates that no more messages are
+ coming.
+ </para>
+ <para>
+ The publishMessages function publishes a series of five messages
+ using the specified routing key.
+ </para>
+
+
+ <programlisting>
+private static void publishMessages(ClientSession session, string routing_key)
+{
+ IMessage message = new Message();
+ // Asynchronous transfer sends messages as quickly as
+ // possible without waiting for confirmation.
+ for (int i = 0; i &lt; 10; i++)
+ {
+ message.clearData();
+ message.appendData(Encoding.UTF8.GetBytes("Message " + i));
+ session.messageTransfer("amq.topic", routing_key, message);
+ }
+}
+ </programlisting>
+
+
+ <para>
+ The noMoreMessages function signals the end of messages using the
+ control routing key, which is reserved for control messages.
+ </para>
+
+
+ <programlisting>
+private static void noMoreMessages(ClientSession session)
+{
+ IMessage message = new Message();
+ // And send a syncrhonous final message to indicate termination.
+ message.clearData();
+ message.appendData(Encoding.UTF8.GetBytes("That's all, folks!"));
+ session.messageTransfer("amq.topic", "control", message);
+ session.sync();
+}
+ </programlisting>
+
+
+ <para>
+ In the main body of the program, messages are published using
+ four different routing keys, and then the end of messages is
+ indicated by a message sent to a separate routing key.
+ </para>
+
+
+ <programlisting>
+publishMessages(session, "usa.news");
+publishMessages(session, "usa.weather");
+publishMessages(session, "europe.news");
+publishMessages(session, "europe.weather");
+
+noMoreMessages(session);
+ </programlisting>
+ <!--h3-->
+ </section>
+
+ <section role="h3" id="NETUserGuide-ReadingMessagesfromtheQueue2">
+ <title>
+ Reading
+ Messages from the Queue
+ </title>
+
+ <para>
+ The second program in the publish/subscribe example, Listener.cs,
+ creates a local private queue, with a unique name, for each of
+ the four binding keys it specifies: usa.#, europe.#, #.news, and
+ #.weather, and creates a listener.
+ </para>
+
+
+ <programlisting>
+Console.WriteLine("Listening for messages ...");
+// Create a listener
+prepareQueue("usa", "usa.#", session);
+prepareQueue("europe", "europe.#", session);
+prepareQueue("news", "#.news", session);
+prepareQueue("weather", "#.weather", session);
+ </programlisting>
+
+
+ <para>
+ The prepareQueue() method creates a queue using a queue name and
+ a routing key supplied as arguments it then attaches a listener
+ with the session for the created queue and subscribe for this
+ receiving messages from the queue:
+ </para>
+
+
+ <programlisting>
+// Create a unique queue name for this consumer by concatenating
+// the queue name parameter with the Session ID.
+Console.WriteLine("Declaring queue: " + queue);
+session.queueDeclare(queue, Option.EXCLUSIVE, Option.AUTO_DELETE);
+
+// Route messages to the new queue if they match the routing key.
+// Also route any messages to with the "control" routing key to
+// this queue so we know when it's time to stop. A publisher sends
+// a message with the content "That's all, Folks!", using the
+// "control" routing key, when it is finished.
+
+session.exchangeBind(queue, "amq.topic", routing_key);
+session.exchangeBind(queue, "amq.topic", "control");
+
+// subscribe the listener to the queue
+IMessageListener listener = new MessageListener(session);
+session.attachMessageListener(listener, queue);
+session.messageSubscribe(queue);
+ </programlisting>
+ <!--h3-->
+ </section>
+ <!--h2-->
+ </section>
+
+ <section role="h2" id="NETUserGuide-WritingRequest-2FResponseApplications">
+ <title>
+ Writing
+ Request/Response Applications
+ </title>
+
+ <para>
+ In the request/response examples, we write a server that accepts
+ strings from clients and converts them to upper case, sending the
+ result back to the requesting client. This example consists of
+ two programs.
+ </para>
+ <itemizedlist>
+ <listitem>
+ <para>Client.cs is a client application that sends messages to the
+ server.
+ • Server.cs is a service that accepts messages, converts
+ their content to upper case, and sends the result to the
+ amq.direct exchange, using the request's reply-to property as
+ the routing key for the response.
+ </para>
+ </listitem>
+ </itemizedlist>
+ <section role="h3" id="NETUserGuide-RunningtheRequest-2FResponseExamples">
+ <title>
+ Running
+ the Request/Response Examples
+ </title>
+ <para>
+ 1) Make sure your PATH contains the directory
+ &lt;home&gt;/qpid/lib
+ </para>
+ <para>
+ 2) Make sure that a qpid broker is running:
+ </para>
+
+
+ <programlisting>
+$ ps -eaf | grep qpidd
+ </programlisting>
+
+
+ <para>
+ If a broker is running, you should see the qpidd process in the
+ output of the above
+ command.
+ </para>
+ <para>
+ 3) Run the server.
+ </para>
+ <para>
+ $ cd &lt;home&gt;/qpid/examples/direct
+ </para>
+
+
+ <programlisting>
+ With cygwin:
+ </programlisting>
+
+
+ <para>
+ $ ./example-request-response-Server.exe [hostname] [portnumber]
+ </para>
+
+
+ <programlisting>
+ or with mono:
+ </programlisting>
+
+
+ <para>
+ $ mono ./example-request-response-Server.exe [hostname] [portnumber]
+ </para>
+
+
+ <programlisting>
+ You will see output similar to this:
+ </programlisting>
+
+
+ <para>
+ Waiting for requests
+ </para>
+
+
+ <programlisting>
+4) In a separate window, start a client:
+
+$ cd &lt;home&gt;/qpid/examples/direct
+ </programlisting>
+
+
+ <para>
+ With cygwin:
+ </para>
+
+
+ <programlisting>
+$ ./example-request-response-Client.exe [hostname] [portnumber]
+ </programlisting>
+
+
+ <para>
+ or with mono:
+ </para>
+
+
+ <programlisting>
+$ mono ./example-request-response-Client.exe [hostname] [portnumber]
+ </programlisting>
+
+
+ <para>
+ You will see output similar to this:
+ </para>
+
+
+ <programlisting>
+Activating response queue listener for: clientSystem.Byte[]
+Waiting for all responses to arrive ...
+Response: TWAS BRILLIG, AND THE SLITHY TOVES
+Response: DID GIRE AND GYMBLE IN THE WABE.
+Response: ALL MIMSY WERE THE BOROGROVES,
+Response: AND THE MOME RATHS OUTGRABE.
+Shutting down listener for clientSystem.Byte[]
+Response: THAT'S ALL, FOLKS!
+ </programlisting>
+
+
+ <para>
+ 4) Go back to the server window, the output should be similar to
+ this:
+ </para>
+
+
+ <programlisting>
+Waiting for requests
+Request: Twas brillig, and the slithy toves
+Request: Did gire and gymble in the wabe.
+Request: All mimsy were the borogroves,
+Request: And the mome raths outgrabe.
+Request: That's all, folks!
+ </programlisting>
+
+
+ <para>
+ Now we will examine the code for each of these programs. In each
+ section, we will discuss only the code that must be added to the
+ skeleton shown in Section "Creating and Closing Sessions".
+ </para>
+ <!--h3-->
+ </section>
+
+
+ <section role="h3" id="NETUserGuide-TheClientApplication">
+ <title>
+ The Client
+ Application
+ </title>
+
+ <para>
+ The first program in the request-response example, Client.cs,
+ sets up a private response queue to receive responses from the
+ server, then sends messages the server, listening to the response
+ queue for the server's responses.
+ </para>
+
+
+ <programlisting>
+string response_queue = "client" + session.getName();
+// Use the name of the response queue as the routing key
+session.queueDeclare(response_queue);
+session.exchangeBind(response_queue, "amq.direct", response_queue);
+
+// Create a listener for the response queue and listen for response messages.
+Console.WriteLine("Activating response queue listener for: " + response_queue);
+IMessageListener listener = new ClientMessageListener(session);
+session.attachMessageListener(listener, response_queue);
+session.messageSubscribe(response_queue);
+ </programlisting>
+
+
+ <para>
+ Set some properties that will be used for all requests. The
+ routing key for a request is request.
+ The reply-to property is set to the routing key for the client's
+ private queue.
+ </para>
+
+
+ <programlisting>
+IMessage request = new Message();
+request.DeliveryProperties.setRoutingKey("request");
+request.MessageProperties.setReplyTo(new ReplyTo("amq.direct", response_queue));
+ </programlisting>
+
+
+ <para>
+ Now send some requests...
+ </para>
+
+
+ <programlisting>
+string[] strs = {
+ "Twas brillig, and the slithy toves",
+ "Did gire and gymble in the wabe.",
+ "All mimsy were the borogroves,",
+ "And the mome raths outgrabe.",
+ "That's all, folks!"
+ };
+foreach (string s in strs)
+{
+ request.clearData();
+ request.appendData(Encoding.UTF8.GetBytes(s));
+ session.messageTransfer("amq.direct", request);
+}
+ </programlisting>
+
+
+ <para>
+ And wait for responses to arrive:
+ </para>
+
+
+ <programlisting>
+Console.WriteLine("Waiting for all responses to arrive ...");
+Monitor.Wait(session);
+ </programlisting>
+ <!--h3-->
+ </section>
+
+ <section role="h3" id="NETUserGuide-TheServerApplication">
+ <title>
+ The Server
+ Application
+ </title>
+
+ <para>
+ The second program in the request-response example, Server.cs,
+ uses the reply-to property as the routing key for responses.
+ </para>
+ <para>
+ The main body of Server.cs creates an exclusive queue for
+ requests, then waits for messages to arrive.
+ </para>
+
+
+ <programlisting>
+const string request_queue = "request";
+// Use the name of the request queue as the routing key
+session.queueDeclare(request_queue);
+session.exchangeBind(request_queue, "amq.direct", request_queue);
+
+lock (session)
+{
+ // Create a listener and subscribe it to the request_queue
+ IMessageListener listener = new MessageListener(session);
+ session.attachMessageListener(listener, request_queue);
+ session.messageSubscribe(request_queue);
+ // Receive messages until all messages are received
+ Console.WriteLine("Waiting for requests");
+ Monitor.Wait(session);
+}
+ </programlisting>
+
+
+ <para>
+ The listener's messageTransfer() method converts the request's
+ content to upper case, then sends a response to the broker, using
+ the request's reply-to property as the routing key for the
+ response.
+ </para>
+
+
+ <programlisting>
+BinaryReader reader = new BinaryReader(request.Body, Encoding.UTF8);
+byte[] body = new byte[request.Body.Length - request.Body.Position];
+reader.Read(body, 0, body.Length);
+ASCIIEncoding enc = new ASCIIEncoding();
+string message = enc.GetString(body);
+Console.WriteLine("Request: " + message);
+
+// Transform message content to upper case
+string responseBody = message.ToUpper();
+
+// Send it back to the user
+response.clearData();
+response.appendData(Encoding.UTF8.GetBytes(responseBody));
+_session.messageTransfer("amq.direct", routingKey, response);
+ </programlisting>
+
+ <!--h3-->
+ </section>
+ <!--h2-->
+ </section>
+ <!--h1-->
+ </section>
+
+
+ </section>
diff --git a/qpid/doc/book/src/Programming-In-Apache-Qpid.xml b/qpid/doc/book/src/Programming-In-Apache-Qpid.xml
new file mode 100644
index 0000000000..6fae2f0bc7
--- /dev/null
+++ b/qpid/doc/book/src/Programming-In-Apache-Qpid.xml
@@ -0,0 +1,6330 @@
+<?xml version='1.0' encoding='utf-8' ?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
+
+<!--
+
+ 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.
+
+ -->
+
+<book id="client-api-tutorial">
+ <title>Programming in Apache Qpid</title>
+ <subtitle>Cross-Platform AMQP Messaging in Java JMS, .NET, C++, and Python</subtitle>
+
+ <chapter>
+ <title>Introduction</title>
+
+ <para>Apache Qpid is a reliable, asynchronous messaging system that
+ supports the AMQP messaging protocol in several common programming
+ languages. Qpid is supported on most common platforms.
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ On the Java platform, Qpid uses the
+ established <ulink url="http://java.sun.com/products/jms/">Java JMS
+ API</ulink>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ For Python, C++, and .NET, Qpid defines its own messaging API, the
+ <firstterm>Qpid Messaging API</firstterm>, which is
+ conceptually similar in each.
+ </para>
+ <para>
+ On the .NET platform, Qpid also provides a WCF binding.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Ruby will also use the Qpid Messaging API, which will soon
+ be implemented. (Ruby currently uses an API that is closely
+ tied to the AMQP version).
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ </chapter>
+
+ <chapter>
+ <title>Using the Qpid Messaging API</title>
+
+ <para>The Qpid Messaging API is quite simple, consisting of only a
+ handful of core classes.
+ </para>
+
+ <itemizedlist>
+
+ <listitem>
+ <para>
+ A <firstterm>message</firstterm> consists of a standard set
+ of fields (e.g. <literal>subject</literal>,
+ <literal>reply-to</literal>), an application-defined set of
+ properties, and message content (the main body of the
+ message).
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ A <firstterm>connection</firstterm> represents a network
+ connection to a remote endpoint.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ A <firstterm>session</firstterm> provides a sequentially
+ ordered context for sending and receiving
+ <emphasis>messages</emphasis>. A session is obtained from a
+ connection.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ A <firstterm>sender</firstterm> sends messages to a target
+ using the <literal>sender.send</literal> method. A sender is
+ obtained from a session for a given target address.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ A <firstterm>receiver</firstterm> receives messages from a
+ source using the <literal>receiver.fetch</literal> method.
+ A receiver is obtained from a session for a given source
+ address.
+ </para>
+ </listitem>
+
+ </itemizedlist>
+
+ <para>
+ The following sections show how to use these classes in a
+ simple messaging program.
+ </para>
+
+ <section>
+ <title>A Simple Messaging Program in C++</title>
+
+ <para>The following C++ program shows how to create a connection,
+ create a session, send messages using a sender, and receive
+ messages using a receiver.</para>
+
+ <example>
+ <title>"Hello world!" in C++</title>
+ <programlisting lang="c++"><![CDATA[
+#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 <iostream>]]>
+
+using namespace qpid::messaging;
+
+int main(int argc, char** argv) {
+ std::string broker = argc > 1 ? argv[1] : "localhost:5672";
+ std::string address = argc > 2 ? argv[2] : "amq.topic";
+ std::string connectionOptions = argc > 3 ? argv[3] : "";
+
+ Connection connection(broker, connectionOptions);
+ try {
+ connection.open(); <co id="hello-cpp-open" linkends="callout-cpp-open"/>
+ Session session = connection.createSession(); <co id="hello-cpp-session" linkends="callout-cpp-session"/>
+
+ Receiver receiver = session.createReceiver(address); <co id="hello-cpp-receiver" linkends="callout-cpp-receiver"/>
+ Sender sender = session.createSender(address); <co id="hello-cpp-sender" linkends="callout-cpp-sender"/>
+
+ sender.send(Message("Hello world!"));
+
+ Message message = receiver.fetch(Duration::SECOND * 1); <co id="hello-cpp-fetch" linkends="callout-cpp-fetch"/>
+ <![CDATA[std::cout << message.getContent() << std::endl;]]>
+ session.acknowledge(); <co id="hello-cpp-acknowledge" linkends="callout-cpp-acknowledge"/>
+
+ connection.close(); <co id="hello-cpp-close" linkends="callout-cpp-close"/>
+ return 0;
+ } catch(const std::exception&amp; error) {
+ <![CDATA[std::cerr << error.what() << std::endl;]]>
+ connection.close();
+ return 1;
+ }
+}</programlisting>
+
+ <calloutlist>
+ <callout id="callout-cpp-open" arearefs="hello-cpp-open">
+ <para>Establishes the connection with the messaging broker.</para>
+ </callout>
+ <callout id="callout-cpp-session" arearefs="hello-cpp-session">
+ <para>Creates a session object on which messages will be sent and received.</para>
+ </callout>
+ <callout id="callout-cpp-receiver" arearefs="hello-cpp-receiver">
+ <para>Creates a receiver that receives messages from the given address.</para>
+ </callout>
+ <callout id="callout-cpp-sender" arearefs="hello-cpp-sender">
+ <para>Creates a sender that sends to the given address.</para>
+ </callout>
+ <callout id="callout-cpp-fetch" arearefs="hello-cpp-fetch">
+ <para>Receives the next message. The duration is optional, if omitted, will wait indefinitely for the next message.</para>
+ </callout>
+ <callout id="callout-cpp-acknowledge" arearefs="hello-cpp-acknowledge">
+ <para>Acknowledges receipt of all fetched messages on the
+ session. This informs the broker that the messages were
+ transferred and processed by the client successfully.</para>
+ </callout>
+ <callout id="callout-cpp-close" arearefs="hello-cpp-close">
+ <para>Closes the connection, all sessions managed by the connection, and all senders and receivers managed by each session.</para>
+ </callout>
+ </calloutlist>
+ </example>
+
+
+ </section>
+
+ <section>
+ <title>A Simple Messaging Program in Python</title>
+
+ <para>The following Python program shows how to create a
+ connection, create a session, send messages using a sender, and
+ receive messages using a receiver.</para>
+
+ <example>
+ <title>"Hello world!" in Python</title>
+ <programlisting lang="python"><![CDATA[
+import sys
+from qpid.messaging import *
+
+broker = "localhost:5672" if len(sys.argv)<2 else sys.argv[1]
+address = "amq.topic" if len(sys.argv)<3 else sys.argv[2]]]>
+
+connection = Connection(broker)
+
+try:
+ connection.open() <co id="hello-python-open" linkends="callout-python-open"/>
+ session = connection.session() <co id="hello-python-session" linkends="callout-python-session"/>
+
+ sender = session.sender(address) <co id="hello-python-sender" linkends="callout-python-sender"/>
+ receiver = session.receiver(address) <co id="hello-python-receiver" linkends="callout-python-receiver"/>
+
+ sender.send(Message("Hello world!"));
+
+ message = receiver.fetch(timeout=1) <co id="hello-python-fetch" linkends="callout-python-fetch"/>
+ print message.content
+ session.acknowledge() <co id="hello-python-acknowledge" linkends="callout-python-acknowledge"/>
+
+except MessagingError,m:
+ print m
+finally:
+ connection.close() <co id="hello-python-close" linkends="callout-python-close"/>
+</programlisting>
+
+ <calloutlist>
+ <callout id="callout-python-open" arearefs="hello-python-open">
+ <para>Establishes the connection with the messaging broker.</para>
+ </callout>
+ <callout id="callout-python-session" arearefs="hello-python-session">
+ <para>Creates a session object on which messages will be sent and received.</para>
+ </callout>
+ <callout id="callout-python-receiver" arearefs="hello-python-receiver">
+ <para>Creates a receiver that receives messages from the given address.</para>
+ </callout>
+ <callout id="callout-python-sender" arearefs="hello-python-sender">
+ <para>Creates a sender that sends to the given address.</para>
+ </callout>
+ <callout id="callout-python-fetch" arearefs="hello-python-fetch">
+ <para>Receives the next message. The duration is optional, if omitted, will wait indefinitely for the next message.</para>
+ </callout>
+ <callout id="callout-python-acknowledge" arearefs="hello-python-acknowledge">
+ <para>Acknowledges receipt of all fetched messages on
+ the session. This informs the broker that the messages were
+ transfered and processed by the client successfully.</para>
+ </callout>
+ <callout id="callout-python-close" arearefs="hello-python-close">
+ <para>Closes the connection, all sessions managed by the connection, and all senders and receivers managed by each session.</para>
+ </callout>
+ </calloutlist>
+
+ </example>
+
+ </section>
+
+
+
+
+ <section>
+ <title>A Simple Messaging Program in .NET C#</title>
+
+ <para>The following .NET C#
+ <footnote>
+ <para>
+ The .NET binding for the Qpid C++ Messaging API
+ applies to all .NET Framework managed code languages. C# was chosen
+ for illustration purposes only.
+ </para>
+ </footnote>
+ program shows how to create a connection,
+ create a session, send messages using a sender, and receive
+ messages using a receiver.
+ </para>
+
+ <example>
+ <title>"Hello world!" in .NET C#</title>
+ <programlisting lang="c++">
+using System;
+using Org.Apache.Qpid.Messaging; <co id="hello-csharp-using" linkends="callout-csharp-using"/>
+
+namespace Org.Apache.Qpid.Messaging {
+ class Program {
+ static void Main(string[] args) {
+ String broker = args.Length > 0 ? args[0] : "localhost:5672";
+ String address = args.Length > 1 ? args[1] : "amq.topic";
+
+ Connection connection = null;
+ try {
+ connection = new Connection(broker);
+ connection.Open(); <co id="hello-csharp-open" linkends="callout-csharp-open"/>
+ Session session = connection.CreateSession(); <co id="hello-csharp-session" linkends="callout-csharp-session"/>
+
+ Receiver receiver = session.CreateReceiver(address); <co id="hello-csharp-receiver" linkends="callout-csharp-receiver"/>
+ Sender sender = session.CreateSender(address); <co id="hello-csharp-sender" linkends="callout-csharp-sender"/>
+
+ sender.Send(new Message("Hello world!"));
+
+ Message message = new Message();
+ message = receiver.Fetch(DurationConstants.SECOND * 1); <co id="hello-csharp-fetch" linkends="callout-csharp-fetch"/>
+ Console.WriteLine("{0}", message.GetContent());
+ session.Acknowledge(); <co id="hello-csharp-acknowledge" linkends="callout-csharp-acknowledge"/>
+
+ connection.Close(); <co id="hello-csharp-close" linkends="callout-csharp-close"/>
+ } catch (Exception e) {
+ Console.WriteLine("Exception {0}.", e);
+ if (null != connection)
+ connection.Close();
+ }
+ }
+ }
+}
+
+</programlisting>
+
+ <calloutlist>
+ <callout id="callout-csharp-using" arearefs="hello-csharp-using">
+ <para> Permits use of Org.Apache.Qpid.Messaging types and methods without explicit namespace qualification. Any .NET project must have a project reference to the assembly file <literal>Org.Apache.Qpid.Messaging.dll</literal> in order to obtain the definitions of the .NET Binding for Qpid Messaging namespace.</para>
+ </callout>
+ <callout id="callout-csharp-open" arearefs="hello-csharp-open">
+ <para>Establishes the connection with the messaging broker.</para>
+ </callout>
+ <callout id="callout-csharp-session" arearefs="hello-csharp-session">
+ <para>Creates a session object on which messages will be sent and received.</para>
+ </callout>
+ <callout id="callout-csharp-receiver" arearefs="hello-csharp-receiver">
+ <para>Creates a receiver that receives messages from the given address.</para>
+ </callout>
+ <callout id="callout-csharp-sender" arearefs="hello-csharp-sender">
+ <para>Creates a sender that sends to the given address.</para>
+ </callout>
+ <callout id="callout-csharp-fetch" arearefs="hello-csharp-fetch">
+ <para>Receives the next message. The duration is optional, if omitted, will wait indefinitely for the next message.</para>
+ </callout>
+ <callout id="callout-csharp-acknowledge" arearefs="hello-csharp-acknowledge">
+ <para>Acknowledges receipt of all fetched messages on the
+ session. This informs the broker that the messages were
+ transfered and processed by the client successfully.</para>
+ </callout>
+ <callout id="callout-csharp-close" arearefs="hello-csharp-close">
+ <para>Closes the connection, all sessions managed by the connection, and all senders and receivers managed by each session.</para>
+ </callout>
+ </calloutlist>
+ </example>
+
+
+ </section>
+
+
+
+
+
+
+ <section id="section-addresses">
+ <title>Addresses</title>
+
+ <para>An <firstterm>address</firstterm> is the name of a message
+ target or message source.
+
+ <footnote><para>In the programs we have just seen, we used
+ <literal>amq.topic</literal> as the default address if none is
+ passed in. This is the name of a standard exchange that always
+ exists on an AMQP 0-10 messaging broker.</para></footnote>
+
+ The methods that create senders and receivers require an
+ address. The details of sending to a particular target or
+ receiving from a particular source are then handled by the
+ sender or receiver. A different target or source can be used
+ simply by using a different address.
+ </para>
+
+ <para>An address resolves to a <firstterm>node</firstterm>. The
+ Qpid Messaging API recognises two kinds of nodes,
+ <firstterm>queues</firstterm> and <firstterm>topics</firstterm>
+
+ <footnote><para>The terms <emphasis>queue</emphasis> and
+ <emphasis>topic</emphasis> here were chosen to align with
+ their meaning in JMS. These two addressing 'patterns',
+ queue and topic, are sometimes refered as point-to-point
+ and publish-subscribe. AMQP 0-10 has an exchange type
+ called a <emphasis>topic exchange</emphasis>. When the term
+ <emphasis>topic</emphasis> occurs alone, it refers to a
+ Messaging API topic, not the topic
+ exchange.</para></footnote>.
+
+ A queue stores each message until it has been received and
+ acknowledged, and only one receiver can receive a given message
+
+ <footnote><para>There are exceptions to this rule; for instance,
+ a receiver can use <literal>browse</literal> mode, which leaves
+ messages on the queue for other receivers to
+ read.</para></footnote>.
+
+ A topic immediately delivers a message to all eligible
+ receivers; if there are no eligible receivers, it discards the
+ message. In the AMQP 0-10 implementation of the API,
+
+ <footnote><para>The AMQP 0-10 implementation is the only one
+ that currently exists.</para></footnote>
+
+ queues map to AMQP queues, and topics map to AMQP exchanges.
+
+ <footnote><para>In AMQP 0-10, messages are sent to
+ exchanges, and read from queues. The Messaging API also
+ allows a sender to send messages to a queue; internally,
+ Qpid implements this by sending the message to the default
+ exchange, with the name of the queue as the routing key. The
+ Messaging API also allows a receiver to receive messages
+ from a topic; internally, Qpid implements this by setting up
+ a private subscription queue for the receiver and binding
+ the subscription queue to the exchange that corresponds to
+ the topic.</para></footnote>
+ </para>
+
+ <para>In the rest of this tutorial, we present many examples
+ using two programs that take an address as a command line
+ parameter. <command>spout</command> sends messages to the
+ target address, <command>drain</command> receives messages from
+ the source address. The source code is available in C++, Python, and
+ .NET C# and can be found in the examples directory for each
+ language. These programs can use any address string as a source
+ or a destination, and have many command line options to
+ configure behavior&mdash;use the <command>-h</command> option
+ for documentation on these options.
+
+ <footnote><para>Currently, the C++, Python, and .NET C#
+ implementations of <command>drain</command> and
+ <command>spout</command> have slightly different
+ options. This tutorial uses the C++ implementation. The
+ options will be reconciled in the near
+ future.</para></footnote>
+
+
+ The examples in this tutorial also use the
+ <command>qpid-config</command> utility to configure AMQP 0-10
+ queues and exchanges on a Qpid broker.
+ </para>
+
+
+ <example>
+ <title>Queues</title>
+
+ <para>Create a queue with <command>qpid-config</command>, send a message using
+ <command>spout</command>, and read it using <command>drain</command>:</para>
+
+ <screen>
+$ qpid-config add queue hello-world
+$ ./spout hello-world
+$ ./drain hello-world
+
+Message(properties={spout-id:c877e622-d57b-4df2-bf3e-6014c68da0ea:0}, content='')
+ </screen>
+
+ <para>The queue stored the message sent by <command>spout</command> and delivered
+ it to <command>drain</command> when requested.</para>
+
+ <para>Once the message has been delivered and and acknowledged
+ by <command>drain</command>, it is no longer available on the queue. If we run
+ <command>drain</command> one more time, no messages will be retrieved.</para>
+
+ <screen>
+$ ./drain hello-world
+$
+ </screen>
+
+ </example>
+
+ <example>
+ <title>Topics</title>
+
+ <para>This example is similar to the previous example, but it
+ uses a topic instead of a queue.</para>
+
+ <para>First, use <command>qpid-config</command> to remove the queue
+ and create an exchange with the same name:</para>
+
+ <screen>
+$ qpid-config del queue hello-world
+$ qpid-config add exchange topic hello-world
+ </screen>
+
+ <para>Now run <command>drain</command> and <command>spout</command> the same way we did in the previous example:</para>
+
+ <screen>
+$ ./spout hello-world
+$ ./drain hello-world
+$
+ </screen>
+
+ <para>Topics deliver messages immediately to any interested
+ receiver, and do not store messages. Because there were no
+ receivers at the time <command>spout</command> sent the
+ message, it was simply discarded. When we ran
+ <command>drain</command>, there were no messages to
+ receive.</para>
+
+ <para>Now let's run <command>drain</command> first, using the
+ <literal>-t</literal> option to specify a timeout in seconds.
+ While <command>drain</command> is waiting for messages,
+ run <command>spout</command> in another window.</para>
+
+ <para><emphasis>First Window:</emphasis></para>
+
+ <screen>
+$ ./drain -t 30 hello-word
+ </screen>
+
+
+ <para><emphasis>Second Window:</emphasis></para>
+
+ <screen>
+$ ./spout hello-word
+ </screen>
+
+ <para>Once <command>spout</command> has sent a message, return
+ to the first window to see the output from
+ <command>drain</command>:</para>
+
+ <screen>
+Message(properties={spout-id:7da2d27d-93e6-4803-8a61-536d87b8d93f:0}, content='')
+ </screen>
+
+ <para>You can run <command>drain</command> in several separate
+ windows; each creates a subscription for the exchange, and
+ each receives all messages sent to the exchange.</para>
+
+ </example>
+
+ <section>
+ <title>Address Strings</title>
+
+ <para>So far, our examples have used address strings that
+ contain only the name of a node. An <firstterm>address
+ string</firstterm> can also contain a
+ <firstterm>subject</firstterm> and
+ <firstterm>options</firstterm>.</para>
+
+ <para>The syntax for an address string is:</para>
+
+ <programlisting><![CDATA[
+address_string ::= <address> [ / <subject> ] [ ; <options> ]
+options ::= { <key> : <value>, ... }
+]]></programlisting>
+
+ <para>Addresses, subjects, and keys are strings. Values can
+ be numbers, strings (with optional single or double quotes),
+ maps, or lists. A complete BNF for address strings appears in
+ <xref linkend="section-address-string-bnf"/>.</para>
+
+
+ <para>So far, the address strings in this tutorial have only
+ used simple names. The following sections show how to use
+ subjects and options.</para>
+
+ </section>
+
+ <section>
+ <title>Subjects</title>
+
+
+ <para>Every message has a property called
+ <firstterm>subject</firstterm>, which is analogous to the
+ subject on an email message. If no subject is specified, the
+ message's subject is null. For convenience, address strings
+ also allow a subject. If a sender's address contains a
+ subject, it is used as the default subject for the messages
+ it sends.
+
+ If a receiver's address contains a subject, it is used to
+ select only messages that match the subject&mdash;the matching
+ algorithm depends on the message source.
+ </para>
+
+ <para>
+ In AMQP 0-10, each exchange type has its own matching
+ algorithm. This is discussed in
+ <xref linkend="section-amqp0-10-mapping"/>.
+ </para>
+
+ <note>
+ <para>
+ Currently, a receiver bound to a queue ignores subjects,
+ receiving messages from the queue without filtering. Support
+ for subject filtering on queues will be implemented soon.
+ </para>
+ </note>
+
+
+ <example>
+ <title>Using subjects</title>
+
+ <para>In this example we show how subjects affect message
+ flow.</para>
+
+ <para>First, let's use <command>qpid-config</command> to create a topic exchange.</para>
+
+ <screen>
+$ qpid-config add exchange topic news-service
+ </screen>
+
+ <para>Now we use drain to receive messages from <literal>news-service</literal> that match the subject <literal>sports</literal>.</para>
+ <para><emphasis>First Window:</emphasis></para>
+ <screen>
+$ ./drain -t 30 news-service/sports
+ </screen>
+
+ <para>In a second window, let's send messages to <literal>news-service</literal> using two different subjects:</para>
+
+ <para><emphasis>Second Window:</emphasis></para>
+ <screen>
+$ ./spout news-service/sports
+$ ./spout news-service/news
+ </screen>
+
+ <para>Now look at the first window, the message with the
+ subject <literal>sports</literal> has been received, but not
+ the message with the subject <literal>news</literal>:</para>
+
+ <screen>
+Message(properties={qpid.subject:sports, spout-id:9441674e-a157-4780-a78e-f7ccea998291:0}, content='')
+ </screen>
+
+ <para>If you run <command>drain</command> in multiple
+ windows using the same subject, all instances of
+ <command>drain</command> receive the messages for that
+ subject.</para>
+ </example>
+
+
+ <para>The AMQP exchange type we are using here,
+ <literal>amq.topic</literal>, can also do more sophisticated
+ matching.
+
+ A sender's subject can contain multiple words separated by a
+ <quote>.</quote> delimiter. For instance, in a news
+ application, the sender might use subjects like
+ <literal>usa.news</literal>, <literal>usa.weather</literal>,
+ <literal>europe.news</literal>, or
+ <literal>europe.weather</literal>.
+
+ The receiver's subject can include wildcard characters&mdash;
+ <quote>#</quote> matches one or more words in the message's
+ subject, <quote>*</quote> matches a single word.
+
+ For instance, if the subject in the source address is
+ <literal>*.news</literal>, it matches messages with the
+ subject <literal>europe.news</literal> or
+ <literal>usa.news</literal>; if it is
+ <literal>europe.#</literal>, it matches messages with subjects
+ like <literal>europe.news</literal> or
+ <literal>europe.pseudo.news</literal>.</para>
+
+ <example>
+ <title>Subjects with multi-word keys</title>
+
+ <para>This example uses drain and spout to demonstrate the
+ use of subjects with two-word keys.</para>
+
+ <para>Let's use <command>drain</command> with the subject
+ <literal>*.news</literal> to listen for messages in which
+ the second word of the key is
+ <literal>news</literal>.</para>
+
+ <para><emphasis>First Window:</emphasis></para>
+
+ <screen>
+$ ./drain -t 30 news-service/*.news
+ </screen>
+
+ <para>Now let's send messages using several different
+ two-word keys:</para>
+
+ <para><emphasis>Second Window:</emphasis></para>
+
+ <screen>
+$ ./spout news-service/usa.news
+$ ./spout news-service/usa.sports
+$ ./spout news-service/europe.sports
+$ ./spout news-service/europe.news
+ </screen>
+
+ <para>In the first window, the messages with
+ <literal>news</literal> in the second word of the key have
+ been received:</para>
+
+ <screen>
+Message(properties={qpid.subject:usa.news, spout-id:73fc8058-5af6-407c-9166-b49a9076097a:0}, content='')
+Message(properties={qpid.subject:europe.news, spout-id:f72815aa-7be4-4944-99fd-c64c9747a876:0}, content='')
+ </screen>
+
+
+ <para>Next, let's use <command>drain</command> with the
+ subject <literal>#.news</literal> to match any sequence of
+ words that ends with <literal>news</literal>.</para>
+
+ <para><emphasis>First Window:</emphasis></para>
+
+ <screen>
+$ ./drain -t 30 news-service/#.news
+ </screen>
+
+ <para>In the second window, let's send messages using a
+ variety of different multi-word keys:</para>
+
+ <para><emphasis>Second Window:</emphasis></para>
+
+ <screen>
+$ ./spout news-service/news
+$ ./spout news-service/sports
+$ ./spout news-service/usa.news
+$ ./spout news-service/usa.sports
+$ ./spout news-service/usa.faux.news
+$ ./spout news-service/usa.faux.sports
+ </screen>
+
+ <para>In the first window, messages with
+ <literal>news</literal> in the last word of the key have been
+ received:</para>
+
+ <screen>
+Message(properties={qpid.subject:news, spout-id:cbd42b0f-c87b-4088-8206-26d7627c9640:0}, content='')
+Message(properties={qpid.subject:usa.news, spout-id:234a78d7-daeb-4826-90e1-1c6540781eac:0}, content='')
+Message(properties={qpid.subject:usa.faux.news, spout-id:6029430a-cfcb-4700-8e9b-cbe4a81fca5f:0}, content='')
+ </screen>
+ </example>
+
+ </section>
+
+ <section>
+ <title>Address String Options</title>
+
+ <para>
+ The options in an address string can contain additional
+ information for the senders or receivers created for it,
+ including:
+ </para>
+ <itemizedlist>
+ <listitem>
+ <para>
+ Policies for assertions about the node to which an address
+ refers.
+ </para>
+ <para>
+ For instance, in the address string <literal>my-queue;
+ {assert: always, node:{ type: queue }}</literal>, the node
+ named <literal>my-queue</literal> must be a queue; if not,
+ the address does not resolve to a node, and an exception
+ is raised.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Policies for automatically creating or deleting the node to which an address refers.
+ </para>
+ <para>
+ For instance, in the address string <literal>xoxox ; {create: always}</literal>,
+ the queue <literal>xoxox</literal> is created, if it does
+ not exist, before the address is resolved.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Extension points that can be used for sender/receiver configuration.
+ </para>
+ <para>
+ For instance, if the address for a receiver is
+ <literal>my-queue; {mode: browse}</literal>, the receiver
+ works in <literal>browse</literal> mode, leaving messages
+ on the queue so other receivers can receive them.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Extension points providing more direct control over the underlying protocol.
+ </para>
+ <para>
+ For instance, the <literal>x-bindings</literal> property
+ allows greater control over the AMQP 0-10 binding process
+ when an address is resolved.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+
+ <para>
+ Let's use some examples to show how these different kinds of
+ address string options affect the behavior of senders and
+ receives.
+ </para>
+
+ <section>
+ <title>assert</title>
+ <para>
+ In this section, we use the <literal>assert</literal> option
+ to ensure that the address resolves to a node of the required
+ type.
+ </para>
+
+
+ <example>
+ <title>Assertions on Nodes</title>
+
+ <para>Let's use <command>qpid-config</command> to create a
+ queue and a topic.</para>
+
+ <screen>
+$ qpid-config add queue my-queue
+$ qpid-config add exchange topic my-topic
+ </screen>
+
+ <para>
+ We can now use the address specified to drain to assert that it is
+ of a particular type:
+ </para>
+
+ <screen>
+$ ./drain 'my-queue; {assert: always, node:{ type: queue }}'
+$ ./drain 'my-queue; {assert: always, node:{ type: topic }}'
+2010-04-20 17:30:46 warning Exception received from broker: not-found: not-found: Exchange not found: my-queue (../../src/qpid/broker/ExchangeRegistry.cpp:92) [caused by 2 \x07:\x01]
+Exchange my-queue does not exist
+ </screen>
+
+ <para>
+ The first attempt passed without error as my-queue is indeed a
+ queue. The second attempt however failed; my-queue is not a
+ topic.
+ </para>
+
+ <para>
+ We can do the same thing for my-topic:
+ </para>
+
+ <screen>
+$ ./drain 'my-topic; {assert: always, node:{ type: topic }}'
+$ ./drain 'my-topic; {assert: always, node:{ type: queue }}'
+2010-04-20 17:31:01 warning Exception received from broker: not-found: not-found: Queue not found: my-topic (../../src/qpid/broker/SessionAdapter.cpp:754) [caused by 1 \x08:\x01]
+Queue my-topic does not exist
+ </screen>
+ </example>
+
+ <para>Now let's use the <literal>create</literal> option to
+ create the queue <literal>xoxox</literal> if it does not already
+ exist:</para>
+
+ </section>
+
+ <section>
+ <title>create</title>
+
+ <para>In previous examples, we created the queue before
+ listening for messages on it. Using <literal>create:
+ always</literal>, the queue is automatically created if it
+ does not exist.</para>
+
+ <example>
+ <title>Creating a Queue Automatically</title>
+
+ <para><emphasis>First Window:</emphasis></para>
+ <screen>$ ./drain -t 30 "xoxox ; {create: always}"</screen>
+
+
+ <para>Now we can send messages to this queue:</para>
+
+ <para><emphasis>Second Window:</emphasis></para>
+ <screen>$ ./spout "xoxox ; {create: always}"</screen>
+
+ <para>Returning to the first window, we see that <command>drain</command> has received this message:</para>
+
+ <screen>Message(properties={spout-id:1a1a3842-1a8b-4f88-8940-b4096e615a7d:0}, content='')</screen>
+ </example>
+ <para>The details of the node thus created can be controlled by further options within the node. See <xref linkend="table-node-properties"/> for details.</para>
+ </section>
+
+ <section>
+ <title>browse</title>
+ <para>Some options specify message transfer semantics; for
+ instance, they may state whether messages should be consumed or
+ read in browsing mode, or specify reliability
+ characteristics. The following example uses the
+ <literal>browse</literal> option to receive messages without
+ removing them from a queue.</para>
+
+ <example>
+ <title>Browsing a Queue</title>
+ <para>
+ Let's use the browse mode to receive messages without
+ removing them from the queue. First we send three messages to the
+ queue:
+ </para>
+ <screen>
+$ ./spout my-queue --content one
+$ ./spout my-queue --content two
+$ ./spout my-queue --content three
+ </screen>
+
+ <para>Now we use drain to get those messages, using the browse option:</para>
+ <screen>
+$ ./drain 'my-queue; {mode: browse}'
+Message(properties={spout-id:fbb93f30-0e82-4b6d-8c1d-be60eb132530:0}, content='one')
+Message(properties={spout-id:ab9e7c31-19b0-4455-8976-34abe83edc5f:0}, content='two')
+Message(properties={spout-id:ea75d64d-ea37-47f9-96a9-d38e01c97925:0}, content='three')
+ </screen>
+
+ <para>We can confirm the messages are still on the queue by repeating the drain:</para>
+ <screen>
+$ ./drain 'my-queue; {mode: browse}'
+Message(properties={spout-id:fbb93f30-0e82-4b6d-8c1d-be60eb132530:0}, content='one')
+Message(properties={spout-id:ab9e7c31-19b0-4455-8976-34abe83edc5f:0}, content='two')
+Message(properties={spout-id:ea75d64d-ea37-47f9-96a9-d38e01c97925:0}, content='three')
+ </screen>
+ </example>
+ </section>
+
+ <section>
+ <title>x-bindings</title>
+
+ <para>Greater control over the AMQP 0-10 binding process can
+ be achieved by including an <literal>x-bindings</literal>
+ option in an address string.
+
+ For instance, the XML Exchange is an AMQP 0-10 custom exchange
+ provided by the Apache Qpid C++ broker. It allows messages to
+ be filtered using XQuery; queries can address either message
+ properties or XML content in the body of the message. The
+ xquery is specified in the arguments field of the AMQP 0-10
+ command. When using the messaging API an xquery can be
+ specified in and address that resolves to an XML exchange by
+ using the x-bindings property.</para>
+
+
+ <para>An instance of the XML Exchange must be added before it
+ can be used:</para>
+
+ <programlisting>
+$ qpid-config add exchange xml xml
+ </programlisting>
+
+ <para>When using the XML Exchange, a receiver provides an
+ XQuery as an x-binding argument. If the query contains a
+ context item (a path starting with <quote>.</quote>), then it
+ is applied to the content of the message, which must be
+ well-formed XML. For instance, <literal>./weather</literal> is
+ a valid XQuery, which matches any message in which the root
+ element is named <literal>weather</literal>. Here is an
+ address string that contains this query:</para>
+
+ <programlisting><![CDATA[
+xml; {
+ link: {
+ x-bindings: [{exchange:xml, key:weather, arguments:{xquery:"./weather"} }]
+ }
+}
+ ]]></programlisting>
+
+ <para>When using longer queries with <command>drain</command>,
+ it is often useful to place the query in a file, and use
+ <command>cat</command> in the command line. We do this in the
+ following example.</para>
+
+ <example>
+ <title>Using the XML Exchange</title>
+
+ <para>This example uses an x-binding that contains queries, which filter based on the content of XML messages. Here is an XQuery that we will use in this example:</para>
+
+ <programlisting>
+ <![CDATA[
+let $w := ./weather
+return $w/station = 'Raleigh-Durham International Airport (KRDU)'
+ and $w/temperature_f > 50
+ and $w/temperature_f - $w/dewpoint > 5
+ and $w/wind_speed_mph > 7
+ and $w/wind_speed_mph < 20 ]]>
+ </programlisting>
+
+ <para>We can specify this query in an x-binding to listen to messages that meet the criteria specified by the query:</para>
+
+ <para><emphasis>First Window:</emphasis></para>
+
+ <screen>
+$ ./drain -f "xml; {link:{x-bindings:[{key:'weather',
+arguments:{xquery:\"$(cat rdu.xquery )\"}}]}}"
+ </screen>
+
+ <para>In another window, let's create an XML message that meets the criteria in the query, and place it in the file <filename>rdu.xml</filename>:</para>
+
+ <programlisting>
+<![CDATA[
+<weather>
+ <station>Raleigh-Durham International Airport (KRDU)</station>
+ <wind_speed_mph>16</wind_speed_mph>
+ <temperature_f>70</temperature_f>
+ <dewpoint>35</dewpoint>
+</weather>
+ ]]></programlisting>
+
+ <para>Now let's use <command>spout</command> to send this message to the XML exchange:</para>
+
+ <para><emphasis>Second Window:</emphasis></para>
+ <screen>
+spout --content "$(cat rdu.xml)" xml/weather
+ </screen>
+
+ <para>Returning to the first window, we see that the message has been received:</para>
+
+ <screen><![CDATA[$ ./drain -f "xml; {link:{x-bindings:[{exchange:'xml', key:'weather', arguments:{xquery:\"$(cat rdu.xquery )\"}}]}}"
+Message(properties={qpid.subject:weather, spout-id:31c431de-593f-4bec-a3dd-29717bd945d3:0},
+content='<weather>
+ <station>Raleigh-Durham International Airport (KRDU)</station>
+ <wind_speed_mph>16</wind_speed_mph>
+ <temperature_f>40</temperature_f>
+ <dewpoint>35</dewpoint>
+</weather>') ]]>
+ </screen>
+ </example>
+ </section>
+
+<!--
+ <para>When sending data using <command>cat</command> to provide arguments to <command>spout</command>, you can use <command>sed</command> to change the values that are sent:</para>
+
+ <screen>
+spout - -content "$(cat rdu.xml | sed -e 's/70/45/')" xml/weather
+ </screen>
+-->
+
+ <!--
+ TODO: Add some reliability option examples
+ -->
+
+ <section>
+ <title>Address String Options - Reference</title>
+
+ <table pgwide="1">
+ <title>Address String Options</title>
+ <tgroup cols="3">
+ <thead>
+ <colspec colnum="1" colwidth="1*"/>
+ <colspec colnum="2" colwidth="3*"/>
+ <colspec colnum="3" colwidth="3*"/>
+ <row>
+ <entry>option</entry>
+ <entry>value</entry>
+ <entry>semantics</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>
+ assert
+ </entry>
+ <entry>
+ one of: always, never, sender or receiver
+ </entry>
+ <entry>
+ Asserts that the properties specified in the node option
+ match whatever the address resolves to. If they do not,
+ resolution fails and an exception is raised. <!-- ###
+ Which exception -->
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ create
+ </entry>
+ <entry>
+ one of: always, never, sender or receiver
+ </entry>
+ <entry>
+ Creates the node to which an address refers if it does
+ not exist. No error is raised if the node does
+ exist. The details of the node may be specified in the
+ node option.
+ </entry>
+ </row>
+ <row>
+ <entry>
+ delete
+ </entry>
+ <entry>
+ one of: always, never, sender or receiver
+ </entry>
+ <entry>
+ Delete the node when the sender or receiver is closed.
+ </entry>
+ </row>
+ <row>
+ <entry>
+ node
+ </entry>
+ <entry>
+ A nested map containing the entries shown in <xref linkend="table-node-properties"/>.
+ </entry>
+ <entry>
+ Specifies properties of the node to which the address
+ refers. These are used in conjunction with the assert or
+ create options.
+ </entry>
+ </row>
+ <row>
+ <entry>
+ link
+ </entry>
+ <entry>
+ A nested map containing the entries shown in <xref linkend="table-link-properties"/>.
+ </entry>
+ <entry>
+ Used to control the establishment of a conceptual link
+ from the client application to or from the target/source
+ address.
+ </entry>
+ </row>
+ <row>
+ <entry>
+ mode
+ </entry>
+ <entry>
+ one of: browse, consume
+ </entry>
+ <entry>
+ This option is only of relevance for source addresses
+ that resolve to a queue. If browse is specified the
+ messages delivered to the receiver are left on the queue
+ rather than being removed. If consume is specified the
+ normal behaviour applies; messages are removed from the
+ queue once the client acknowledges their receipt.
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+
+ <table id="table-node-properties" pgwide="1">
+ <title>Node Properties</title>
+ <tgroup cols="3">
+ <thead>
+ <colspec colnum="1" colwidth="1*"/>
+ <colspec colnum="2" colwidth="3*"/>
+ <colspec colnum="3" colwidth="3*"/>
+ <row>
+ <entry>property</entry>
+ <entry>value</entry>
+ <entry>semantics</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>
+ type
+ </entry>
+ <entry>
+ topic, queue
+ </entry>
+ <entry>
+ Indicates the type of the node.
+ </entry>
+ </row>
+ <row>
+ <entry>
+ durable
+ </entry>
+ <entry>
+ True, False
+ </entry>
+ <entry>
+ Indicates whether the node survives a loss of
+ volatile storage e.g. if the broker is restarted.
+ </entry>
+ </row>
+ <row>
+ <entry>
+ x-declare
+ </entry>
+ <entry>
+ A nested map whose values correspond to the valid fields
+ on an AMQP 0-10 queue-declare or exchange-declare
+ command.
+ </entry>
+ <entry>
+ These values are used to fine tune the creation or
+ assertion process. Note however that they are protocol
+ specific.
+ </entry>
+ </row>
+ <row>
+ <entry>
+ x-bindings
+ </entry>
+ <entry>
+ A nested list in which each binding is represented by
+ a map. The entries of the map for a binding contain
+ the fields that describe an AMQP 0-10 binding. Here is
+ the format for x-bindings:
+
+<programlisting><![CDATA[
+[
+ {
+ exchange: <exchange>,
+ queue: <queue>,
+ key: <key>,
+ arguments: {
+ <key_1>: <value_1>,
+ ...,
+ <key_n>: <value_n> }
+ },
+ ...
+]
+]]></programlisting>
+ </entry>
+ <entry>
+ In conjunction with the create option, each of these
+ bindings is established as the address is resolved. In
+ conjunction with the assert option, the existence of
+ each of these bindings is verified during
+ resolution. Again, these are protocol specific.
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table id="table-link-properties" pgwide="1">
+ <title>Link Properties</title>
+ <tgroup cols="3">
+ <thead>
+ <colspec colnum="1" colwidth="1*"/>
+ <colspec colnum="2" colwidth="3*"/>
+ <colspec colnum="3" colwidth="3*"/>
+ <row>
+ <entry>option</entry>
+ <entry>value</entry>
+ <entry>semantics</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>
+ reliability
+ </entry>
+ <entry>
+ one of: unreliable, at-least-once, at-most-once, exactly-once
+ </entry>
+ <entry>
+ Reliability indicates the level of reliability that
+ the sender or receiver. <literal>unreliable</literal>
+ and <literal>at-most-once</literal> are currently
+ treated as synonyms, and allow messages to be lost if
+ a broker crashes or the connection to a broker is
+ lost. <literal>at-least-once</literal> guarantees that
+ a message is not lost, but duplicates may be
+ received. <literal>exactly-once</literal> guarantees
+ that a message is not lost, and is delivered precisely
+ once. Currently only <literal>unreliable</literal>
+ and <literal>at-least-once</literal> are supported.
+ <footnote><para>If at-most-once is requested,
+ unreliable will be used and for durable messages on
+ durable queues there is the possibility that messages
+ will be redelivered; if exactly-once is requested,
+ at-most-once will be used and the application needs to
+ be able to deal with duplicates.</para></footnote>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ durable
+ </entry>
+ <entry>
+ True, False
+ </entry>
+ <entry>
+ Indicates whether the link survives a loss of
+ volatile storage e.g. if the broker is restarted.
+ </entry>
+ </row>
+ <row>
+ <entry>
+ x-declare
+ </entry>
+ <entry>
+ A nested map whose values correspond to the valid fields
+ of an AMQP 0-10 queue-declare command.
+ </entry>
+ <entry>
+ These values can be used to customise the subscription
+ queue in the case of receiving from an exchange. Note
+ however that they are protocol specific.
+ </entry>
+ </row>
+ <row>
+ <entry>
+ x-subscribe
+ </entry>
+ <entry>
+ A nested map whose values correspond to the valid fields
+ of an AMQP 0-10 message-subscribe command.
+ </entry>
+ <entry>
+ These values can be used to customise the subscription.
+ </entry>
+ </row>
+ <row>
+ <entry>
+ x-bindings
+ </entry>
+ <entry>
+ A nested list each of whose entries is a map that may
+ contain fields (queue, exchange, key and arguments)
+ describing an AMQP 0-10 binding.
+ </entry>
+ <entry>
+ These bindings are established during resolution
+ independent of the create option. They are considered
+ logically part of the linking process rather than of
+ node creation.
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </section>
+ </section>
+
+ <section id="section-address-string-bnf">
+ <title>Address String Grammar</title>
+
+ <para>This section provides a formal grammar for address strings.</para>
+
+ <formalpara>
+ <title>Tokens</title>
+ <para>The following regular expressions define the tokens used
+ to parse address strings:</para></formalpara>
+<programlisting><![CDATA[
+LBRACE: \\{
+RBRACE: \\}
+LBRACK: \\[
+RBRACK: \\]
+COLON: :
+SEMI: ;
+SLASH: /
+COMMA: ,
+NUMBER: [+-]?[0-9]*\\.?[0-9]+
+ID: [a-zA-Z_](?:[a-zA-Z0-9_-]*[a-zA-Z0-9_])?
+STRING: "(?:[^\\\\"]|\\\\.)*"|\'(?:[^\\\\\']|\\\\.)*\'
+ESC: \\\\[^ux]|\\\\x[0-9a-fA-F][0-9a-fA-F]|\\\\u[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]
+SYM: [.#*%@$^!+-]
+WSPACE: [ \\n\\r\\t]+
+]]></programlisting>
+
+ <formalpara>
+ <title>Grammar</title>
+ <para>The formal grammar for addresses is given below:</para>
+ </formalpara>
+
+ <programlisting><![CDATA[
+address := name [ SLASH subject ] [ ";" options ]
+ name := ( part | quoted )+
+subject := ( part | quoted | SLASH )*
+ quoted := STRING / ESC
+ part := LBRACE / RBRACE / COLON / COMMA / NUMBER / ID / SYM
+options := map
+ map := "{" ( keyval ( "," keyval )* )? "}"
+ keyval "= ID ":" value
+ value := NUMBER / STRING / ID / map / list
+ list := "[" ( value ( "," value )* )? "]"
+ ]]></programlisting>
+
+
+ <formalpara>
+ <title>Address String Options</title>
+ <para>The address string options map supports the following parameters:</para>
+ </formalpara>
+
+ <programlisting><![CDATA[
+<name> [ / <subject> ] ; {
+ create: always | sender | receiver | never,
+ delete: always | sender | receiver | never,
+ assert: always | sender | receiver | never,
+ mode: browse | consume,
+ node: {
+ type: queue | topic,
+ durable: True | False,
+ x-declare: { ... <declare-overrides> ... },
+ x-bindings: [<binding_1>, ... <binding_n>]
+ },
+ link: {
+ name: <link-name>,
+ durable: True | False,
+ reliability: unreliable | at-most-once | at-least-once | exactly-once,
+ x-declare: { ... <declare-overrides> ... },
+ x-bindings: [<binding_1>, ... <binding_n>],
+ x-subscribe: { ... <subscribe-overrides> ... }
+ }
+}
+]]></programlisting>
+
+
+ <itemizedlist>
+ <title>Create, Delete, and Assert Policies</title>
+ <para>The create, delete, and assert policies specify who should
+ perfom the associated action:</para>
+ <listitem><para><emphasis>always</emphasis>: the action is performed by any messaging client</para></listitem>
+ <listitem><para><emphasis>sender</emphasis>: the action is only performed by a sender</para></listitem>
+ <listitem><para><emphasis>receiver</emphasis>: the action is only performed by a receiver</para></listitem>
+ <listitem><para><emphasis>never</emphasis>: the action is never performed (this is the default)</para></listitem>
+ </itemizedlist>
+
+ <itemizedlist>
+ <title>Node-Type</title>
+ <para>The node-type is one of:</para>
+ <listitem><para><emphasis>topic</emphasis>: in the AMQP 0-10
+ mapping, a topic node defaults to the topic exchange, x-declare
+ may be used to specify other exchange types</para></listitem>
+ <listitem><para><emphasis>queue</emphasis>: this is the default node-type</para></listitem>
+ </itemizedlist>
+ </section>
+
+
+</section>
+
+<section id="replay">
+ <title>Sender Capacity and Replay</title>
+
+ <para>The send method of a sender has an optional second parameter
+ that controls whether the send call is synchronous or not. A
+ synchronous send call will block until the broker has confirmed
+ receipt of the message. An asynchronous send call will return
+ before the broker confirms receipt of the message, allowing for
+ example further send calls to be made without waiting for a
+ roundtrip to the broker for each message. This is desirable where
+ increased throughput is important.</para>
+
+ <para>The sender maintains a list of sent messages whose receipt
+ has yet to be confirmed by the broker. The maximum number of such
+ messages that it will hold is defined by the capacity of the
+ sender, which can be set by the application. If an application
+ tries to send with a sender whose capacity is already fully used
+ up, the send call will block waiting for capacity regardless of
+ the value of the sync flag.</para>
+
+ <para>The sender can be queried for the available space (i.e. the
+ unused capacity), and for the current count of unsettled messages
+ (i.e. those held in the replay list pending confirmation by the
+ server). When the unsettled count is zero, all messages on that
+ sender have been successfully sent.</para>
+
+ <para>If the connection fails and is transparently reconnected
+ (see <xref linkend="connection-options"/> for details on how to control
+ this feature), the unsettled messages for each sender over that
+ connection will be re-transmitted. This provides a transparent
+ level of reliability. This feature can be controlled through the
+ link's reliability as defined in the address (see
+ <xref linkend="table-link-properties"/>). At present only
+ at-least-once guarantees are offered. </para>
+</section>
+
+<section id="prefetch">
+ <title>Receiver Capacity (Prefetch)</title>
+
+ <para>By default, a receiver requests the next message from the
+ server in response to each fetch call, resulting in messages being
+ sent to the receiver one at a time. As in the case of sending, it
+ is often desirable to avoid this roundtrip for each message. This
+ can be achieved by allowing the receiver
+ to <firstterm>prefetch</firstterm> messages in anticipation of
+ fetch calls being made. The receiver needs to be able to store
+ these prefetched messages, the number it can hold is controlled by
+ the receivers capacity.</para>
+
+</section>
+
+<section id="acknowledgements">
+ <title>Acknowledging Received Messages</title>
+
+ <para>Applications that receive messages should acknowledge their
+ receipt by calling the session's acknowledge method. As in the
+ case of sending messages, acknowledged transfer of messages to
+ receivers provides at-least-once reliability, which means that the
+ loss of the connection or a client crash does not result in lost
+ messages; durable messages are not lost even if the broker is
+ restarted.
+
+ Some cases may not require this however and the reliability can be
+ controlled through a link property in the address options (see
+ <xref linkend="table-link-properties"/>).</para>
+
+ <para>The acknowledge call acknowledges all messages received on
+ the session (i.e. all message that have been returned from a fetch
+ call on a receiver created on that session).</para>
+
+ <para>The acknowledge call also support an optional parameter
+ controlling whether the call is synchronous or not. A synchronous
+ acknowledge will block until the server has confirmed that it has
+ received the acknowledgement. In the asynchronous case, when the
+ call returns there is not yet any guarantee that the server has
+ received and processed the acknowledgement. The session may be
+ queried for the number of unsettled acknowledgements; when that
+ count is zero all acknowledgements made for received messages have
+ been successful.</para>
+
+</section>
+
+
+ <section>
+ <title>Receiving Messages from Multiple Sources</title>
+
+ <para>A receiver can only read from one source, but many
+ programs need to be able to read messages from many sources. In
+ the Qpid Messaging API, a program can ask a session for
+ the <quote>next receiver</quote>; that is, the receiver that is
+ responsible for the next available message. The following
+ examples show how this is done in C++, Python, and .NET C#.
+ </para>
+
+ <para>Note that to use this pattern you must enable prefetching
+ for each receiver of interest so that the broker will send
+ messages before a fetch call is made. See
+ <xref linkend="prefetch"/> for more on this.</para>
+
+ <example>
+ <title>Receiving Messages from Multiple Sources</title>
+
+ <para>C++:</para>
+
+ <programlisting><![CDATA[
+Receiver receiver1 = session.createReceiver(address1);
+receiver1.setCapacity(10);
+Receiver receiver2 = session.createReceiver(address2);
+receiver2.setCapacity(10);
+
+Message message = session.nextReceiver().fetch();
+std::cout << message.getContent() << std::endl;
+session.acknowledge(); // acknowledge message receipt
+]]> </programlisting>
+
+ <para>Python:</para>
+ <programlisting><![CDATA[
+receiver1 = session.receiver(address1)
+receiver1.capacity = 10
+receiver2 = session.receiver(address)
+receiver2.capacity = 10
+message = session.next_receiver().fetch()
+print message.content
+session.acknowledge()
+]]> </programlisting>
+
+ <para>.NET C#:</para>
+ <programlisting><![CDATA[
+Receiver receiver1 = session.CreateReceiver(address1);
+receiver1.Capacity = 10;
+Receiver receiver2 = session.CreateReceiver(address2);
+receiver2.Capacity = 10;
+
+Message message = new Message();
+message = session.NextReceiver().Fetch();
+Console.WriteLine("{0}", message.GetContent());
+session.Acknowledge();
+]]> </programlisting>
+
+ </example>
+ </section>
+
+ <section>
+ <title>Transactions</title>
+
+ <para>Sometimes it is useful to be able to group messages
+ transfers - sent and/or received - on a session into atomic
+ grouping. This can be done be creating the session as
+ transactional. On a transactional session sent messages only
+ become available at the target address on commit. Likewise any
+ received and acknowledged messages are only discarded at their
+ source on commit
+
+ <footnote><para>Note that this currently is only true for
+ messages received using a reliable mode
+ e.g. at-least-once. Messages sent by a broker to a receiver in
+ unreliable receiver will be discarded immediately regardless of
+ transctionality.</para></footnote>
+
+ .</para>
+
+ <example>
+ <title>Transactions</title>
+ <para>C++:</para>
+ <programlisting><![CDATA[
+Connection connection(broker);
+Session session = connection.createTransactionalSession();
+...
+if (smellsOk())
+ session.commit();
+else
+ session.rollback();
+ ]]></programlisting>
+ <para>
+ .NET C#:
+ </para>
+
+<programlisting>
+Connection connection = new Connection(broker);
+Session session = connection.CreateTransactionalSession();
+...
+if (smellsOk())
+ session.Commit();
+else
+ session.Rollback();
+</programlisting>
+<!--
+ <para>Python</para>
+ <programlisting><![CDATA[
+### TODO
+ ]]></programlisting>
+-->
+ </example>
+
+ </section>
+
+ <section id="connection-options">
+ <title>Connection Options</title>
+
+ <para>
+ Aspects of the connections behaviour can be controlled through
+ specifying connection options. For example, connections can be
+ configured to automatically reconnect if the connection to a
+ broker is lost.
+ </para>
+
+ <example>
+ <title>Specifying Connection Options in C++, Python, and .NET</title>
+
+ <para>In C++, these options can be set using <function>Connection::setOption()</function> or by passing in a set of options to the constructor. The options can be passed in as a map or in string form:</para>
+
+ <programlisting><![CDATA[
+Connection connection("localhost:5672", "{reconnect: true}");
+try {
+ connection.open();
+ !!! SNIP !!!
+ ]]></programlisting>
+
+<para>or</para>
+
+ <programlisting><![CDATA[
+Connection connection("localhost:5672");
+connection.setOption("reconnect", true);
+try {
+ connection.open();
+ !!! SNIP !!!
+ ]]></programlisting>
+
+ <para>In Python, these options can be set as attributes of the connection or using named arguments in
+ the <function>Connection</function> constructor:</para>
+
+ <programlisting><![CDATA[
+connection = Connection("localhost:5672", reconnect=True)
+try:
+ connection.open()
+ !!! SNIP !!!
+ ]]></programlisting>
+
+<para>or</para>
+
+ <programlisting><![CDATA[
+connection = Connection("localhost:5672")
+connection.reconnect = True
+try:
+ connection.open()
+ !!! SNIP !!!
+ ]]></programlisting>
+ <para>
+ In .NET, these options can be set using <function>Connection.SetOption()</function> or by passing in a set of options to the constructor. The options can be passed in as a map or in string form:
+ </para>
+
+<programlisting>
+Connection connection= new Connection(&#34;localhost:5672&#34;, &#34;{reconnect: true}&#34;);
+try {
+ connection.Open();
+ !!! SNIP !!!
+</programlisting>
+ <para>
+ or
+ </para>
+
+<programlisting>
+Connection connection = new Connection(&#34;localhost:5672&#34;);
+connection.SetOption(&#34;reconnect&#34;, true);
+try {
+ connection.Open();
+ !!! SNIP !!!
+</programlisting>
+
+ <para>See the reference documentation for details in each language.</para>
+ </example>
+
+ <para>The following table lists the supported connection options.</para>
+
+ <table pgwide="1">
+ <title>Connection Options</title>
+ <tgroup cols="3">
+ <thead>
+ <colspec colnum="1" colwidth="1*"/>
+ <colspec colnum="2" colwidth="1*"/>
+ <colspec colnum="3" colwidth="3*"/>
+ <row>
+ <entry>option name</entry>
+ <entry>value type</entry>
+ <entry>semantics</entry>
+ </row>
+ </thead>
+ <tbody>
+
+ <row>
+ <entry>
+ <literal>username</literal>
+ </entry>
+ <entry>
+ string
+ </entry>
+ <entry>
+ The username to use when authenticating to the broker.
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>password</literal>
+ </entry>
+ <entry>
+ string
+ </entry>
+ <entry>
+ The password to use when authenticating to the broker.
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>sasl_mechanisms</literal>
+ </entry>
+ <entry>
+ string
+ </entry>
+ <entry>
+ The specific SASL mechanisms to use with the python
+ client when authenticating to the broker. The value
+ is a space separated list.
+ </entry>
+ </row>
+
+
+ <row>
+ <entry>
+ <literal>reconnect</literal>
+ </entry>
+ <entry>
+ boolean
+ </entry>
+ <entry>
+ Transparently reconnect if the connection is lost.
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>reconnect_timeout</literal>
+ </entry>
+ <entry>
+ integer
+ </entry>
+ <entry>
+ Total number of seconds to continue reconnection attempts before giving up and raising an exception.
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>reconnect_limit</literal>
+ </entry>
+ <entry>
+ integer
+ </entry>
+ <entry>
+ Maximum number of reconnection attempts before giving up and raising an exception.
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>reconnect_interval_min</literal>
+ </entry>
+ <entry>
+ integer representing time in seconds
+ </entry>
+ <entry>
+ Minimum number of seconds between reconnection attempts. The first reconnection attempt is made immediately; if that fails, the first reconnection delay is set to the value of <literal>reconnect_interval_min</literal>; if that attempt fails, the reconnect interval increases exponentially until a reconnection attempt succeeds or <literal>reconnect_interval_max</literal> is reached.
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>reconnect_interval_max</literal>
+ </entry>
+ <entry>
+ integer representing time in seconds
+ </entry>
+ <entry>
+ Maximum reconnect interval.
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>reconnect_interval</literal>
+ </entry>
+ <entry>
+ integer representing time in seconds
+ </entry>
+ <entry>
+ Sets both <literal>reconnection_interval_min</literal> and <literal>reconnection_interval_max</literal> to the same value.
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <literal>heartbeat</literal>
+ </entry>
+ <entry>
+ integer representing time in seconds
+ </entry>
+ <entry>
+ Requests that heartbeats be sent every N seconds. If two
+ successive heartbeats are missed the connection is
+ considered to be lost.
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>protocol</literal>
+ </entry>
+ <entry>
+ string
+ </entry>
+ <entry>
+ Sets the underlying protocol used. The default option is 'tcp'. To enable ssl, set to 'ssl'. The C++ client additionally supports 'rdma'.
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>tcp-nodelay</literal>
+ </entry>
+ <entry>
+ boolean
+ </entry>
+ <entry>
+ Set tcp no-delay, i.e. disable Nagle algorithm. [C++ only]
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </section>
+
+ <section id="section-Maps">
+ <title>Maps and Lists in Message Content</title>
+
+ <para>Many messaging applications need to exchange data across
+ languages and platforms, using the native datatypes of each
+ programming language.</para>
+
+ <para>The Qpid Messaging API supports <classname>map</classname> and <classname>list</classname> in message content.
+
+ <footnote><para>Unlike JMS, there is not a specific message type for
+ map messages.</para></footnote>
+
+ <footnote>
+ <para>
+ Note that the Qpid JMS client supports MapMessages whose values can be nested maps or lists. This is not standard JMS behaviour.
+ </para>
+ </footnote>
+ Specific language support for <classname>map</classname> and <classname>list</classname> objects are shown in the following table.
+ </para>
+ <table id="tabl-Programming_in_Apache_Qpid-Qpid_Maps_in_Message_Content">
+ <title>Map and List Representation in Supported Languages</title>
+ <tgroup cols="3">
+ <thead>
+ <row>
+ <entry>Language</entry>
+ <entry>map</entry>
+ <entry>list</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>Python</entry>
+ <entry><classname>dict</classname></entry>
+ <entry><classname>list</classname></entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry><classname>Variant::Map</classname></entry>
+ <entry><classname>Variant::List</classname></entry>
+ </row>
+ <row>
+ <entry>Java</entry>
+ <entry><classname>MapMessage</classname></entry>
+ <entry><classname>&nbsp;</classname></entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry><classname>Dictionary&#60;string, object&#62;</classname></entry>
+ <entry><classname>Collection&#60;object&#62;</classname></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ <para>
+ In all languages, messages are encoded using AMQP&#39;s portable datatypes.
+ </para>
+
+ <tip>
+ <para>Because of the differences in type systems among
+ languages, the simplest way to provide portable messages is to
+ rely on maps, lists, strings, 64 bit signed integers, and
+ doubles for messages that need to be exchanged across languages
+ and platforms.</para>
+ </tip>
+
+ <section id="section-Python-Maps">
+ <title>Qpid Maps and Lists in Python</title>
+
+ <para>In Python, Qpid supports the <classname>dict</classname> and <classname>list</classname> types directly in message content. The following code shows how to send these structures in a message:</para>
+
+ <example>
+ <title>Sending Qpid Maps and Lists in Python</title>
+ <programlisting><![CDATA[
+from qpid.messaging import *
+# !!! SNIP !!!
+
+content = {'Id' : 987654321, 'name' : 'Widget', 'percent' : 0.99}
+content['colours'] = ['red', 'green', 'white']
+content['dimensions'] = {'length' : 10.2, 'width' : 5.1,'depth' : 2.0};
+content['parts'] = [ [1,2,5], [8,2,5] ]
+content['specs'] = {'colors' : content['colours'],
+ 'dimensions' : content['dimensions'],
+ 'parts' : content['parts'] }
+message = Message(content=content)
+sender.send(message)
+ ]]> </programlisting>
+ </example>
+
+
+ <para>The following table shows the datatypes that can be sent in a Python map message,
+ and the corresponding datatypes that will be received by clients in Java or C++.</para>
+
+
+ <table id="table-Python-Maps" >
+ <title>Python Datatypes in Maps</title>
+ <tgroup cols="3">
+ <thead>
+ <row>
+ <entry>Python Datatype</entry>
+ <entry>&rarr; C++</entry>
+ <entry>&rarr; Java</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row><entry>bool</entry><entry>bool</entry><entry>boolean</entry></row>
+ <row><entry>int</entry><entry>int64</entry><entry>long</entry></row>
+ <row><entry>long</entry><entry>int64</entry><entry>long</entry></row>
+ <row><entry>float</entry><entry>double</entry><entry>double</entry></row>
+ <row><entry>unicode</entry><entry>string</entry><entry>java.lang.String</entry></row>
+ <row><entry>uuid</entry><entry>qpid::types::Uuid</entry><entry>java.util.UUID</entry></row>
+ <row><entry>dict</entry><entry>Variant::Map</entry><entry>java.util.Map</entry></row>
+ <row><entry>list</entry><entry>Variant::List</entry><entry>java.util.List</entry></row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </section>
+
+
+
+
+ <section id="section-cpp-Maps">
+ <title>Qpid Maps and Lists in C++</title>
+
+
+ <para>In C++, Qpid defines the the
+ <classname>Variant::Map</classname> and
+ <classname>Variant::List</classname> types, which can be
+ encoded into message content. The following code shows how to
+ send these structures in a message:</para>
+
+ <example>
+ <title>Sending Qpid Maps and Lists in C++</title>
+ <programlisting><![CDATA[
+using namespace qpid::types;
+
+// !!! SNIP !!!
+
+Message message;
+Variant::Map content;
+content["id"] = 987654321;
+content["name"] = "Widget";
+content["percent"] = 0.99;
+Variant::List colours;
+colours.push_back(Variant("red"));
+colours.push_back(Variant("green"));
+colours.push_back(Variant("white"));
+content["colours"] = colours;
+
+Variant::Map dimensions;
+dimensions["length"] = 10.2;
+dimensions["width"] = 5.1;
+dimensions["depth"] = 2.0;
+content["dimensions"]= dimensions;
+
+Variant::List part1;
+part1.push_back(Variant(1));
+part1.push_back(Variant(2));
+part1.push_back(Variant(5));
+
+Variant::List part2;
+part2.push_back(Variant(8));
+part2.push_back(Variant(2));
+part2.push_back(Variant(5));
+
+Variant::List parts;
+parts.push_back(part1);
+parts.push_back(part2);
+content["parts"]= parts;
+
+Variant::Map specs;
+specs["colours"] = colours;
+specs["dimensions"] = dimensions;
+specs["parts"] = parts;
+content["specs"] = specs;
+
+encode(content, message);
+sender.send(message, true);
+]]> </programlisting>
+ </example>
+
+ <para>The following table shows the datatypes that can be sent
+ in a C++ map message, and the corresponding datatypes that
+ will be received by clients in Java and Python.</para>
+
+ <table id="table-cpp-Maps">
+ <title>C++ Datatypes in Maps</title>
+ <tgroup cols="3">
+ <thead>
+ <row>
+ <entry>C++ Datatype</entry>
+ <entry>&rarr; Python</entry>
+ <entry>&rarr; Java</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row><entry>bool</entry><entry>bool</entry><entry>boolean</entry></row>
+ <row><entry>uint16</entry><entry>int | long</entry><entry>short</entry></row>
+ <row><entry>uint32</entry><entry>int | long</entry><entry>int</entry></row>
+ <row><entry>uint64</entry><entry>int | long</entry><entry>long</entry></row>
+ <row><entry>int16</entry><entry>int | long</entry><entry>short</entry></row>
+ <row><entry>int32</entry><entry>int | long</entry><entry>int</entry></row>
+ <row><entry>int64</entry><entry>int | long</entry><entry>long</entry></row>
+ <row><entry>float</entry><entry>float</entry><entry>float</entry></row>
+ <row><entry>double</entry><entry>float</entry><entry>double</entry></row>
+ <row><entry>string</entry><entry>unicode</entry><entry>java.lang.String</entry></row>
+ <row><entry>qpid::types::Uuid</entry><entry>uuid</entry><entry>java.util.UUID</entry></row>
+ <row><entry>Variant::Map</entry><entry>dict</entry><entry>java.util.Map</entry></row>
+ <row><entry>Variant::List</entry><entry>list</entry><entry>java.util.List</entry></row>
+ </tbody>
+ </tgroup>
+ </table>
+ </section>
+
+ <section id="section-dotnet-Maps">
+ <title>Qpid Maps and Lists in .NET</title>
+
+
+ <para>
+ The .NET binding for the Qpid Messaging API binds .NET managed data types
+ to C++ <classname>Variant</classname> data types. The following code shows how to
+ send Map and List structures in a message:
+ </para>
+
+ <example>
+ <?dbfo keep-together="auto" ?>
+ <title>Sending Qpid Maps and Lists in .NET C#</title>
+ <programlisting><![CDATA[
+using System;
+using Org.Apache.Qpid.Messaging;
+
+// !!! SNIP !!!
+
+Dictionary<string, object> content = new Dictionary<string, object>();
+Dictionary<string, object> subMap = new Dictionary<string, object>();
+Collection<object> colors = new Collection<object>();
+
+// add simple types
+content["id"] = 987654321;
+content["name"] = "Widget";
+content["percent"] = 0.99;
+
+// add nested amqp/map
+subMap["name"] = "Smith";
+subMap["number"] = 354;
+content["nestedMap"] = subMap;
+
+// add an amqp/list
+colors.Add("red");
+colors.Add("green");
+colors.Add("white");
+content["colorsList"] = colors;
+
+// add one of each supported amqp data type
+bool mybool = true;
+content["mybool"] = mybool;
+
+byte mybyte = 4;
+content["mybyte"] = mybyte;
+
+UInt16 myUInt16 = 5;
+content["myUInt16"] = myUInt16;
+
+UInt32 myUInt32 = 6;
+content["myUInt32"] = myUInt32;
+
+UInt64 myUInt64 = 7;
+content["myUInt64"] = myUInt64;
+
+char mychar = 'h';
+content["mychar"] = mychar;
+
+Int16 myInt16 = 9;
+content["myInt16"] = myInt16;
+
+Int32 myInt32 = 10;
+content["myInt32"] = myInt32;
+
+Int64 myInt64 = 11;
+content["myInt64"] = myInt64;
+
+Single mySingle = (Single)12.12;
+content["mySingle"] = mySingle;
+
+Double myDouble = 13.13;
+content["myDouble"] = myDouble;
+
+Guid myGuid = new Guid("000102030405060708090a0b0c0d0e0f");
+content["myGuid"] = myGuid;
+
+Message message = new Message(content);
+Send(message, true);
+]]> </programlisting>
+ </example>
+
+ <para>
+ The following table shows the mapping between datatypes in .NET and C++.
+ </para>
+
+ <table id="table-dotnet-Maps">
+ <title>Datatype Mapping between C++ and .NET binding</title>
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>C++ Datatype</entry>
+ <entry>&rarr; .NET binding</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row><entry>void</entry><entry>nullptr</entry></row>
+ <row><entry>bool</entry><entry>bool</entry></row>
+ <row><entry>uint8</entry><entry>byte</entry></row>
+ <row><entry>uint16</entry><entry>UInt16</entry></row>
+ <row><entry>uint32</entry><entry>UInt32</entry></row>
+ <row><entry>uint64</entry><entry>UInt64</entry></row>
+ <row><entry>uint8</entry><entry>char</entry></row>
+ <row><entry>int16</entry><entry>Int16</entry></row>
+ <row><entry>int32</entry><entry>Int32</entry></row>
+ <row><entry>int64</entry><entry>Int64</entry></row>
+ <row><entry>float</entry><entry>Single</entry></row>
+ <row><entry>double</entry><entry>Double</entry></row>
+ <row><entry>string</entry><entry>string
+ <footnote id="callout-dotnet-string">
+ <para>Strings are currently interpreted only with UTF-8 encoding.</para>
+ </footnote></entry></row>
+ <row><entry>qpid::types::Uuid</entry><entry>Guid</entry></row>
+ <row><entry>Variant::Map</entry><entry><![CDATA[Dictionary<string, object>]]>
+ <footnoteref linkend="callout-dotnet-string"/></entry></row>
+ <row><entry>Variant::List</entry><entry><![CDATA[Collection<object>]]>
+ <footnoteref linkend="callout-dotnet-string"/></entry></row>
+ </tbody>
+ </tgroup>
+ </table>
+
+
+ </section>
+
+
+</section>
+
+ <section>
+ <title>The Request / Response Pattern</title>
+ <para>Request / Response applications use the reply-to property,
+ described in <xref
+ linkend="table-amqp0-10-message-properties"/>, to allow a server
+ to respond to the client that sent a message. A server sets up a
+ service queue, with a name known to clients. A client creates a
+ private queue for the server's response, creates a message for a
+ request, sets the request's reply-to property to the address of
+ the client's response queue, and sends the request to the
+ service queue. The server sends the response to the address
+ specified in the request's reply-to property.
+ </para>
+ <example>
+ <title>Request / Response Applications in C++</title>
+
+ <para>This example shows the C++ code for a client and server
+ that use the request / response pattern.</para>
+
+ <para>The server creates a service queue and waits for a
+ message to arrive. If it receives a message, it sends a
+ message back to the sender.</para>
+
+ <programlisting><![CDATA[Receiver receiver = session.createReceiver("service_queue; {create: always}");
+
+Message request = receiver.fetch();
+const Address&amp; address = request.getReplyTo(); // Get "reply-to" from request ...
+if (address) {
+ Sender sender = session.createSender(address); // ... send response to "reply-to"
+ Message response("pong!");
+ sender.send(response);
+ session.acknowledge();
+}
+ ]]></programlisting>
+
+ <para>The client creates a sender for the service queue, and
+ also creates a response queue that is deleted when the
+ client closes the receiver for the response queue. In the C++
+ client, if the address starts with the character
+ <literal>#</literal>, it is given a unique name.</para>
+
+ <programlisting><![CDATA[
+Sender sender = session.createSender("service_queue");
+
+Address responseQueue("#response-queue; {create:always, delete:always}");
+Receiver receiver = session.createReceiver(responseQueue);
+
+Message request;
+request.setReplyTo(responseQueue);
+request.setContent("ping");
+sender.send(request);
+Message response = receiver.fetch();
+std::cout << request.getContent() << " -> " << response.getContent() << std::endl;
+]]> </programlisting>
+
+ <para>The client sends the string <literal>ping</literal> to
+ the server. The server sends the response
+ <literal>pong</literal> back to the same client, using the
+ <varname>replyTo</varname> property.</para>
+
+ </example>
+<!--
+ <example>
+ <title>Request / Response Applications in Python</title>
+ <programlisting>### TODO</programlisting>
+ </example>
+-->
+ </section>
+
+
+ <section>
+ <title>Performance Tips</title>
+
+ <itemizedlist>
+ <listitem>
+ <para>Consider prefetching messages for receivers (see
+ <xref linkend="prefetch"/>). This helps eliminate roundtrips
+ and increases throughput. Prefetch is disabled by default,
+ and enabling it is the most effective means of improving
+ throughput of received messages.</para>
+ </listitem>
+ <listitem>
+ <para>Send messages asynchronously. Again, this helps
+ eliminate roundtrips and increases throughput. The C++ and
+ .NET clients send asynchronously by default, however the
+ python client defaults to synchronous sends. </para>
+ </listitem>
+ <listitem>
+ <para>Acknowledge messages in batches (see
+ <xref linkend="acknowledgements"/>). Rather than
+ acknowledging each message individually, consider issuing
+ acknowledgements after n messages and/or after a particular
+ duration has elapsed.</para>
+ </listitem>
+ <listitem>
+ <para>Tune the sender capacity (see
+ <xref linkend="replay"/>). If the capacity is too low the
+ sender may block waiting for the broker to confirm receipt
+ of messages, before it can free up more capacity.</para>
+ </listitem>
+ <listitem>
+ <para>If you are setting a reply-to address on messages
+ being sent by the c++ client, make sure the address type is
+ set to either queue or topic as appropriate. This avoids the
+ client having to determine which type of node is being
+ refered to, which is required when hanling reply-to in AMQP
+ 0-10. </para>
+ </listitem>
+ <listitem>
+ <para>For latency sensitive applications, setting tcp-nodelay
+ on qpidd and on client connections can help reduce the
+ latency.</para>
+ </listitem>
+ </itemizedlist>
+ </section>
+
+ <section>
+ <title>Cluster Failover</title>
+
+ <para>The messaging broker can be run in clustering mode, which provides high reliability through replicating state between brokers in the cluster. If one broker in a cluster fails, clients can choose another broker in the cluster and continue their work. Each broker in the cluster also advertises the addresses of all known brokers
+
+<footnote><para>This is done via the amq.failover exchange in AMQP 0-10</para></footnote>
+
+. A client can use this information to dynamically keep the list of reconnection urls up to date.</para>
+
+ <para>In C++, the <classname>FailoverUpdates</classname> class provides this functionality:</para>
+
+ <example>
+ <title>Tracking cluster membership</title>
+
+ <para>In C++:</para>
+
+ <programlisting><![CDATA[
+#include <qpid/messaging/FailoverUpdates.h>
+...
+Connection connection("localhost:5672");
+connection.setOption("reconnect", true);
+try {
+ connection.open();
+ std::auto_ptr<FailoverUpdates> updates(new FailoverUpdates(connection));
+]]>
+ </programlisting>
+
+ <para>In python:</para>
+
+ <programlisting><![CDATA[
+import qpid.messaging.util
+...
+connection = Connection("localhost:5672")
+connection.reconnect = True
+try:
+ connection.open()
+ auto_fetch_reconnect_urls(connection)
+]]>
+ </programlisting>
+ <para>
+ In .NET C#:
+ </para>
+
+<programlisting>
+using Org.Apache.Qpid.Messaging;
+...
+connection = new Connection(&#34;localhost:5672&#34;);
+connection.SetOption("reconnect", true);
+try {
+ connection.Open();
+ FailoverUpdates failover = new FailoverUpdates(connection);
+
+</programlisting>
+
+
+ </example>
+ </section>
+
+
+
+<section>
+ <title>Logging</title>
+
+ <para>To simplify debugging, Qpid provides a logging facility
+ that prints out messaging events.</para>
+
+ <section>
+ <title>Logging in C++</title>
+ <para>
+ The Qpidd broker and C++ clients can both use environment variables to enable logging. Linux and Windows systems use the same named environment variables and values.
+ </para>
+ <para>Use QPID_LOG_ENABLE to set the level of logging you are interested in (trace, debug, info, notice, warning, error, or critical):
+ </para>
+
+<screen>
+export QPID_LOG_ENABLE=&#34;warning+&#34;
+</screen>
+ <para>
+ The Qpidd broker and C++ clients use QPID_LOG_OUTPUT to determine where logging output should be sent. This is either a file name or the special values stderr, stdout, or syslog:
+ </para>
+
+<screen>
+export QPID_LOG_TO_FILE=&#34;/tmp/myclient.out&#34;
+</screen>
+
+ <para>
+ From a Windows command prompt, use the following command format to set the environment variables:
+ </para>
+
+<screen>
+set QPID_LOG_ENABLE=warning+
+set QPID_LOG_TO_FILE=D:\tmp\myclient.out
+</screen>
+ </section>
+
+ <section>
+ <title>Logging in Python</title>
+ <para>
+ The Python client library supports logging using the standard Python logging module. The easiest way to do logging is to use the <command>basicConfig()</command>, which reports all warnings and errors:
+ </para>
+
+<programlisting>from logging import basicConfig
+basicConfig()
+</programlisting>
+ <para>
+ Qpidd also provides a convenience method that makes it easy to specify the level of logging desired. For instance, the following code enables logging at the <command>DEBUG</command> level:
+ </para>
+
+<programlisting>from qpid.log import enable, DEBUG
+enable("qpid.messaging.io", DEBUG)
+</programlisting>
+ <para>
+ For more information on Python logging, see <ulink url="http://docs.python.org/lib/node425.html">http://docs.python.org/lib/node425.html</ulink>. For more information on Qpid logging, use <command>$ pydoc qpid.log</command>.
+ </para>
+ </section>
+</section>
+
+
+
+ <section id="section-amqp0-10-mapping">
+ <title>The AMQP 0-10 mapping</title>
+
+ <para>
+ This section describes the AMQP 0-10 mapping for the Qpid
+ Messaging API.
+ </para>
+ <para>
+ The interaction with the broker triggered by creating a sender
+ or receiver depends on what the specified address resolves
+ to. Where the node type is not specified in the address, the
+ client queries the broker to determine whether it refers to a
+ queue or an exchange.
+ </para>
+ <para>
+ When sending to a queue, the queue's name is set as the
+ routing key and the message is transfered to the default (or
+ nameless) exchange. When sending to an exchange, the message
+ is transfered to that exchange and the routing key is set to
+ the message subject if one is specified. A default subject may
+ be specified in the target address. The subject may also be
+ set on each message individually to override the default if
+ required. In each case any specified subject is also added as
+ a qpid.subject entry in the application-headers field of the
+ message-properties.
+ </para>
+ <para>
+ When receiving from a queue, any subject in the source address
+ is currently ignored. The client sends a message-subscribe
+ request for the queue in question. The accept-mode is
+ determined by the reliability option in the link properties;
+ for unreliable links the accept-mode is none, for reliable
+ links it is explicit. The default for a queue is reliable. The
+ acquire-mode is determined by the value of the mode option. If
+ the mode is set to browse the acquire mode is not-acquired,
+ otherwise it is set to pre-acquired. The exclusive and
+ arguments fields in the message-subscribe command can be
+ controlled using the x-subscribe map.
+ </para>
+ <para>
+ When receiving from an exchange, the client creates a
+ subscription queue and binds that to the exchange. The
+ subscription queue's arguments can be specified using the
+ x-declare map within the link properties. The reliability
+ option determines most of the other parameters. If the
+ reliability is set to unreliable then an auto-deleted,
+ exclusive queue is used meaning that if the client or
+ connection fails messages may be lost. For exactly-once the
+ queue is not set to be auto-deleted. The durability of the
+ subscription queue is determined by the durable option in the
+ link properties. The binding process depends on the type of
+ the exchange the source address resolves to.
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ For a topic exchange, if no subject is specified and no
+ x-bindings are defined for the link, the subscription
+ queue is bound using a wildcard matching any routing key
+ (thus satisfying the expectation that any message sent to
+ that address will be received from it). If a subject is
+ specified in the source address however, it is used for
+ the binding key (this means that the subject in the source
+ address may be a binding pattern including wildcards).
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ For a fanout exchange the binding key is irrelevant to
+ matching. A receiver created from a source address that
+ resolves to a fanout exchange receives all messages
+ sent to that exchange regardless of any subject the source
+ address may contain. An x-bindings element in the link
+ properties should be used if there is any need to set the
+ arguments to the bind.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ For a direct exchange, the subject is used as the binding
+ key. If no subject is specified an empty string is used as
+ the binding key.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ For a headers exchange, if no subject is specified the
+ binding arguments simply contain an x-match entry and no
+ other entries, causing all messages to match. If a subject
+ is specified then the binding arguments contain an x-match
+ entry set to all and an entry for qpid.subject whose value
+ is the subject in the source address (this means the
+ subject in the source address must match the message
+ subject exactly). For more control the x-bindings element
+ in the link properties must be used.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ For the XML exchange,<footnote><para>Note that the XML
+ exchange is not a standard AMQP exchange type. It is a
+ Qpid extension and is currently only supported by the C++
+ broker.</para></footnote> if a subject is specified it is
+ used as the binding key and an XQuery is defined that
+ matches any message with that value for
+ qpid.subject. Again this means that only messages whose
+ subject exactly match that specified in the source address
+ are received. If no subject is specified then the empty
+ string is used as the binding key with an xquery that will
+ match any message (this means that only messages with an
+ empty string as the routing key will be received). For more
+ control the x-bindings element in the link properties must
+ be used. A source address that resolves to the XML
+ exchange must contain either a subject or an x-bindings
+ element in the link properties as there is no way at
+ present to receive any message regardless of routing key.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ If an x-bindings list is present in the link options a binding
+ is created for each element within that list. Each element is
+ a nested map that may contain values named queue, exchange,
+ key or arguments. If the queue value is absent the queue name
+ the address resolves to is implied. If the exchange value is
+ absent the exchange name the address resolves to is implied.
+ </para>
+
+ <para>The following table shows how Qpid Messaging API message
+ properties are mapped to AMQP 0-10 message properties and
+ delivery properties. In this table <varname>msg</varname>
+ refers to the Message class defined in the Qpid Messaging API,
+ <varname>mp</varname> refers to an AMQP 0-10
+ <varname>message-properties</varname> struct, and
+ <varname>dp</varname> refers to an AMQP 0-10
+ <varname>delivery-properties</varname> struct.</para>
+
+ <table id="table-amqp0-10-message-properties" pgwide="1">
+ <title>Mapping to AMQP 0-10 Message Properties</title>
+ <tgroup cols="3">
+ <thead>
+ <colspec colnum="1" colname="Python API" colwidth="3*"/>
+ <colspec colnum="2" colname="C++ API" colwidth="3*"/>
+ <colspec colnum="3" colname="AMPQ 0-10 Property" colwidth="6*"/>
+ <row>
+ <entry>Python API</entry>
+ <entry>C++ API
+ <footnote>
+ <para>
+ The .NET Binding for C++ Messaging provides all the
+ message and delivery properties described in the C++ API.
+ See <xref linkend="table-Dotnet-Binding-Message" /> .
+ </para>
+ </footnote>
+ </entry>
+ <entry>AMQP 0-10 Property<footnote><para>In these entries, <literal>mp</literal> refers to an AMQP message property, and <literal>dp</literal> refers to an AMQP delivery property.</para></footnote></entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>msg.id</entry><entry>msg.{get,set}MessageId()</entry><entry>mp.message_id</entry>
+ </row>
+ <row>
+ <entry>msg.subject</entry><entry>msg.{get,set}Subject()</entry><entry>mp.application_headers["qpid.subject"]</entry>
+ </row>
+ <row>
+ <entry>msg.user_id</entry><entry>msg.{get,set}UserId()</entry><entry>mp.user_id</entry>
+ </row>
+ <row>
+ <entry>msg.reply_to</entry><entry>msg.{get,set}ReplyTo()</entry><entry>mp.reply_to<footnote><para>The reply_to is converted from the protocol representation into an address.</para></footnote></entry>
+ </row>
+ <row>
+ <entry>msg.correlation_id</entry><entry>msg.{get,set}CorrelationId()</entry><entry>mp.correlation_id</entry>
+ </row>
+ <row>
+ <entry>msg.durable</entry><entry>msg.{get,set}Durable()</entry><entry>dp.delivery_mode == delivery_mode.persistent<footnote><para>Note that msg.durable is a boolean, not an enum.</para></footnote></entry>
+ </row>
+ <row>
+ <entry>msg.priority</entry><entry>msg.{get,set}Priority()</entry><entry>dp.priority</entry>
+ </row>
+ <row>
+ <entry>msg.ttl</entry><entry>msg.{get,set}Ttl()</entry><entry>dp.ttl</entry>
+ </row>
+ <row>
+ <entry>msg.redelivered</entry><entry>msg.{get,set}Redelivered()</entry><entry>dp.redelivered</entry>
+ </row>
+ <row><entry>msg.properties</entry><entry>msg.{get,set}Properties()</entry><entry>mp.application_headers</entry>
+ </row>
+ <row>
+ <entry>msg.content_type</entry><entry>msg.{get,set}ContentType()</entry><entry>mp.content_type</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>The 0-10 mapping also recognises certain special property
+ keys. If the properties contain entries for <literal>x-amqp-0-10.app-id</literal>
+ or <literal>x-amqp-0-10.content-encoding</literal>, the values will be used to
+ set <literal>message-properties.app-id</literal> and
+ <literal>message-properties.content-encoding</literal> on the
+ resulting 0-10 message transfer. Likewise if an incoming
+ transfer has those properties set, they will be exposed in the
+ same manner. In addition the routing key on incoming transfers
+ will be exposed directly via the custom property with key
+ <literal>x-amqp-0-10.routing-key</literal>.</para>
+
+ </section>
+ </chapter>
+
+
+ <chapter id="QpidJMS">
+ <title>Using the Qpid JMS client</title>
+ <section>
+ <title>A Simple Messaging Program in Java JMS</title>
+
+ <para>The following program shows how to send and receive a
+ message using the Qpid JMS client. JMS programs typically use
+ JNDI to obtain connection factory and destination objects which
+ the application needs. In this way the configuration is kept
+ separate from the application code itself.</para>
+
+ <para>In this example, we create a JNDI context using a
+ properties file, use the context to lookup a connection factory,
+ create and start a connection, create a session, and lookup a
+ destination from the JNDI context. Then we create a producer and
+ a consumer, send a message with the producer and receive it with
+ the consumer. This code should be straightforward for anyone
+ familiar with Java JMS.</para>
+
+ <example>
+ <title>"Hello world!" in Java</title>
+ <programlisting lang="java">
+package org.apache.qpid.example.jmsexample.hello;
+
+import javax.jms.*;
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import java.util.Properties;
+
+public class Hello {
+
+ public Hello() {
+ }
+
+ public static void main(String[] args) {
+ Hello producer = new Hello();
+ producer.runTest();
+ }
+
+ private void runTest() {
+ try {
+ Properties properties = new Properties();
+ properties.load(this.getClass().getResourceAsStream("hello.properties")); <co id="hello-java-properties" linkends="callout-java-properties"/>
+ Context context = new InitialContext(properties); <co id="hello-java-context" linkends="callout-java-context"/>
+
+ ConnectionFactory connectionFactory
+ = (ConnectionFactory) context.lookup("qpidConnectionfactory"); <co id="hello-java-connection-factory" linkends="callout-java-connection-factory"/>
+ Connection connection = connectionFactory.createConnection(); <co id="hello-java-connection" linkends="callout-java-connection"/>
+ connection.start(); <co id="hello-java-start" linkends="callout-java-start"/>
+
+ Session session=connection.createSession(false,Session.AUTO_ACKNOWLEDGE);<co id="hello-java-session" linkends="callout-java-session"/>
+ Destination destination = (Destination) context.lookup("topicExchange"); <co id="hello-java-destination" linkends="callout-java-destination"/>
+
+ MessageProducer messageProducer = session.createProducer(destination); <co id="hello-java-producer" linkends="callout-java-producer"/>
+ MessageConsumer messageConsumer = session.createConsumer(destination); <co id="hello-java-consumer" linkends="callout-java-consumer"/>
+
+ TextMessage message = session.createTextMessage("Hello world!");
+ messageProducer.send(message);
+
+ message = (TextMessage)messageConsumer.receive(); <co id="hello-java-receive" linkends="callout-java-receive"/>
+ System.out.println(message.getText());
+
+ connection.close(); <co id="hello-java-close" linkends="callout-java-close"/>
+ context.close(); <co id="hello-java-jndi-close" linkends="callout-java-jndi-close"/>
+ }
+ catch (Exception exp) {
+ exp.printStackTrace();
+ }
+ }
+}
+ </programlisting>
+ </example>
+
+ <calloutlist>
+ <callout id="callout-java-properties" arearefs="hello-java-properties">
+ <para>Loads the JNDI properties file, which specifies connection properties, queues, topics, and addressing options. See <xref linkend="QpidJNDI"/> for details.</para>
+ </callout>
+ <callout id="callout-java-context" arearefs="hello-java-context">
+ <para>Creates the JNDI initial context.</para>
+ </callout>
+ <callout id="callout-java-connection-factory" arearefs="hello-java-connection-factory">
+ <para>Creates a JMS connection factory for Qpid.</para>
+ </callout>
+ <callout id="callout-java-connection" arearefs="hello-java-connection">
+ <para>Creates a JMS connection.</para>
+ </callout>
+ <callout id="callout-java-start" arearefs="hello-java-start">
+ <para>Activates the connection.</para>
+ </callout>
+ <callout id="callout-java-session" arearefs="hello-java-session">
+ <para>Creates a session. This session is not transactional (transactions='false'), and messages are automatically acknowledged.</para>
+ </callout>
+ <callout id="callout-java-destination" arearefs="hello-java-destination">
+ <para>Creates a destination for the topic exchange, so senders and receivers can use it.</para>
+ </callout>
+ <callout id="callout-java-producer" arearefs="hello-java-producer">
+ <para>Creates a producer that sends messages to the topic exchange.</para>
+ </callout>
+ <callout id="callout-java-consumer" arearefs="hello-java-consumer">
+ <para>Creates a consumer that reads messages from the topic exchange.</para>
+ </callout>
+ <callout id="callout-java-receive" arearefs="hello-java-receive">
+ <para>Reads the next available message.</para>
+ </callout>
+ <callout id="callout-java-close" arearefs="hello-java-close">
+ <para>Closes the connection, all sessions managed by the connection, and all senders and receivers managed by each session.</para>
+ </callout>
+ <callout id="callout-java-jndi-close" arearefs="hello-java-jndi-close">
+ <para>Closes the JNDI context.</para>
+ </callout>
+ </calloutlist>
+
+ <para>The contents of the hello.properties file are shown below.</para>
+
+ <example>
+ <title>JNDI Properties File for "Hello world!" example</title>
+ <programlisting>
+java.naming.factory.initial
+ = org.apache.qpid.jndi.PropertiesFileInitialContextFactory
+
+# connectionfactory.[jndiname] = [ConnectionURL]
+connectionfactory.qpidConnectionfactory
+ = amqp://guest:guest@clientid/test?brokerlist='tcp://localhost:5672' <co id="hello-properties-connectionfactory" linkends="callout-hello-properties-connectionfactory"/>
+# destination.[jndiname] = [address_string]
+destination.topicExchange = amq.topic <co id="hello-properties-destination" linkends="callout-hello-properties-destination"/>
+ </programlisting>
+ </example>
+
+ <calloutlist>
+ <callout id="callout-hello-properties-connectionfactory" arearefs="hello-properties-connectionfactory">
+ <para>Defines a connection factory from which connections
+ can be created. The syntax of a ConnectionURL is given in
+ <xref linkend="QpidJNDI"/>.</para>
+ </callout>
+ <callout id="callout-hello-properties-destination" arearefs="hello-properties-destination">
+ <para>Defines a destination for which MessageProducers
+ and/or MessageConsumers can be created to send and receive
+ messages. The value for the destination in the properties
+ file is an address string as described in
+ <xref linkend="section-addresses"/>. In the JMS
+ implementation MessageProducers are analogous to senders in
+ the Qpid Message API, and MessageConsumers are analogous to
+ receivers.</para>
+ </callout>
+ </calloutlist>
+
+ </section>
+
+ <section id="QpidJNDI">
+ <title>Apache Qpid JNDI Properties for AMQP Messaging</title>
+
+
+ <para>
+ Apache Qpid defines JNDI properties that can be used to specify JMS Connections and Destinations. Here is a typical JNDI properties file:
+ </para>
+
+ <example>
+ <title>JNDI Properties File</title>
+ <programlisting><![CDATA[
+java.naming.factory.initial
+ = org.apache.qpid.jndi.PropertiesFileInitialContextFactory
+
+# connectionfactory.[jndiname] = [ConnectionURL]
+connectionfactory.qpidConnectionfactory
+ = amqp://guest:guest@clientid/test?brokerlist='tcp://localhost:5672'
+# destination.[jndiname] = [address_string]
+destination.topicExchange = amq.topic
+]]></programlisting>
+ </example>
+
+ <para>The following sections describe the JNDI properties that Qpid uses.</para>
+
+
+ <section>
+ <title>JNDI Properties for Apache Qpid</title>
+ <para>
+ Apache Qpid supports the properties shown in the following table:
+ </para>
+ <table>
+ <title>JNDI Properties supported by Apache Qpid</title>
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>
+ Property
+ </entry>
+ <entry>
+ Purpose
+ </entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>
+ connectionfactory.&lt;jndiname&gt;
+ </entry>
+ <entry>
+ <para>
+ The Connection URL that the connection factory uses to perform connections.
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ queue.&lt;jndiname&gt;
+ </entry>
+ <entry>
+ <para>
+ A JMS queue, which is implemented as an amq.direct exchange in Apache Qpid.
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ topic.&lt;jndiname&gt;
+ </entry>
+ <entry>
+ <para>
+ A JMS topic, which is implemented as an amq.topic exchange in Apache Qpid.
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ destination.&lt;jndiname&gt;
+ </entry>
+ <entry>
+ <para>
+ Can be used for defining all amq destinations,
+ queues, topics and header matching, using an
+ address string.
+
+ <footnote><para>Binding URLs, which were used in
+ earlier versions of the Qpid Java JMS client, can
+ still be used instead of address
+ strings.</para></footnote>
+ </para>
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </section>
+
+ <section id="section-jms-connection-url">
+ <title>Connection URLs</title>
+ <para>
+ In JNDI properties, a Connection URL specifies properties for a connection. The format for a Connection URL is:
+ </para>
+
+ <programlisting>amqp://[&lt;user&gt;:&lt;pass&gt;@][&lt;clientid&gt;]&lt;virtualhost&gt;[?&lt;option&gt;=&#39;&lt;value&gt;&#39;[&amp;&lt;option&gt;=&#39;&lt;value&gt;&#39;]]
+ </programlisting>
+ <para>
+ For instance, the following Connection URL specifies a user name, a password, a client ID, a virtual host ("test"), a broker list with a single broker, and a TCP host with the host name <quote>localhost</quote> using port 5672:
+ </para>
+
+ <programlisting>amqp://username:password@clientid/test?brokerlist=&#39;tcp://localhost:5672&#39;
+ </programlisting>
+ <para>
+ Apache Qpid supports the following properties in Connection URLs:
+ </para>
+ <table pgwide="1">
+ <title>Connection URL Properties</title>
+ <tgroup cols="3">
+ <thead>
+ <row>
+ <entry>
+ Option
+ </entry>
+ <entry>
+ Type
+ </entry>
+ <entry>
+ Description
+ </entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>
+ brokerlist
+ </entry>
+ <entry>
+ see below
+ </entry>
+ <entry>
+ The broker to use for this connection. In the current release, precisely one broker must be specified.
+ </entry>
+ </row>
+ <row>
+ <entry>
+ maxprefetch
+ </entry>
+ <entry>
+ --
+ </entry>
+ <entry>
+ The maximum number of pre-fetched messages per destination.
+ </entry>
+ </row>
+ <row>
+ <entry>
+ sync_publish
+ </entry>
+ <entry>
+ {'persistent' | 'all'}
+ </entry>
+ <entry>
+ A sync command is sent after every persistent message to guarantee that it has been received; if the value is 'persistent', this is done only for persistent messages.
+ </entry>
+ </row>
+ <row>
+ <entry>
+ sync_ack
+ </entry>
+ <entry>
+ Boolean
+ </entry>
+ <entry>
+ A sync command is sent after every acknowledgement to guarantee that it has been received.
+ </entry>
+ </row>
+ <row>
+ <entry>
+ use_legacy_map_msg_format
+ </entry>
+ <entry>
+ Boolean
+ </entry>
+ <entry>
+ If you are using JMS Map messages and deploying a new client with any JMS client older than 0.8 release, you must set this to true to ensure the older clients can understand the map message encoding.
+ </entry>
+ </row>
+ <row>
+ <entry>
+ failover
+ </entry>
+ <entry>
+ {'roundrobin' | 'failover_exchange'}
+ </entry>
+ <entry>
+ If roundrobin is selected it will try each broker given in the broker list.
+ If failover_exchange is selected it connects to the initial broker given in the broker URL and will receive membership updates via the failover exchange.
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ <para>
+ Broker lists are specified using a URL in this format:
+ </para>
+
+ <programlisting>brokerlist=&lt;transport&gt;://&lt;host&gt;[:&lt;port&gt;](?&lt;param>=&lt;value>)?(&amp;&lt;param>=&lt;value>)*</programlisting>
+ <para>
+ For instance, this is a typical broker list:
+ </para>
+
+ <programlisting>brokerlist=&#39;tcp://localhost:5672&#39;
+ </programlisting>
+
+ <para>
+ A broker list can contain more than one broker address; if so, the connection is made to the first broker in the list that is available. In general, it is better to use the failover exchange when using multiple brokers, since it allows applications to fail over if a broker goes down.
+ </para>
+
+ <example>
+ <title>Broker Lists</title>
+ <para>A broker list can specify properties to be used when connecting to the broker, such as security options. This broker list specifies options for a Kerberos connection using GSSAPI:</para>
+ <programlisting><![CDATA[
+amqp://guest:guest@test/test?sync_ack='true'
+ &brokerlist='tcp://ip1:5672?sasl_mechs='GSSAPI'
+ ]]></programlisting>
+
+ <para>This broker list specifies SSL options:</para>
+
+ <programlisting><![CDATA[
+amqp://guest:guest@test/test?sync_ack='true'
+ &brokerlist='tcp://ip1:5672?ssl='true'&ssl_cert_alias='cert1'
+ ]]></programlisting>
+ </example>
+
+ <para>The following broker list options are supported.</para>
+
+ <table pgwide="1">
+ <title>Broker List Options</title>
+ <tgroup cols="3">
+ <thead>
+ <row>
+ <entry>
+ Option
+ </entry>
+ <entry>
+ Type
+ </entry>
+ <entry>
+ Description
+ </entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>
+ heartbeat
+ </entry>
+ <entry>
+ integer
+ </entry>
+ <entry>
+ frequency of heartbeat messages (in seconds)
+ </entry>
+ </row>
+ <row>
+ <entry>
+ sasl_mechs
+ </entry>
+ <entry>
+ --
+ </entry>
+ <entry>
+ For secure applications, we suggest CRAM-MD5,
+ DIGEST-MD5, or GSSAPI. The ANONYMOUS method is not
+ secure. The PLAIN method is secure only when used
+ together with SSL. For Kerberos, sasl_mechs must be
+ set to GSSAPI, sasl_protocol must be set to the
+ principal for the qpidd broker, e.g. qpidd/, and
+ sasl_server must be set to the host for the SASL
+ server, e.g. sasl.com. SASL External is supported
+ using SSL certification, e.g.
+ <literal>ssl='true'&amp;sasl_mechs='EXTERNAL'</literal>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ sasl_encryption
+ </entry>
+ <entry>
+ Boolean
+ </entry>
+ <entry>
+ If <literal>sasl_encryption='true'</literal>, the JMS client attempts to negotiate a security layer with the broker using GSSAPI to encrypt the connection. Note that for this to happen, GSSAPI must be selected as the sasl_mech.
+ </entry>
+ </row>
+ <row>
+ <entry>
+ ssl
+ </entry>
+ <entry>
+ Boolean
+ </entry>
+ <entry>
+ If <literal>ssl='true'</literal>, the JMS client will encrypt the connection using SSL.
+ </entry>
+ </row>
+ <row>
+ <entry>
+ tcp_nodelay
+ </entry>
+ <entry>
+ Boolean
+ </entry>
+ <entry>
+ If <literal>tcp_nodelay='true'</literal>, TCP packet
+ batching is disabled.
+ </entry>
+ </row>
+ <row>
+ <entry>
+ sasl_protocol
+ </entry>
+ <entry>
+ --
+ </entry>
+ <entry>
+ Used only for
+ Kerberos. <literal>sasl_protocol</literal> must be
+ set to the principal for the qpidd broker,
+ e.g. <literal>qpidd/</literal>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ sasl_server
+ </entry>
+ <entry>
+ --
+ </entry>
+ <entry>
+ For Kerberos, sasl_mechs must be set to GSSAPI,
+ sasl_server must be set to the host for the SASL
+ server, e.g. <literal>sasl.com</literal>.
+ </entry>
+ </row>
+ <row>
+ <entry>
+ trust_store
+ </entry>
+ <entry>
+ --
+ </entry>
+ <entry>
+ path to Keberos trust store
+ </entry>
+ </row>
+ <row>
+ <entry>
+ trust_store_password
+ </entry>
+ <entry>
+ </entry>
+ <entry>
+ Kerberos trust store password
+ </entry>
+ </row>
+ <row>
+ <entry>
+ key_store
+ </entry>
+ <entry>
+ </entry>
+ <entry>
+ path to Kerberos key store
+ </entry>
+ </row>
+ <row>
+ <entry>
+ key_store_password
+ </entry>
+ <entry>
+ --
+ </entry>
+ <entry>
+ Kerberos key store password
+ </entry>
+ </row>
+ <row>
+ <entry>
+ ssl_verify_hostname
+ </entry>
+ <entry>
+ Boolean
+ </entry>
+ <entry>
+ When using SSL you can enable hostname verification
+ by using "ssl_verify_hostname=true" in the broker
+ URL.
+ </entry>
+ </row>
+ <row>
+ <entry>
+ ssl_cert_alias
+ </entry>
+ <entry>
+
+ </entry>
+ <entry>
+ If multiple certificates are present in the keystore, the alias will be used to extract the correct certificate.
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </section>
+ </section>
+
+ <section>
+ <title>Java JMS Message Properties</title>
+
+ <para>The following table shows how Qpid Messaging API message
+ properties are mapped to AMQP 0-10 message properties and
+ delivery properties. In this table <varname>msg</varname>
+ refers to the Message class defined in the Qpid Messaging API,
+ <varname>mp</varname> refers to an AMQP 0-10
+ <varname>message-properties</varname> struct, and
+ <varname>dp</varname> refers to an AMQP 0-10
+ <varname>delivery-properties</varname> struct.</para>
+
+ <table >
+ <title>Java JMS Mapping to AMQP 0-10 Message Properties</title>
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Java JMS Message Property</entry>
+ <entry>AMQP 0-10 Property<footnote><para>In these entries, <literal>mp</literal> refers to an AMQP message property, and <literal>dp</literal> refers to an AMQP delivery property.</para></footnote></entry>
+
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>JMSMessageID</entry><entry>mp.message_id</entry>
+ </row>
+ <row>
+ <entry>qpid.subject<footnote><para>This is a custom JMS property, set automatically by the Java JMS client implementation.</para></footnote></entry><entry>mp.application_headers["qpid.subject"]</entry>
+ </row>
+ <row>
+ <entry>JMSXUserID</entry><entry>mp.user_id</entry>
+ </row>
+ <row>
+ <entry>JMSReplyTo</entry><entry>mp.reply_to<footnote><para>The reply_to is converted from the protocol representation into an address.</para></footnote></entry>
+ </row>
+ <row>
+ <entry>JMSCorrelationID</entry><entry>mp.correlation_id</entry>
+ </row>
+ <row>
+ <entry>JMSDeliveryMode</entry><entry>dp.delivery_mode</entry>
+ </row>
+ <row>
+ <entry>JMSPriority</entry><entry>dp.priority</entry>
+ </row>
+ <row>
+ <entry>JMSExpiration</entry><entry>dp.ttl<footnote><para>JMSExpiration = dp.ttl + currentTime</para></footnote></entry>
+ </row>
+ <row>
+ <entry>JMSRedelivered</entry><entry>dp.redelivered</entry>
+ </row>
+ <row>
+ <entry>JMS Properties</entry><entry>mp.application_headers</entry>
+ </row>
+ <row>
+ <entry>JMSType</entry><entry>mp.content_type</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </section>
+
+ <section id="section-JMS-MapMessage">
+ <title>JMS MapMessage Types</title>
+
+ <para>Qpid supports the Java JMS <classname>MapMessage</classname> interface, which provides support for maps in messages. The following code shows how to send a <classname>MapMessage</classname> in Java JMS.</para>
+
+ <example>
+ <title>Sending a Java JMS MapMessage</title>
+ <programlisting><![CDATA[
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.jms.Connection;
+import javax.jms.Destination;
+import javax.jms.MapMessage;
+import javax.jms.MessageProducer;
+import javax.jms.Session;
+
+import org.apache.qpid.client.AMQAnyDestination;
+import org.apache.qpid.client.AMQConnection;
+
+import edu.emory.mathcs.backport.java.util.Arrays;
+
+// !!! SNIP !!!
+
+MessageProducer producer = session.createProducer(queue);
+
+MapMessage m = session.createMapMessage();
+m.setIntProperty("Id", 987654321);
+m.setStringProperty("name", "Widget");
+m.setDoubleProperty("price", 0.99);
+
+List<String> colors = new ArrayList<String>();
+colors.add("red");
+colors.add("green");
+colors.add("white");
+m.setObject("colours", colors);
+
+Map<String,Double> dimensions = new HashMap<String,Double>();
+dimensions.put("length",10.2);
+dimensions.put("width",5.1);
+dimensions.put("depth",2.0);
+m.setObject("dimensions",dimensions);
+
+List<List<Integer>> parts = new ArrayList<List<Integer>>();
+parts.add(Arrays.asList(new Integer[] {1,2,5}));
+parts.add(Arrays.asList(new Integer[] {8,2,5}));
+m.setObject("parts", parts);
+
+Map<String,Object> specs = new HashMap<String,Object>();
+specs.put("colours", colors);
+specs.put("dimensions", dimensions);
+specs.put("parts", parts);
+m.setObject("specs",specs);
+
+producer.send(m);
+ ]]></programlisting>
+ </example>
+
+ <para>The following table shows the datatypes that can be sent in a <classname>MapMessage</classname>, and the corresponding datatypes that will be received by clients in Python or C++.</para>
+
+ <table id="table-Java-Maps">
+ <title>Java Datatypes in Maps</title>
+ <tgroup cols="3">
+ <thead>
+ <row>
+ <entry>Java Datatype</entry>
+ <entry>&rarr; Python</entry>
+ <entry>&rarr; C++</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row><entry>boolean</entry><entry>bool</entry><entry>bool</entry></row>
+ <row><entry>short</entry><entry>int | long</entry><entry>int16</entry></row>
+ <row><entry>int</entry><entry>int | long</entry><entry>int32</entry></row>
+ <row><entry>long</entry><entry>int | long</entry><entry>int64</entry></row>
+ <row><entry>float</entry><entry>float</entry><entry>float</entry></row>
+ <row><entry>double</entry><entry>float</entry><entry>double</entry></row>
+ <row><entry>java.lang.String</entry><entry>unicode</entry><entry>std::string</entry></row>
+ <row><entry>java.util.UUID</entry><entry>uuid</entry><entry>qpid::types::Uuid</entry></row>
+ <row><entry>java.util.Map<footnote><para>In Qpid, maps can nest. This goes beyond the functionality required by the JMS specification.</para></footnote></entry><entry>dict</entry><entry>Variant::Map</entry></row>
+ <row><entry>java.util.List</entry><entry>list</entry><entry>Variant::List</entry></row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </section>
+
+ <section id="section-JMS-Logging">
+ <title>JMS Client Logging</title>
+ <para>The JMS Client logging is handled using the Simple Logging Facade for Java (<ulink url="http://www.slf4j.org/">SLF4J</ulink>). As the name implies, slf4j is a facade that delegates to other logging systems like log4j or JDK 1.4 logging. For more information on how to configure slf4j for specific logging systems, please consult the slf4j documentation.</para>
+
+ <para>When using the log4j binding, please set the log level for org.apache.qpid explicitly. Otherwise log4j will default to DEBUG which will degrade performance considerably due to excessive logging. The recommended logging level for production is <literal>WARN</literal>.</para>
+
+ <para>The following example shows the logging properties used to configure client logging for slf4j using the log4j binding. These properties can be placed in a log4j.properties file and placed in the <varname>CLASSPATH</varname>, or they can be set explicitly using the <literal>-Dlog4j.configuration</literal> property.</para>
+
+ <example>
+ <title>log4j Logging Properties</title>
+
+ <programlisting><![CDATA[
+log4j.logger.org.apache.qpid=WARN, console
+log4j.additivity.org.apache.qpid=false
+
+log4j.appender.console=org.apache.log4j.ConsoleAppender
+log4j.appender.console.Threshold=all
+log4j.appender.console.layout=org.apache.log4j.PatternLayout
+log4j.appender.console.layout.ConversionPattern=%t %d %p [%c{4}] %m%n
+]]></programlisting>
+ </example>
+
+ </section>
+
+ <section>
+ <title>Configuring the JMS Client</title>
+
+ <para>The Qpid JMS Client allows several configuration options to customize it's behaviour at different levels of granualarity.</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ JVM level using JVM arguments : Configuration that affects all connections, sessions, consumers and producers created within that JVM.
+ </para>
+ <para>Ex. <varname>-Dmax_prefetch=1000</varname> property specifies the message credits to use.</para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Connection level using Connection/Broker properties : Affects the respective connection and sessions, consumers and produces created by that connection.
+ </para>
+ <para>Ex. <varname>amqp://guest:guest@test/test?max_prefetch='1000'
+ &amp;brokerlist='tcp://localhost:5672'
+</varname> property specifies the message credits to use. This overrides any value specified via the JVM argument <varname>max_prefetch</varname>.</para>
+ <para>Please refer to the <xref linkend="section-jms-connection-url"/> section for a complete list of all properties and how to use them.</para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Destination level using Addressing options : Affects the producer(s) and consumer(s) created using the respective destination.
+ </para>
+ <para>Ex. <varname>my-queue; {create: always, link:{capacity: 10}}</varname>, where <varname>capacity</varname> option specifies the message credits to use. This overrides any connection level configuration.</para>
+ <para>Please refer to the <xref linkend="section-addresses"/> section for a complete understanding of addressing and it's various options.</para>
+ </listitem>
+ </itemizedlist>
+
+<para>Some of these config options are available at all three levels (Ex. <varname>max_prefetch</varname>), while others are available only at JVM or connection level.</para>
+
+ <section>
+ <title>Qpid JVM Arguments</title>
+
+ <table >
+ <title>Config Options For Connection Behaviour</title>
+ <tgroup cols="4">
+ <thead>
+ <row>
+ <entry>Property Name</entry>
+ <entry>Type</entry>
+ <entry>Default Value</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>qpid.amqp.version</entry>
+ <entry>string</entry>
+ <entry>0-10</entry>
+ <entry>Sets the AMQP version to be used - currently supports one of {0-8,0-9,0-91,0-10}</entry>
+ </row>
+
+ <row>
+ <entry>qpid.heartbeat</entry>
+ <entry>int</entry>
+ <entry>120 (secs)</entry>
+ <entry>The heartbeat interval in seconds. Two consective misssed heartbeats will result in the connection timing out.<para>This could also be set per connection as well (see connection paramters).</para></entry>
+ </row>
+
+ <row>
+ <entry>ignore_setclientID</entry>
+ <entry>boolean</entry>
+ <entry>false</entry>
+ <entry>If a client ID is specified in the connection URL it's used or else an ID is generated. If an ID is specified after it's been set Qpid will throw an exception. <para>Setting this property to 'true' will disable that check and allow you to set a client ID of your choice later on.</para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+
+ <table >
+ <title>Config Options For Session Behaviour</title>
+ <tgroup cols="4">
+ <thead>
+ <row>
+ <entry>Property Name</entry>
+ <entry>Type</entry>
+ <entry>Default Value</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>qpid.session.command_limit</entry>
+ <entry>int</entry>
+ <entry>65536</entry>
+ <entry>Limits the # of unacked commands</entry>
+ </row>
+
+ <row>
+ <entry>qpid.session.byte_limit</entry>
+ <entry>int</entry>
+ <entry>1048576</entry>
+ <entry>Limits the # of unacked commands in terms of bytes</entry>
+ </row>
+
+ <row>
+ <entry>qpid.use_legacy_map_message</entry>
+ <entry>boolean</entry>
+ <entry>false</entry>
+ <entry><para>If set will use the old map message encoding. By default the Map messages are encoded using the 0-10 map encoding.</para><para>This could also be set per connection as well (see connection paramters).</para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table >
+ <title>Config Options For Consumer Behaviour</title>
+ <tgroup cols="4">
+ <thead>
+ <row>
+ <entry>Property Name</entry>
+ <entry>Type</entry>
+ <entry>Default Value</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>max_prefetch</entry>
+ <entry>int</entry>
+ <entry>500</entry>
+ <entry>Maximum number of messages to credits. <para>This could also be set per connection (see connection paramters) or per destination (see the <varname>capacity</varname> option under link properties in addressing).</para></entry>
+ </row>
+
+ <row>
+ <entry>qpid.session.max_ack_delay</entry>
+ <entry>long</entry>
+ <entry>1000 (ms)</entry>
+ <entry><para>Timer interval to flush message acks in buffer when using AUTO_ACK and DUPS_OK.</para> <para>When using the above ack modes, message acks are batched and sent if one of the following conditions are met (which ever happens first).
+ <itemizedlist>
+ <listitem><para>When the ack timer fires.</para></listitem>
+ <listitem><para>if un_acked_msg_count > max_prefetch/2.</para></listitem>
+ </itemizedlist>
+ </para>
+ <para>The ack timer can be disabled by setting it to 0.</para>
+ </entry>
+ </row>
+
+ <row>
+ <entry>sync_ack</entry>
+ <entry>boolean</entry>
+ <entry>false</entry>
+ <entry><para>If set, each message will be acknowledged synchronously. When using AUTO_ACK mode, you need to set this to "true", in order to get the correct behaviour as described by the JMS spec.</para><para>This is set to false by default for performance reasons, therefore by default AUTO_ACK behaves similar to DUPS_OK.</para><para>This could also be set per connection as well (see connection paramters).</para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table >
+ <title>Config Options For Producer Behaviour</title>
+ <tgroup cols="4">
+ <thead>
+ <row>
+ <entry>Property Name</entry>
+ <entry>Type</entry>
+ <entry>Default Value</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>sync_publish</entry>
+ <entry>string</entry>
+ <entry>"" (disabled)</entry>
+ <entry><para>If one of {persistent|all} is set then persistent messages or all messages will be sent synchronously.</para><para>This could also be set per connection as well (see connection paramters).</para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table >
+ <title>Config Options For Threading</title>
+ <tgroup cols="4">
+ <thead>
+ <row>
+ <entry>Property Name</entry>
+ <entry>Type</entry>
+ <entry>Default Value</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>qpid.thread_factory</entry>
+ <entry>string</entry>
+ <entry>org.apache.qpid.thread.DefaultThreadFactory</entry>
+ <entry><para>Specifies the thread factory to use.</para><para>If using a real time JVM, you need to set the above property to <varname>org.apache.qpid.thread.RealtimeThreadFactory</varname>.</para></entry>
+ </row>
+
+ <row>
+ <entry>qpid.rt_thread_priority</entry>
+ <entry>int</entry>
+ <entry>20</entry>
+ <entry><para>Specifies the priority (1-99) for Real time threads created by the real time thread factory.</para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table >
+ <title>Config Options For I/O</title>
+ <tgroup cols="4">
+ <thead>
+ <row>
+ <entry>Property Name</entry>
+ <entry>Type</entry>
+ <entry>Default Value</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>qpid.transport</entry>
+ <entry>string</entry>
+ <entry>org.apache.qpid.transport.network.io.IoNetworkTransport</entry>
+ <entry><para>The transport implementation to be used.</para><para>A user could specify an alternative transport mechanism that implements the <varname>org.apache.qpid.transport.network.NetworkTransport</varname> interface.</para></entry>
+ </row>
+
+ <row>
+ <entry>amqj.tcp_nodelay</entry>
+ <entry>boolean</entry>
+ <entry>false</entry>
+ <entry><para>Sets the TCP_NODELAY property of the underlying socket.</para><para>This could also be set per connection as well (see connection paramters).</para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table >
+ <title>Config Options For Security</title>
+ <tgroup cols="4">
+ <thead>
+ <row>
+ <entry>Property Name</entry>
+ <entry>Type</entry>
+ <entry>Default Value</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>qpid.sasl_mechs</entry>
+ <entry>string</entry>
+ <entry>PLAIN</entry>
+ <entry><para>The SASL mechanism to be used. More than one could be specified as a comma separated list.</para><para>We currently support the following mechanisms {PLAIN | GSSAPI | EXTERNAL}.</para><para>This could also be set per connection as well (see connection paramters).</para></entry>
+ </row>
+
+ <row>
+ <entry>qpid.sasl_protocol</entry>
+ <entry>string</entry>
+ <entry>AMQP</entry>
+ <entry><para>When using GSSAPI as the SASL mechanism, <varname>sasl_protocol</varname> must be set to the principal for the qpidd broker, e.g. <varname>qpidd</varname>.</para><para>This could also be set per connection as well (see connection paramters).</para></entry>
+ </row>
+
+ <row>
+ <entry>qpid.sasl_server_name</entry>
+ <entry>string</entry>
+ <entry>localhost</entry>
+ <entry><para>When using GSSAPI as the SASL mechanism, <varname>sasl_server</varname> must be set to the host for the SASL server, e.g. <varname>example.com</varname>.</para><para>This could also be set per connection as well (see connection paramters).</para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table>
+ <title>Config Options For Security - Standard JVM properties needed when using GSSAPI as the SASL mechanism.<footnote><para>Please refer to the Java security documentation for a complete understanding of the above properties.</para></footnote></title>
+ <tgroup cols="4">
+ <thead>
+ <row>
+ <entry>Property Name</entry>
+ <entry>Type</entry>
+ <entry>Default Value</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>javax.security.auth.useSubjectCredsOnly</entry>
+ <entry>boolean</entry>
+ <entry>true</entry>
+ <entry><para>If set to 'false', forces the SASL GASSPI client to obtain the kerberos credentials explicitly instead of obtaining from the "subject" that owns the current thread.</para></entry>
+ </row>
+
+ <row>
+ <entry>java.security.auth.login.config</entry>
+ <entry>string</entry>
+ <entry></entry>
+ <entry><para>Specifies the jass configuration file.</para><para><varname>Ex-Djava.security.auth.login.config=myjas.conf</varname>
+</para><para>Here is the sample myjas.conf JASS configuration file: <programlisting><![CDATA[
+
+ com.sun.security.jgss.initiate {
+ com.sun.security.auth.module.Krb5LoginModule required useTicketCache=true;
+ };
+
+]]></programlisting></para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table>
+ <title>Config Options For Security - Using SSL for securing connections or using EXTERNAL as the SASL mechanism.</title>
+ <tgroup cols="4">
+ <thead>
+ <row>
+ <entry>Property Name</entry>
+ <entry>Type</entry>
+ <entry>Default Value</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>qpid.ssl_timeout</entry>
+ <entry>long</entry>
+ <entry>60000</entry>
+ <entry><para>Timeout value used by the Java SSL engine when waiting on operations.</para></entry>
+ </row>
+
+ <row>
+ <entry>qpid.ssl.keyStoreCertType</entry>
+ <entry>string</entry>
+ <entry>SunX509</entry>
+ <entry><para>The certificate type.</para><para>This could also be set per connection as well (see connection paramters).</para></entry>
+ </row>
+
+ <row>
+ <entry>qpid.ssl.trustStoreCertType</entry>
+ <entry>string</entry>
+ <entry>SunX509</entry>
+ <entry><para>The certificate type.</para><para>This could also be set per connection as well (see connection paramters).</para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table>
+ <title>Config Options For Security - Standard JVM properties needed when Using SSL for securing connections or using EXTERNAL as the SASL mechanism.<footnote><para>Qpid allows you to have per connection key and trust stores if required. If specified per connection, the JVM arguments are ignored.</para></footnote></title>
+ <tgroup cols="4">
+ <thead>
+ <row>
+ <entry>Property Name</entry>
+ <entry>Type</entry>
+ <entry>Default Value</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>javax.net.ssl.keyStore</entry>
+ <entry>string</entry>
+ <entry>jvm default</entry>
+ <entry><para>Specifies the key store path.</para><para>This could also be set per connection as well (see connection paramters).</para></entry>
+ </row>
+
+ <row>
+ <entry>javax.net.ssl.keyStorePassword</entry>
+ <entry>string</entry>
+ <entry>jvm default</entry>
+ <entry><para>Specifies the key store password.</para><para>This could also be set per connection as well (see connection paramters).</para></entry>
+ </row>
+
+ <row>
+ <entry>javax.net.ssl.trustStore</entry>
+ <entry>string</entry>
+ <entry>jvm default</entry>
+ <entry><para>Specifies the trust store path.</para><para>This could also be set per connection as well (see connection paramters).</para></entry>
+ </row>
+
+ <row>
+ <entry>javax.net.ssl.trustStorePassword</entry>
+ <entry>string</entry>
+ <entry>jvm default</entry>
+ <entry><para>Specifies the trust store password.</para><para>This could also be set per connection as well (see connection paramters).</para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </section>
+ </section>
+
+ </chapter>
+
+ <chapter id="QpidWCF">
+ <title>Using the Qpid WCF client</title>
+ <section>
+ <title>XML and Binary Bindings</title>
+
+ <para>The Qpid WCF client provides two bindings, each with support for
+ Windows .NET transactions.</para>
+
+ <para>The AmqpBinding is suitable for communication between two WCF
+ applications. By default it uses the WCF binary .NET XML encoder
+ (BinaryMessageEncodingBindingElement) for efficient message
+ transmission, but it can also use the text and Message Transmission
+ Optimization Mechanism (MTOM) encoders. Here is a traditional service
+ model sample program using the AmqpBinding. It assumes that the queue
+ "hello_service_node" has been created and configured on the AMQP
+ broker.</para>
+
+ <example><?dbfo keep-together="auto" ?>
+ <title>Traditional service model "Hello world!" example</title>
+ <programlisting><![CDATA[
+namespace Apache.Qpid.Documentation.HelloService
+{
+ using System;
+ using System.ServiceModel;
+ using System.ServiceModel.Channels;
+ using System.Threading;
+ using Apache.Qpid.Channel;
+
+ [ServiceContract]
+ public interface IHelloService
+ {
+ [OperationContract(IsOneWay = true, Action = "*")]
+ void SayHello(string greeting);
+ }
+
+ public class HelloService : IHelloService
+ {
+ private static int greetingCount;
+
+ public static int GreetingCount
+ {
+ get { return greetingCount; }
+ }
+
+ public void SayHello(string greeting)
+ {
+ Console.WriteLine("Service received: " + greeting);
+ greetingCount++;
+ }]]></programlisting>
+
+ <programlisting><![CDATA[
+ static void Main(string[] args)
+ {
+ try
+ {
+ AmqpBinding amqpBinding = new AmqpBinding();
+ amqpBinding.BrokerHost = "localhost";
+ amqpBinding.BrokerPort = 5672;
+
+ ServiceHost serviceHost = new ServiceHost(typeof(HelloService));
+ serviceHost.AddServiceEndpoint(typeof(IHelloService),
+ amqpBinding, "amqp:hello_service_node");
+ serviceHost.Open();
+
+ // Send the service a test greeting
+ Uri amqpClientUri=new Uri("amqp:amq.direct?routingkey=hello_service_node");
+ EndpointAddress clientEndpoint = new EndpointAddress(amqpClientUri);
+ ChannelFactory<IHelloService> channelFactory =
+ new ChannelFactory<IHelloService>(amqpBinding, clientEndpoint);
+ IHelloService clientProxy = channelFactory.CreateChannel();
+
+ clientProxy.SayHello("Greetings from WCF client");
+
+ // wait for service to process the greeting
+ while (HelloService.GreetingCount == 0)
+ {
+ Thread.Sleep(100);
+ }
+ channelFactory.Close();
+ serviceHost.Close();
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine("Exception: {0}", e);
+ }
+ }
+ }
+}
+ ]]></programlisting>
+ </example>
+
+ <para>The second binding, AmqpBinaryBinding, is suitable for WCF
+ applications that need to inter-operate with non-WCF clients or that
+ wish to have direct access to the raw wire representation of the
+ message body. It relies on a custom encoder to read and write raw
+ (binary) content which operates similarly to the ByteStream encoder
+ (introduced in .NET 4.0). The encoder presents an abstract XML
+ infoset view of the raw message content on input. On output, the
+ encoder does the reverse and peels away the XML infoset layer exposing
+ the raw content to the wire representation of the message body. The
+ application must do the inverse of what the encoder does to allow the
+ XML infoset wrapper to cancel properly. This is demonstrated in the
+ following sample code (using the channel programming model) which
+ directly manipulates or provides callbacks to the WCF message readers
+ and writers when the content is consumed. In contrast to the
+ AmqpBinding sample where the simple greeting is encapsulated in a
+ compressed SOAP envelope, the wire representation of the message
+ contains the raw content and is identical and fully interoperable with
+ the Qpid C++ "Hello world!" example.</para>
+
+ <example><?dbfo keep-together="auto" ?>
+ <title>Binary "Hello world!" example using the channel model</title>
+ <programlisting><![CDATA[
+namespace Apache.Qpid.Samples.Channel.HelloWorld
+{
+ using System;
+ using System.ServiceModel;
+ using System.ServiceModel.Channels;
+ using System.ServiceModel.Description;
+ using System.Text;
+ using System.Xml;
+ using Apache.Qpid.Channel;
+
+ public class HelloWorld
+ {
+ static void Main(string[] args)
+ {
+ String broker = "localhost";
+ int port = 5672;
+ String target = "amq.topic";
+ String source = "my_topic_node";
+
+ if (args.Length > 0)
+ {
+ broker = args[0];
+ }
+
+ if (args.Length > 1)
+ {
+ port = int.Parse(args[1]);
+ }
+
+ if (args.Length > 2)
+ {
+ target = args[2];
+ }
+
+ if (args.Length > 3)
+ {
+ source = args[3];
+ }
+
+ AmqpBinaryBinding binding = new AmqpBinaryBinding();
+ binding.BrokerHost = broker;
+ binding.BrokerPort = port;
+
+ IChannelFactory<IInputChannel> receiverFactory = binding.BuildChannelFactory<IInputChannel>();
+ receiverFactory.Open();
+ IInputChannel receiver = receiverFactory.CreateChannel(new EndpointAddress("amqp:" + source));
+ receiver.Open();
+
+ IChannelFactory<IOutputChannel> senderFactory = binding.BuildChannelFactory<IOutputChannel>();
+ senderFactory.Open();
+ IOutputChannel sender = senderFactory.CreateChannel(new EndpointAddress("amqp:" + target));
+ sender.Open();
+
+ sender.Send(Message.CreateMessage(MessageVersion.None, "", new HelloWorldBinaryBodyWriter()));
+
+ Message message = receiver.Receive();
+ XmlDictionaryReader reader = message.GetReaderAtBodyContents();
+ while (!reader.HasValue)
+ {
+ reader.Read();
+ }
+
+ byte[] binaryContent = reader.ReadContentAsBase64();
+ string text = Encoding.UTF8.GetString(binaryContent);
+
+ Console.WriteLine(text);
+
+ senderFactory.Close();
+ receiverFactory.Close();
+ }
+ }
+
+ public class HelloWorldBinaryBodyWriter : BodyWriter
+ {
+ public HelloWorldBinaryBodyWriter() : base (true) {}
+
+ protected override void OnWriteBodyContents(XmlDictionaryWriter writer)
+ {
+ byte[] binaryContent = Encoding.UTF8.GetBytes("Hello world!");
+
+ // wrap the content:
+ writer.WriteStartElement("Binary");
+ writer.WriteBase64(binaryContent, 0, binaryContent.Length);
+ }
+ }
+}
+]]></programlisting>
+ </example>
+
+ <para>Bindings define ChannelFactories and ChannelListeners associated with
+ an AMQP Broker. WCF will frequently automatically create and manage
+ the life cycle of a these and the resulting IChannel objects used in
+ message transfer. The binding parameters that can be set are:</para>
+
+ <table pgwide="1">
+ <title>WCF Binding Parameters</title>
+ <tgroup cols="3">
+ <thead>
+ <colspec colnum="1" colwidth="1*"/>
+ <colspec colnum="2" colwidth="3*"/>
+ <colspec colnum="3" colwidth="3*"/>
+ <row>
+ <entry>Parameter</entry>
+ <entry>Default</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>
+ BrokerHost
+ </entry>
+ <entry>
+ localhost
+ </entry>
+ <entry>
+ The broker's server name. Currently the WCF channel
+ only supports connections with a single broker.
+ Failover to multiple brokers will be provided in the
+ future.
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ BrokerPort
+ </entry>
+ <entry>
+ 5672
+ </entry>
+ <entry>
+ The port the broker is listening on.
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ PrefetchLimit
+ </entry>
+ <entry>
+ 0
+ </entry>
+ <entry>
+ The number of messages to prefetch from the amqp
+ broker before the application actually consumes them.
+ Increasing this number can dramatically increase the
+ read performance in some circumstances.
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ Shared
+ </entry>
+ <entry>
+ false
+ </entry>
+ <entry>
+ Indicates if separate channels to the same broker can
+ share an underlying AMQP tcp connection (provided they
+ also share the same authentication credentials).
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ TransferMode
+ </entry>
+ <entry>
+ buffered
+ </entry>
+ <entry>
+ Indicates whether the channel's encoder uses the WCF
+ BufferManager cache to temporarily store message
+ content during the encoding/decoding phase. For small
+ to medium sized SOAP based messages, buffered is
+ usually the preferred choice. For binary messages,
+ streamed TransferMode is the more efficient mode.
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </section>
+
+ <section>
+ <title>Endpoints</title>
+
+ <para>In Qpid 0.6 the WCF Endpoints map to simple AMQP 0-10
+ exchanges (IOutputChannel) or AMQP 0-10 queues (IInputChannel).
+ The format for an IOutputChannel is</para>
+
+ <programlisting><![CDATA[
+ "amqp:amq.direct" or "amqp:my_exchange?routingkey=my_routing_key"
+]]></programlisting>
+
+ <para>and for an IInputChannel is</para>
+
+ <programlisting><![CDATA[
+ "amqp:my_queue"
+]]></programlisting>
+
+ <para>The routing key is in fact a default value associated with
+ the particular channel. Outgoing messages can always have their
+ routing key uniquely set.</para>
+
+ <para>If the respective queue or exchange doesn't exist, an exception
+ is thrown when opening the channel. Queues and exchanges can be
+ created and configured using qpid-config.</para>
+
+ </section>
+
+ <section>
+ <title>Message Headers</title>
+
+ <para>AMQP specific message headers can be set on or retrieved
+ from the ServiceModel.Channels.Message using the AmqpProperties
+ type.</para>
+
+ <para>For example, on output:</para>
+
+ <programlisting><![CDATA[
+AmqpProperties props = new AmqpProperties();
+props.Durable = true;
+props.PropertyMap.Add("my_custom_header", new AmqpString("a custom value"));
+Message msg = Message.CreateMessage(args);
+msg.Properties.Add("AmqpProperties", amqpProperties);
+outputChannel.Send(msg);
+]]></programlisting>
+
+ <para>On input the headers can be accessed from the Message or extracted
+ from the operation context</para>
+
+ <programlisting><![CDATA[
+public void SayHello(string greeting)
+{
+ AmqpProperties props = (AmqpProperties) OperationContext.
+ Current.IncomingMessageProperties["AmqpProperties"];
+ AmqpString extra = (AmqpString) props.PropertyMap["my_custom_header"];
+ Console.WriteLine("Service received: {0} and {1}", greeting, extra);
+}
+]]></programlisting>
+
+ </section>
+
+ <section>
+ <title>Security</title>
+
+ <para>To engage TLS/SSL:</para>
+
+ <programlisting><![CDATA[
+binding.Security.Mode = AmqpSecurityMode.Transport;
+binding.Security.Transport.UseSSL = true;
+binding.BrokerPort = 5671;
+]]></programlisting>
+
+ <para>Currently the WCF client only provides SASL PLAIN (i.e. username and
+ password) authentication. To provide a username and password, you can
+ set the DefaultAmqpCredential value in the binding. This value can be
+ overridden or set for a binding's channel factories and listeners,
+ either by setting the ClientCredentials as a binding parameter, or by
+ using an AmqpCredential as a binding parameter. The search order for
+ credentials is the AmqpCredential binding parameter, followed by the
+ ClientCredentials (unless IgnoreEndpointClientCredentials has been
+ set), and finally defaulting to the DefaultAmqpCredential of the
+ binding itself. Here is a sample using ClientCredentials:</para>
+
+ <programlisting><![CDATA[
+ClientCredentials credentials = new ClientCredentials();
+credentials.UserName.UserName = "guest";
+credentials.UserName.Password = "guest";
+bindingParameters = new BindingParameterCollection();
+bindingParameters.Add(credentials);
+readerFactory = binding.BuildChannelFactory<IInputChannel>(bindingParameters);
+]]></programlisting>
+
+ </section>
+
+ <section>
+ <title>Transactions</title>
+
+ <para>The WCF channel provides a transaction resource manager
+ module and a recovery module that together provide distributed
+ transaction support with one-phase optimization. Some
+ configuration is required on Windows machines to enable
+ transaction support (see your installation notes or top level
+ ReadMe.txt file for instructions). Once properly configured,
+ the Qpid WCF channel acts as any other System.Transactions aware
+ resource, capable of participating in explicit or implicit
+ transactions.</para>
+
+ <para>Server code:</para>
+
+ <programlisting><![CDATA[
+[OperationBehavior(TransactionScopeRequired = true,
+ TransactionAutoComplete = true)]
+
+public void SayHello(string greeting)
+{
+ // increment ExactlyOnceReceived counter on DB
+
+ // Success: transaction auto completes:
+}
+]]></programlisting>
+
+ <para>Because this operation involves two transaction resources, the
+ database and the AMQP message broker, this operates as a full two
+ phase commit transaction managed by the Distributed Transaction
+ Coordinator service. If the transaction proceeds without error,
+ both ExactlyOnceReceived is incremented in the database and the AMQP
+ message is consumed from the broker. Otherwise, ExactlyOnceReceived is
+ unchanged and AMQP message is returned to its queue on the broker.</para>
+
+ <para>For the client code a few changes are made to the non-transacted
+ example. For "exactly once" semantics, we set the AMQP "Durable"
+ message property and enclose the transacted activities in a
+ TransactionScope:</para>
+
+ <programlisting><![CDATA[
+AmqpProperties myDefaults = new AmqpProperties();
+myDefaults.Durable = true;
+amqpBinding.DefaultMessageProperties = myDefaults;
+ChannelFactory<IHelloService> channelFactory =
+new ChannelFactory<IHelloService>(amqpBinding, clientEndpoint);
+IHelloService clientProxy = channelFactory.CreateChannel();
+
+using (TransactionScope ts = new TransactionScope())
+{
+ AmqpProperties amqpProperties = new AmqpProperties();
+ clientProxy.SayHello("Greetings from WCF client");
+ // increment ExactlyOnceSent counter on DB
+ ts.Complete();
+}
+]]></programlisting>
+
+ </section>
+ </chapter>
+
+ <chapter>
+ <title>The .NET Binding for the C++ Messaging Client</title>
+ <para>
+ The .NET Binding for the C++ Qpid Messaging Client is a library that gives
+ any .NET program access to Qpid C++ Messaging objects and methods.
+ </para>
+ <section>
+ <title>.NET Binding for the C++ Messaging Client Component Architecture</title>
+
+ <programlisting><![CDATA[
+ +----------------------------+
+ | Dotnet examples |
+ | Managed C# |
+ +------+---------------+-----+
+ | |
+ V |
+ +---------------------------+ |
+ | .NET Managed Callback | |
+ | org.apache.qpid.messaging.| |
+ | sessionreceiver.dll | |
+ +----------------------+----+ |
+ | |
+managed V V
+(.NET) +--------------------------------+
+:::::::::::::::::::::::| .NET Binding Library |::::::::::::
+unmanaged | org.apache.qpid.messaging.dll |
+(Native Win32/64) +---------------+----------------+
+ |
+ |
+ +----------------+ |
+ | Native examples| |
+ | Unmanaged C++ | |
+ +--------+-------+ |
+ | |
+ V V
+ +----------------------------------+
+ | QPID Messaging C++ Libraries |
+ | qpid*.dll qmf*.dll |
+ +--------+--------------+----------+
+]]></programlisting>
+
+
+<para>This diagram illustrates the code and library components of the binding
+and the hierarchical relationships between them.</para>
+
+ <table id="table-Dotnet-Binding-Component-Architecture" >
+ <title>.NET Binding for the C++ Messaging Client Component Architecture</title>
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Component Name</entry>
+ <entry>Component Function</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>QPID Messaging C++ Libraries</entry>
+ <entry>The QPID Messaging C++ core run time system</entry>
+ </row>
+ <row>
+ <entry>Unmanaged C++ Example Source Programs</entry>
+ <entry>Ordinary C++ programs that illustrate using qpid/cpp Messaging directly
+ in a native Windows environment.</entry>
+ </row>
+ <row>
+ <entry>.NET Messaging Binding Library</entry>
+ <entry>The .NET Messaging Binding library provides interoprability between
+ managed .NET programs and the unmanaged, native Qpid Messaging C++ core
+ run time system. .NET programs create a Reference to this library thereby
+ exposing all of the native C++ Messaging functionality to programs
+ written in any .NET language.</entry>
+ </row>
+ <row>
+ <entry>.NET Messaging Managed Callback Library</entry>
+ <entry>An extension of the .NET Messaging Binding Library that provides message
+ callbacks in a managed .NET environment.</entry>
+ </row>
+ <row>
+ <entry>Managed C# .NET Example Source Programs</entry>
+ <entry>Various C# example programs that illustrate using .NET Binding for C++ Messaging in the .NET environment.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </section>
+
+ <section>
+ <title>.NET Binding for the C++ Messaging Client Examples</title>
+
+ <para>This chapter describes the various sample programs that
+ are available to illustrate common Qpid Messaging usage.</para>
+
+ <table id="table-Dotnet-Binding-Example-Client-Server">
+ <title>Example : Client - Server</title>
+ <tgroup cols="2">
+ <colspec colname="c1"/>
+ <colspec colname="c2"/>
+ <thead>
+ <row>
+ <entry>Example Name</entry>
+ <entry>Example Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>csharp.example.server</entry>
+ <entry>Creates a Receiver and listens for messages.
+ Upon message reception the message content is converted to upper case
+ and forwarded to the received message's ReplyTo address.</entry>
+ </row>
+ <row>
+ <entry>csharp.example.client</entry>
+ <entry>Sends a series of messages to the Server and prints the original message
+ content and the received message content.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table id="table-Dotnet-Binding-Example-MapSender-MapReceiver">
+ <title>Example : Map Sender – Map Receiver</title>
+ <tgroup cols="2">
+ <colspec colname="c1"/>
+ <colspec colname="c2"/>
+ <thead>
+ <row>
+ <entry>Example Name</entry>
+ <entry>Example Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>csharp.map.receiver</entry>
+ <entry>Creates a Receiver and listens for a map message.
+ Upon message reception the message is decoded and displayed on the console.</entry>
+ </row>
+ <row>
+ <entry>csharp.map.sender</entry>
+ <entry>Creates a map message and sends it to map.receiver.
+ The map message contains values for every supported .NET Messaging
+ Binding data type.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table id="table-Dotnet-Binding-Example-Spout-Drain">
+ <title>Example : Spout - Drain</title>
+ <tgroup cols="2">
+ <colspec colname="c1"/>
+ <colspec colname="c2"/>
+ <thead>
+ <row>
+ <entry>Example Name</entry>
+ <entry>Example Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>csharp.example.spout</entry>
+ <entry>Spout is a more complex example of code that generates a series of messages
+ and sends them to peer program Drain. Flexible command line arguments allow
+ the user to specify a variety of message and program options.</entry>
+ </row>
+ <row>
+ <entry>csharp.example.drain</entry>
+ <entry>Drain is a more complex example of code that receives a series of messages
+ and displays their contents on the console.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table id="table-Dotnet-Binding-Example-CallbackSender-CallbackReceiver">
+ <title>Example : Map Callback Sender – Map Callback Receiver</title>
+ <tgroup cols="2">
+ <colspec colname="c1"/>
+ <colspec colname="c2"/>
+ <thead>
+ <row>
+ <entry>Example Name</entry>
+ <entry>Example Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>csharp.map.callback.receiver</entry>
+ <entry>Creates a Receiver and listens for a map message.
+ Upon message reception the message is decoded and displayed on the console.
+ This example illustrates the use of the C# managed code callback mechanism
+ provided by .NET Messaging Binding Managed Callback Library.</entry>
+ </row>
+ <row>
+ <entry>csharp.map.callback.sender</entry>
+ <entry>Creates a map message and sends it to map_receiver.
+ The map message contains values for every supported .NET Messaging
+ Binding data type.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table id="table-Dotnet-Binding-Example-DeclareQueues">
+ <title>Example - Declare Queues</title>
+ <tgroup cols="2">
+ <colspec colname="c1"/>
+ <colspec colname="c2"/>
+ <thead>
+ <row>
+ <entry>Example Name</entry>
+ <entry>Example Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>csharp.example.declare_queues</entry>
+ <entry>A program to illustrate creating objects on a broker.
+ This program creates a queue used by spout and drain.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table id="table-Dotnet-Binding-Example-DirectSender-DirectReceiver">
+ <title>Example: Direct Sender - Direct Receiver</title>
+ <tgroup cols="2">
+ <colspec colname="c1"/>
+ <colspec colname="c2"/>
+ <thead>
+ <row>
+ <entry>Example Name</entry>
+ <entry>Example Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>csharp.direct.receiver</entry>
+ <entry>Creates a Receiver and listens for a messages.
+ Upon message reception the message is decoded and displayed on the console.</entry>
+ </row>
+ <row>
+ <entry>csharp.direct.sender</entry>
+ <entry> Creates a series of messages and sends them to csharp.direct.receiver.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table id="table-Dotnet-Binding-Example-Helloworld">
+ <title>Example: Hello World</title>
+ <tgroup cols="2">
+ <colspec colname="c1"/>
+ <colspec colname="c2"/>
+ <thead>
+ <row>
+ <entry>Example Name</entry>
+ <entry>Example Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>csharp.example.helloworld</entry>
+ <entry>A program to send a message and to receive the same message.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </section>
+
+ <section>
+ <title>.NET Binding Class Mapping to Underlying C++ Messaging API</title>
+
+ <para>This chapter describes the specific mappings between
+ classes in the .NET Binding and the underlying C++ Messaging
+ API.</para>
+
+ <section>
+ <title>.NET Binding for the C++ Messaging API Class: Address</title>
+ <table id="table-Dotnet-Binding-Address">
+ <title>.NET Binding for the C++ Messaging API Class: Address</title>
+ <tgroup cols="2">
+ <colspec colname="c1" colwidth="1*"/>
+ <colspec colname="c2" colwidth="7*"/>
+ <thead>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">.NET Binding Class: Address</entry>
+ </row>
+ <row>
+ <entry>Language</entry>
+ <entry>Syntax</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>C++</entry>
+ <entry>class Address</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public ref class Address</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Constructor</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>Address();</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public Address();</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Constructor</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>Address(const std::string&amp; address);</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public Address(string address);</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Constructor</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>Address(const std::string&amp; name, const std::string&amp; subject, const qpid::types::Variant::Map&amp; options, const std::string&amp; type = "");</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public Address(string name, string subject, Dictionary&lt;string, object&gt; options);</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public Address(string name, string subject, Dictionary&lt;string, object&gt; options, string type);</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Copy constructor</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>Address(const Address&amp; address);</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public Address(Address address);</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Destructor</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>~Address();</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>~Address();</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Finalizer</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>n/a</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>!Address();</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Copy assignment operator</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>Address&amp; operator=(const Address&amp;);</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public Address op_Assign(Address rhs);</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Property: Name</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>const std::string&amp; getName() const;</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>void setName(const std::string&amp;);</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public string Name { get; set; }</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Property: Subject</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>const std::string&amp; getSubject() const;</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>void setSubject(const std::string&amp;);</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public string Subject { get; set; }</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Property: Options</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>const qpid::types::Variant::Map&amp; getOptions() const;</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>qpid::types::Variant::Map&amp; getOptions();</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>void setOptions(const qpid::types::Variant::Map&amp;);</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public Dictionary&lt;string, object&gt; Options { get; set; }</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Property: Type</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>std::string getType() const;</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>void setType(const std::string&amp;);</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public string Type { get; set; }</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Miscellaneous</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>std::string str() const;</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public string ToStr();</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Miscellaneous</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>operator bool() const;</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>n/a</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Miscellaneous</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>bool operator !() const;</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>n/a</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </section>
+ <section>
+ <title>.NET Binding for the C++ Messaging API Class: Connection</title>
+ <table id="table-Dotnet-Binding-Connection">
+ <title>.NET Binding for the C++ Messaging API Class: Connection</title>
+ <tgroup cols="2">
+ <colspec colname="c1" colwidth="1*"/>
+ <colspec colname="c2" colwidth="7*"/>
+ <thead>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">.NET Binding Class: Connection</entry>
+ </row>
+ <row>
+ <entry>Language</entry>
+ <entry>Syntax</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>C++</entry>
+ <entry>class Connection : public qpid::messaging::Handle&lt;ConnectionImpl&gt;</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public ref class Connection</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Constructor</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>Connection(ConnectionImpl* impl);</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>n/a</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Constructor</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>Connection();</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>n/a</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Constructor</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>Connection(const std::string&amp; url, const qpid::types::Variant::Map&amp; options = qpid::types::Variant::Map());</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public Connection(string url);</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public Connection(string url, Dictionary&lt;string, object&gt; options);</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Constructor</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>Connection(const std::string&amp; url, const std::string&amp; options);</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public Connection(string url, string options); </entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Copy Constructor</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>Connection(const Connection&amp;);</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public Connection(Connection connection);</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Destructor</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>~Connection();</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>~Connection();</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Finalizer</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>n/a</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>!Connection();</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Copy assignment operator</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>Connection&amp; operator=(const Connection&amp;);</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public Connection op_Assign(Connection rhs);</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Method: SetOption</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>void setOption(const std::string&amp; name, const qpid::types::Variant&amp; value);</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public void SetOption(string name, object value);</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Method: open</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>void open();</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public void Open();</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Property: isOpen</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>bool isOpen();</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public bool IsOpen { get; }</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Method: close</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>void close();</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public void Close();</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Method: createTransactionalSession</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>Session createTransactionalSession(const std::string&amp; name = std::string());</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public Session CreateTransactionalSession();</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public Session CreateTransactionalSession(string name);</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Method: createSession</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>Session createSession(const std::string&amp; name = std::string());</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public Session CreateSession();</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public Session CreateSession(string name);</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Method: getSession</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>Session getSession(const std::string&amp; name) const;</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public Session GetSession(string name);</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Property: AuthenticatedUsername</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>std::string getAuthenticatedUsername();</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public string GetAuthenticatedUsername();</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </section>
+ <section>
+ <title>.NET Binding for the C++ Messaging API Class: Duration</title>
+ <table id="table-Dotnet-Binding-Duration">
+ <title>.NET Binding for the C++ Messaging API Class: Duration</title>
+ <tgroup cols="2">
+ <colspec colname="c1" colwidth="1*"/>
+ <colspec colname="c2" colwidth="7*"/>
+ <thead>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">.NET Binding Class: Duration</entry>
+ </row>
+ <row>
+ <entry>Language</entry>
+ <entry>Syntax</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>C++</entry>
+ <entry>class Duration</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public ref class Duration</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Constructor</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>explicit Duration(uint64_t milliseconds);</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public Duration(ulong mS);</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Copy constructor</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>n/a</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public Duration(Duration rhs);</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Destructor</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>default</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>default</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Finalizer</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>n/a</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>default</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Property: Milliseconds</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>uint64_t getMilliseconds() const;</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public ulong Milliseconds { get; }</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Operator: *</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>Duration operator*(const Duration&amp; duration, uint64_t multiplier);</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public static Duration operator *(Duration dur, ulong multiplier);</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public static Duration Multiply(Duration dur, ulong multiplier);</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>Duration operator*(uint64_t multiplier, const Duration&amp; duration);</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public static Duration operator *(ulong multiplier, Duration dur);</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public static Duration Multiply(ulong multiplier, Duration dur);</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Constants</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>static const Duration FOREVER;</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>static const Duration IMMEDIATE;</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>static const Duration SECOND;</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>static const Duration MINUTE;</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public sealed class DurationConstants</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public static Duration FORVER;</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public static Duration IMMEDIATE;</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public static Duration MINUTE;</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public static Duration SECOND;</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </section>
+ <section>
+ <title>.NET Binding for the C++ Messaging API Class: FailoverUpdates</title>
+ <table id="table-Dotnet-Binding-FailoverUpdates">
+ <title>.NET Binding for the C++ Messaging API Class: FailoverUpdates</title>
+ <tgroup cols="2">
+ <colspec colname="c1" colwidth="1*"/>
+ <colspec colname="c2" colwidth="7*"/>
+ <thead>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">.NET Binding Class: FailoverUpdates</entry>
+ </row>
+ <row>
+ <entry>Language</entry>
+ <entry>Syntax</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>C++</entry>
+ <entry>class FailoverUpdates</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public ref class FailoverUpdates</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Constructor</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>FailoverUpdates(Connection&amp; connection);</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public FailoverUpdates(Connection connection);</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Destructor</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>~FailoverUpdates();</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>~FailoverUpdates();</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Finalizer</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>n/a</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>!FailoverUpdates();</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </section>
+ <section>
+ <title>.NET Binding for the C++ Messaging API Class: Message</title>
+ <table id="table-Dotnet-Binding-Message">
+ <title>.NET Binding for the C++ Messaging API Class: Message</title>
+ <tgroup cols="2">
+ <colspec colname="c1" colwidth="1*"/>
+ <colspec colname="c2" colwidth="7*"/>
+ <thead>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">.NET Binding Class: Message</entry>
+ </row>
+ <row>
+ <entry>Language</entry>
+ <entry>Syntax</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>C++</entry>
+ <entry>class Message</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public ref class Message</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Constructor</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>Message(const std::string&amp; bytes = std::string());</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>Message();</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>Message(System::String ^ theStr);</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>Message(System::Object ^ theValue);</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>Message(array&lt;System::Byte&gt; ^ bytes);</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Constructor</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>Message(const char*, size_t);</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public Message(byte[] bytes, int offset, int size);</entry>
+ </row>
+ <row>
+ <entry> </entry>
+ <entry>Copy constructor</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>Message(const Message&amp;);</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public Message(Message message);</entry>
+ </row>
+ <row>
+ <entry> </entry>
+ <entry>Copy assignment operator</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>Message&amp; operator=(const Message&amp;);</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public Message op_Assign(Message rhs);</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Destructor</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>~Message();</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>~Message();</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Finalizer</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>n/a</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>!Message()</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Property: ReplyTo</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>void setReplyTo(const Address&amp;);</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>const Address&amp; getReplyTo() const;</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public Address ReplyTo { get; set; }</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Property: Subject</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>void setSubject(const std::string&amp;);</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>const std::string&amp; getSubject() const;</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public string Subject { get; set; }</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Property: ContentType</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>void setContentType(const std::string&amp;);</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>const std::string&amp; getContentType() const;</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public string ContentType { get; set; }</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Property: MessageId</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>void setMessageId(const std::string&amp;);</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>const std::string&amp; getMessageId() const;</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public string MessageId { get; set; }</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Property: UserId</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>void setUserId(const std::string&amp;);</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>const std::string&amp; getUserId() const;</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public string UserId { get; set; }</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Property: CorrelationId</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>void setCorrelationId(const std::string&amp;);</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>const std::string&amp; getCorrelationId() const;</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public string CorrelationId { get; set; }</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Property: Priority</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>void setPriority(uint8_t);</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>uint8_t getPriority() const;</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public byte Priority { get; set; }</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Property: Ttl</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>void setTtl(Duration ttl);</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>Duration getTtl() const;</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public Duration Ttl { get; set; }</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Property: Durable</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>void setDurable(bool durable);</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>bool getDurable() const;</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public bool Durable { get; set; }</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Property: Redelivered</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>bool getRedelivered() const;</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>void setRedelivered(bool);</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public bool Redelivered { get; set; }</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Method: SetProperty</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>void setProperty(const std::string&amp;, const qpid::types::Variant&amp;);</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public void SetProperty(string name, object value);</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Property: Properties</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>const qpid::types::Variant::Map&amp; getProperties() const;</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>qpid::types::Variant::Map&amp; getProperties();</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public Dictionary&lt;string, object&gt; Properties { get; set; }</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Method: SetContent</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>void setContent(const std::string&amp;);</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>void setContent(const char* chars, size_t count);</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public void SetContent(byte[] bytes);</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public void SetContent(string content);</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public void SetContent(byte[] bytes, int offset, int size);</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Method: GetContent</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>std::string getContent() const;</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public string GetContent();</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public void GetContent(byte[] arr);</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public void GetContent(Collection&lt;object&gt; __p1);</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public void GetContent(Dictionary&lt;string, object&gt; dict);</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Method: GetContentPtr</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>const char* getContentPtr() const;</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>n/a</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Property: ContentSize</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>size_t getContentSize() const;</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public ulong ContentSize { get; }</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Struct: EncodingException</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>struct EncodingException : qpid::types::Exception</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>n/a</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Method: decode</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>void decode(const Message&amp; message, qpid::types::Variant::Map&amp; map, const std::string&amp; encoding = std::string());</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>void decode(const Message&amp; message, qpid::types::Variant::List&amp; list, const std::string&amp; encoding = std::string());</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>n/a</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Method: encode</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>void encode(const qpid::types::Variant::Map&amp; map, Message&amp; message, const std::string&amp; encoding = std::string());</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>void encode(const qpid::types::Variant::List&amp; list, Message&amp; message, const std::string&amp; encoding = std::string());</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>n/a</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Method: AsString</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>n/a</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public string AsString(object obj);</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public string ListAsString(Collection&lt;object&gt; list);</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public string MapAsString(Dictionary&lt;string, object&gt; dict);</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </section>
+ <section>
+ <title>.NET Binding for the C++ Messaging API Class: Receiver</title>
+ <table id="table-Dotnet-Binding-Receiver">
+ <title>.NET Binding for the C++ Messaging API Class: Receiver</title>
+ <tgroup cols="2">
+ <colspec colname="c1" colwidth="1*"/>
+ <colspec colname="c2" colwidth="7*"/>
+ <thead>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">.NET Binding Class: Receiver</entry>
+ </row>
+ <row>
+ <entry>Language</entry>
+ <entry>Syntax</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>C++</entry>
+ <entry>class Receiver</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public ref class Receiver</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Constructor</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>Constructed object is returned by Session.CreateReceiver</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Copy constructor</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>Receiver(const Receiver&amp;);</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public Receiver(Receiver receiver);</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Destructor</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>~Receiver();</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>~Receiver();</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Finalizer</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>n/a</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>!Receiver()</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Copy assignment operator</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>Receiver&amp; operator=(const Receiver&amp;);</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public Receiver op_Assign(Receiver rhs);</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Method: Get</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>bool get(Message&amp; message, Duration timeout=Duration::FOREVER);</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public bool Get(Message mmsgp);</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public bool Get(Message mmsgp, Duration durationp);</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Method: Get</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>Message get(Duration timeout=Duration::FOREVER);</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public Message Get();</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public Message Get(Duration durationp);</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Method: Fetch</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>bool fetch(Message&amp; message, Duration timeout=Duration::FOREVER);</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public bool Fetch(Message mmsgp);</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public bool Fetch(Message mmsgp, Duration duration);</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Method: Fetch</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>Message fetch(Duration timeout=Duration::FOREVER);</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public Message Fetch();</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public Message Fetch(Duration durationp);</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Property: Capacity</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>void setCapacity(uint32_t);</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>uint32_t getCapacity();</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public uint Capacity { get; set; }</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Property: Available</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>uint32_t getAvailable();</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public uint Available { get; }</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Property: Unsettled</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>uint32_t getUnsettled();</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public uint Unsettled { get; }</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Method: Close</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>void close();</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public void Close();</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Property: IsClosed</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>bool isClosed() const;</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public bool IsClosed { get; }</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Property: Name</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>const std::string&amp; getName() const;</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public string Name { get; }</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Property: Session</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>Session getSession() const;</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public Session Session { get; }</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </section>
+ <section>
+ <title>.NET Binding for the C++ Messaging API Class: Sender</title>
+ <table id="table-Dotnet-Binding-Sender">
+ <title>.NET Binding for the C++ Messaging API Class: Sender</title>
+ <tgroup cols="2">
+ <colspec colname="c1" colwidth="1*"/>
+ <colspec colname="c2" colwidth="7*"/>
+ <thead>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">.NET Binding Class: Sender</entry>
+ </row>
+ <row>
+ <entry>Language</entry>
+ <entry>Syntax</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>C++</entry>
+ <entry>class Sender</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public ref class Sender</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Constructor</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>Constructed object is returned by Session.CreateSender</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Copy constructor</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>Sender(const Sender&amp;);</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public Sender(Sender sender);</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Destructor</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>~Sender();</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>~Sender();</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Finalizer</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>n/a</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>!Sender()</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Copy assignment operator</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>Sender&amp; operator=(const Sender&amp;);</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public Sender op_Assign(Sender rhs);</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Method: Send</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>void send(const Message&amp; message, bool sync=false);</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public void Send(Message mmsgp);</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public void Send(Message mmsgp, bool sync);</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Method: Close</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>void close();</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public void Close();</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Property: Capacity</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>void setCapacity(uint32_t);</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>uint32_t getCapacity();</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public uint Capacity { get; set; }</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Property: Available</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>uint32_t getAvailable();</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public uint Available { get; }</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Property: Unsettled</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>uint32_t getUnsettled();</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public uint Unsettled { get; }</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Property: Name</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>const std::string&amp; getName() const;</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public string Name { get; }</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Property: Session</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>Session getSession() const;</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public Session Session { get; }</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </section>
+ <section>
+ <title>.NET Binding for the C++ Messaging API Class: Session</title>
+ <table id="table-Dotnet-Binding-Session">
+ <title>.NET Binding for the C++ Messaging API Class: Session</title>
+ <tgroup cols="2">
+ <colspec colname="c1" colwidth="1*"/>
+ <colspec colname="c2" colwidth="7*"/>
+ <thead>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">.NET Binding Class: Session</entry>
+ </row>
+ <row>
+ <entry>Language</entry>
+ <entry>Syntax</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>C++</entry>
+ <entry>class Session</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public ref class Session</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Constructor</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>Constructed object is returned by Connection.CreateSession</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Copy constructor</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>Session(const Session&amp;);</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public Session(Session session);</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Destructor</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>~Session();</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>~Session();</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Finalizer</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>n/a</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>!Session()</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Copy assignment operator</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>Session&amp; operator=(const Session&amp;);</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public Session op_Assign(Session rhs);</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Method: Close</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>void close();</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public void Close();</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Method: Commit</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>void commit();</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public void Commit();</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Method: Rollback</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>void rollback();</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public void Rollback();</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Method: Acknowledge</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>void acknowledge(bool sync=false);</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>void acknowledge(Message&amp;, bool sync=false);</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public void Acknowledge();</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public void Acknowledge(bool sync);</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public void Acknowledge(Message __p1);</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public void Acknowledge(Message __p1, bool __p2);</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Method: Reject</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>void reject(Message&amp;);</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public void Reject(Message __p1);</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Method: Release</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>void release(Message&amp;);</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public void Release(Message __p1);</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Method: Sync</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>void sync(bool block=true);</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public void Sync();</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public void Sync(bool block);</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Property: Receivable</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>uint32_t getReceivable();</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public uint Receivable { get; }</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Property: UnsettledAcks</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>uint32_t getUnsettledAcks();</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public uint UnsetledAcks { get; }</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Method: NextReceiver</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>bool nextReceiver(Receiver&amp;, Duration timeout=Duration::FOREVER);</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public bool NextReceiver(Receiver rcvr);</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public bool NextReceiver(Receiver rcvr, Duration timeout);</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Method: NextReceiver</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>Receiver nextReceiver(Duration timeout=Duration::FOREVER);</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public Receiver NextReceiver();</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public Receiver NextReceiver(Duration timeout);</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Method: CreateSender</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>Sender createSender(const Address&amp; address);</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public Sender CreateSender(Address address);</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Method: CreateSender</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>Sender createSender(const std::string&amp; address);</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public Sender CreateSender(string address);</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Method: CreateReceiver</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>Receiver createReceiver(const Address&amp; address);</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public Receiver CreateReceiver(Address address);</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Method: CreateReceiver</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>Receiver createReceiver(const std::string&amp; address);</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public Receiver CreateReceiver(string address);</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Method: GetSender</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>Sender getSender(const std::string&amp; name) const;</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public Sender GetSender(string name);</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Method: GetReceiver</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>Receiver getReceiver(const std::string&amp; name) const;</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public Receiver GetReceiver(string name);</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Property: Connection</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>Connection getConnection() const;</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public Connection Connection { get; }</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Property: HasError</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>bool hasError();</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public bool HasError { get; }</entry>
+ </row>
+ <row>
+ <entry namest="c1" nameend="c2" align="center">Method: CheckError</entry>
+ </row>
+ <row>
+ <entry>C++</entry>
+ <entry>void checkError();</entry>
+ </row>
+ <row>
+ <entry>.NET</entry>
+ <entry>public void CheckError();</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </section>
+ <section>
+ <title>.NET Binding Class: SessionReceiver</title>
+ <para>
+ The SessionReceiver class provides a convenient callback
+ mechanism for Messages received by all Receivers on a given
+ Session.
+ </para>
+ <para>
+ <programlisting><![CDATA[
+using Org.Apache.Qpid.Messaging;
+using System;
+
+namespace Org.Apache.Qpid.Messaging.SessionReceiver
+{
+ public interface ISessionReceiver
+ {
+ void SessionReceiver(Receiver receiver, Message message);
+ }
+
+ public class CallbackServer
+ {
+ public CallbackServer(Session session, ISessionReceiver callback);
+
+ public void Close();
+ }
+}
+]]>
+ </programlisting>
+ </para>
+ <para>
+ To use this class a client program includes references to both
+ Org.Apache.Qpid.Messaging and Org.Apache.Qpid.Messaging.SessionReceiver.
+ The calling program creates a function that implements the
+ ISessionReceiver interface. This function will be called whenever
+ message is received by the session. The callback process is started
+ by creating a CallbackServer and will continue to run until the
+ client program calls the CallbackServer.Close function.
+ </para>
+ <para>
+ A complete operating example of using the SessionReceiver callback
+ is contained in cpp/bindings/qpid/dotnet/examples/csharp.map.callback.receiver.
+ </para>
+ </section>
+ </section>
+ </chapter>
+</book>
+
+<!--
+ - client code remains exactly the same, but routing behavior
+ changes
+ - exchanges drop messages if nobody is listening, so we need to
+ start drain first
+ - drain will exit immediately if the source is empty (note that
+ this is actually a semantic guarantee provided by the API, we
+ know for a fact that the source is empty when drain/fetch
+ reports it, no fudge factor timeout is required [this assumes
+ nobody is concurrently publishing of course])
+ - drain -f invokes blocking fetch (you could use a timeout here also)
+ -->
diff --git a/qpid/doc/book/src/PythonBrokerTest.xml b/qpid/doc/book/src/PythonBrokerTest.xml
new file mode 100644
index 0000000000..ae7edade40
--- /dev/null
+++ b/qpid/doc/book/src/PythonBrokerTest.xml
@@ -0,0 +1,98 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+
+ 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.
+
+-->
+
+<section>
+ <title>
+ PythonBrokerTest
+ </title>
+ <section role="h2" id="PythonBrokerTest-PythonBrokerSystemTestSuite">
+ <title>
+ Python Broker System Test Suite
+ </title>
+ <para>
+ This is a suite of python client tests that exercise and verify
+ broker functionality. Python allows us to rapidly develop client
+ test scenarios and provides a 'neutral' set of tests that can run
+ against any AMQP-compliant broker.
+ </para>
+ <para>
+ The python/tests directory contains a collection of python
+ modules, each containing several unittest classes, each
+ containing a set of test methods that represent some test
+ scenario. Test classes inherit qpid.TestBas from
+ qpid/testlib.py, it inherits unittest.TestCase
+ but adds some qpid-specific setUp/tearDown and
+ convenience functions.
+ </para>
+ <para>
+ TODO: get pydoc generated up to qpid wiki or website
+ automatically?
+ </para>
+ <section role="h3" id="PythonBrokerTest-Runningthetests">
+ <title>
+ Running the tests
+ </title>
+ <para>
+ Simplest way to run the tests:
+ </para>
+ <itemizedlist>
+ <listitem>
+ <para>Run a broker on the default port
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ ./run_tests
+ </para>
+ </listitem>
+ </itemizedlist>
+ <para>
+ For additional options: ./run_tests --help
+ </para>
+ <!--h3-->
+ </section>
+
+ <section role="h3" id="PythonBrokerTest-Expectedfailures">
+ <title>
+ Expected failures
+ </title>
+ <para>
+ Until we complete functionality, tests may fail because the
+ tested functionality is missing in the broker. To skip
+ expected failures in the C++ or Java brokers:
+ </para>
+ <programlisting>
+./run_tests -I cpp_failing.txt
+./run_tests -I java_failing.txt
+ </programlisting>
+ <para>
+ If you fix a failure, please remove it from the corresponding
+ list.
+ </para>
+
+ <!--h3-->
+ </section>
+
+ <!--h2-->
+ </section>
+
+</section>
diff --git a/qpid/doc/book/src/QMF-Python-Console-Tutorial.xml b/qpid/doc/book/src/QMF-Python-Console-Tutorial.xml
new file mode 100644
index 0000000000..2cb802671b
--- /dev/null
+++ b/qpid/doc/book/src/QMF-Python-Console-Tutorial.xml
@@ -0,0 +1,894 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+
+ 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.
+
+-->
+
+<section><title>
+ QMF Python Console Tutorial
+ </title>
+ <itemizedlist>
+ <listitem><para>
+ <xref linkend="QMFPythonConsoleTutorial-PrerequisiteInstallQpidMessaging"/>
+ </para></listitem>
+ <listitem><para>
+ <xref linkend="QMFPythonConsoleTutorial-SynchronousConsoleOperations"/>
+ </para></listitem>
+ <listitem><para>
+ <itemizedlist>
+ <listitem><para>
+ <xref linkend="QMFPythonConsoleTutorial-CreatingaQMFConsoleSessionandAttachingtoaBroker"/>
+ </para></listitem>
+ <listitem><para>
+ <xref linkend="QMFPythonConsoleTutorial-AccessingManagedObjects"/>
+ </para></listitem>
+ <listitem><para>
+ <itemizedlist>
+ <listitem><para>
+ <xref linkend="QMFPythonConsoleTutorial-ViewingPropertiesandStatisticsofanObject"/>
+ </para></listitem>
+ <listitem><para>
+ <xref linkend="QMFPythonConsoleTutorial-InvokingMethodsonanObject"/>
+ </para></listitem>
+ </itemizedlist>
+ </para></listitem>
+ </itemizedlist>
+ </para></listitem>
+ <listitem><para>
+ <xref linkend="QMFPythonConsoleTutorial-AsynchronousConsoleOperations"/>
+ </para></listitem>
+ <listitem><para>
+ <itemizedlist>
+ <listitem><para>
+ <xref linkend="QMFPythonConsoleTutorial-CreatingaConsoleClasstoReceiveAsynchronousData"/>
+ </para></listitem>
+ <listitem><para>
+ <xref linkend="QMFPythonConsoleTutorial-ReceivingEvents"/>
+ </para></listitem>
+ <listitem><para>
+ <xref linkend="QMFPythonConsoleTutorial-ReceivingObjects"/>
+ </para></listitem>
+ <listitem><para>
+ <xref linkend="QMFPythonConsoleTutorial-AsynchronousMethodCallsandMethodTimeouts"/>
+ </para></listitem>
+ </itemizedlist>
+ </para></listitem>
+ <listitem><para>
+ <xref linkend="QMFPythonConsoleTutorial-DiscoveringwhatKindsofObjectsareAvailable"/>
+ </para></listitem>
+ </itemizedlist>
+ <section role="h1" id="QMFPythonConsoleTutorial-PrerequisiteInstallQpidMessaging"><title>
+ Prerequisite
+ - Install Qpid Messaging
+ </title>
+
+ <para>
+ 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
+ <ulink url="http://qpid.apache.org">http://qpid.apache.org</ulink>for
+ information as to where to get Qpid Messaging.
+ </para><para>
+ 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 Python-language client library
+ includes the QMF console libraries needed for this tutorial.
+ </para><para>
+ 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.
+ </para><para>
+ 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.
+ </para>
+<!--h1--></section>
+
+ <section role="h1" id="QMFPythonConsoleTutorial-SynchronousConsoleOperations"><title>
+ Synchronous
+ Console Operations
+ </title>
+
+ <para>
+ The Python 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 Python 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.
+ </para><section role="h2" id="QMFPythonConsoleTutorial-CreatingaQMFConsoleSessionandAttachingtoaBroker"><title>
+ Creating a QMF Console Session and Attaching to a Broker
+ </title>
+
+ <para>
+ For the purposes of this tutorial, code examples will be shown as
+ they are entered in an interactive python session.
+ </para>
+ <programlisting>
+$ python
+Python 2.5.2 (r252:60911, Sep 30 2008, 15:41:38)
+[GCC 4.3.2 20080917 (Red Hat 4.3.2-4)] on linux2
+Type "help", "copyright", "credits" or "license" for more information.
+&gt;&gt;&gt;
+</programlisting>
+ <para>
+ We will begin by importing the required libraries. If the Python
+ client is properly installed, these libraries will be found
+ normally by the Python interpreter.
+ </para>
+ <programlisting>
+&gt;&gt;&gt; from qmf.console import Session
+</programlisting>
+ <para>
+ We must now create a <emphasis>Session</emphasis> object to manage this QMF
+ console session.
+ </para>
+ <programlisting>
+&gt;&gt;&gt; sess = Session()
+</programlisting>
+ <para>
+ If no arguments are supplied to the creation of <emphasis>Session</emphasis>,
+ it defaults to synchronous-only operation. It also defaults to
+ user-management of connections. More on this in a moment.
+ </para><para>
+ We will now establish a connection to the messaging broker. If
+ the broker daemon is running on the local host, simply use the
+ following:
+ </para>
+ <programlisting>
+&gt;&gt;&gt; broker = sess.addBroker()
+</programlisting>
+ <para>
+ If the messaging broker is on a remote host, supply the URL to
+ the broker in the <emphasis>addBroker</emphasis> function call. Here's how to
+ connect to a local broker using the URL.
+ </para>
+ <programlisting>
+&gt;&gt;&gt; broker = sess.addBroker("amqp://localhost")
+</programlisting>
+ <para>
+ The call to <emphasis>addBroker</emphasis> is synchronous and will return
+ only after the connection has been successfully established or
+ has failed. If a failure occurs, <emphasis>addBroker</emphasis> will raise an
+ exception that can be handled by the console script.
+ </para>
+ <programlisting>
+&gt;&gt;&gt; try:
+... broker = sess.addBroker("amqp://localhost:1000")
+... except:
+... print "Connection Failed"
+...
+Connection Failed
+&gt;&gt;&gt;
+</programlisting>
+ <para>
+ This operation fails because there is no Qpid Messaging broker
+ listening on port 1000 (the default port for qpidd is 5672).
+ </para><para>
+ If preferred, the QMF session can manage the connection for you.
+ In this case, <emphasis>addBroker</emphasis> 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.
+ </para>
+<!--h2--></section>
+
+ <section role="h2" id="QMFPythonConsoleTutorial-AccessingManagedObjects"><title>
+ Accessing
+ Managed Objects
+ </title>
+
+ <para>
+ The Python console API provides access to remotely managed
+ objects via a <emphasis>proxy</emphasis> 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.
+ </para><para>
+ 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.
+ </para><para>
+ Proxy objects are obtained by calling the
+ <emphasis>Session.getObjects</emphasis> function.
+ </para><para>
+ To illustrate, we'll get a list of objects representing queues in
+ the message broker itself.
+ </para>
+ <programlisting>
+&gt;&gt;&gt; queues = sess.getObjects(_class="queue", _package="org.apache.qpid.broker")
+</programlisting>
+ <para>
+ <emphasis>queues</emphasis> 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.
+ </para>
+ <programlisting>
+&gt;&gt;&gt; for q in queues:
+... print q
+...
+org.apache.qpid.broker:queue[0-1537-1-0-58] 0-0-1-0-1152921504606846979:reply-localhost.localdomain.32004
+org.apache.qpid.broker:queue[0-1537-1-0-61] 0-0-1-0-1152921504606846979:topic-localhost.localdomain.32004
+&gt;&gt;&gt;
+</programlisting>
+ <section role="h3" id="QMFPythonConsoleTutorial-ViewingPropertiesandStatisticsofanObject"><title>
+ Viewing Properties and Statistics of an Object
+ </title>
+
+ <para>
+ Let us now focus our attention on one of the queue objects.
+ </para>
+ <programlisting>
+&gt;&gt;&gt; queue = queues[0]
+</programlisting>
+ <para>
+ The attributes of an object are partitioned into
+ <emphasis>properties</emphasis> and <emphasis>statistics</emphasis>. Though the
+ distinction is somewhat arbitrary, <emphasis>properties</emphasis> tend to
+ be fairly static and may also be large and <emphasis>statistics</emphasis>
+ tend to change rapidly and are relatively small (counters, etc.).
+ </para><para>
+ There are two ways to view the properties of an object. An array
+ of properties can be obtained using the <emphasis>getProperties</emphasis>
+ function:
+ </para>
+ <programlisting>
+&gt;&gt;&gt; props = queue.getProperties()
+&gt;&gt;&gt; for prop in props:
+... print prop
+...
+(vhostRef, 0-0-1-0-1152921504606846979)
+(name, u'reply-localhost.localdomain.32004')
+(durable, False)
+(autoDelete, True)
+(exclusive, True)
+(arguments, {})
+&gt;&gt;&gt;
+</programlisting>
+ <para>
+ The <emphasis>getProperties</emphasis> function returns an array of tuples.
+ Each tuple consists of the property descriptor and the property
+ value.
+ </para><para>
+ A more convenient way to access properties is by using the
+ attribute of the proxy object directly:
+ </para>
+ <programlisting>
+&gt;&gt;&gt; queue.autoDelete
+True
+&gt;&gt;&gt; queue.name
+u'reply-localhost.localdomain.32004'
+&gt;&gt;&gt;
+</programlisting>
+ <para>
+ Statistics are accessed in the same way:
+ </para>
+ <programlisting>
+&gt;&gt;&gt; stats = queue.getStatistics()
+&gt;&gt;&gt; for stat in stats:
+... print stat
+...
+(msgTotalEnqueues, 53)
+(msgTotalDequeues, 53)
+(msgTxnEnqueues, 0)
+(msgTxnDequeues, 0)
+(msgPersistEnqueues, 0)
+(msgPersistDequeues, 0)
+(msgDepth, 0)
+(byteDepth, 0)
+(byteTotalEnqueues, 19116)
+(byteTotalDequeues, 19116)
+(byteTxnEnqueues, 0)
+(byteTxnDequeues, 0)
+(bytePersistEnqueues, 0)
+(bytePersistDequeues, 0)
+(consumerCount, 1)
+(consumerCountHigh, 1)
+(consumerCountLow, 1)
+(bindingCount, 2)
+(bindingCountHigh, 2)
+(bindingCountLow, 2)
+(unackedMessages, 0)
+(unackedMessagesHigh, 0)
+(unackedMessagesLow, 0)
+(messageLatencySamples, 0)
+(messageLatencyMin, 0)
+(messageLatencyMax, 0)
+(messageLatencyAverage, 0)
+&gt;&gt;&gt;
+</programlisting>
+ <para>
+ or alternatively:
+ </para>
+ <programlisting>
+&gt;&gt;&gt; queue.byteTotalEnqueues
+19116
+&gt;&gt;&gt;
+</programlisting>
+ <para>
+ 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 <emphasis>byteTotalEnqueues</emphasis> statistic will show
+ the same number as it did the first time. To get updated data on
+ a proxy object, use the <emphasis>update</emphasis> function call:
+ </para>
+ <programlisting>
+&gt;&gt;&gt; queue.update()
+&gt;&gt;&gt; queue.byteTotalEnqueues
+19783
+&gt;&gt;&gt;
+</programlisting>
+
+ <note><title>Be Advised</title>
+ <para>
+ The <emphasis>update</emphasis> method was added after the M4 release
+ of Qpid/Qmf. It may not be available in your
+ distribution.
+ </para>
+ </note>
+<!--h3--></section>
+
+ <section role="h3" id="QMFPythonConsoleTutorial-InvokingMethodsonanObject"><title>
+ Invoking
+ Methods on an Object
+ </title>
+
+ <para>
+ Up to this point, we have used the QMF Console API to find
+ managed objects and view their attributes, a read-only activity.
+ The next topic to illustrate is how to invoke a method on a
+ managed object. Methods allow consoles to control the managed
+ agents by either triggering a one-time action or by changing the
+ values of attributes in an object.
+ </para><para>
+ First, we'll cover some background information about methods. A
+ <emphasis>QMF object class</emphasis> (of which a <emphasis>QMF object</emphasis> is an
+ instance), may have zero or more methods. To obtain a list of
+ methods available for an object, use the <emphasis>getMethods</emphasis>
+ function.
+ </para>
+ <programlisting>
+&gt;&gt;&gt; methodList = queue.getMethods()
+</programlisting>
+ <para>
+ <emphasis>getMethods</emphasis> returns an array of method descriptors (of
+ type qmf.console.SchemaMethod). To get a summary of a method, you
+ can simply print it. The _<emphasis>repr</emphasis>_ function returns a
+ string that looks like a function prototype.
+ </para>
+ <programlisting>
+&gt;&gt;&gt; print methodList
+[purge(request)]
+&gt;&gt;&gt;
+</programlisting>
+ <para>
+ For the purposes of illustration, we'll use a more interesting
+ method available on the <emphasis>broker</emphasis> object which represents
+ the connected Qpid message broker.
+ </para>
+ <programlisting>
+&gt;&gt;&gt; br = sess.getObjects(_class="broker", _package="org.apache.qpid.broker")[0]
+&gt;&gt;&gt; mlist = br.getMethods()
+&gt;&gt;&gt; for m in mlist:
+... print m
+...
+echo(sequence, body)
+connect(host, port, durable, authMechanism, username, password, transport)
+queueMoveMessages(srcQueue, destQueue, qty)
+&gt;&gt;&gt;
+</programlisting>
+ <para>
+ We have just learned that the <emphasis>broker</emphasis> object has three
+ methods: <emphasis>echo</emphasis>, <emphasis>connect</emphasis>, and
+ <emphasis>queueMoveMessages</emphasis>. We'll use the <emphasis>echo</emphasis> method to
+ "ping" the broker.
+ </para>
+ <programlisting>
+&gt;&gt;&gt; result = br.echo(1, "Message Body")
+&gt;&gt;&gt; print result
+OK (0) - {'body': u'Message Body', 'sequence': 1}
+&gt;&gt;&gt; print result.status
+0
+&gt;&gt;&gt; print result.text
+OK
+&gt;&gt;&gt; print result.outArgs
+{'body': u'Message Body', 'sequence': 1}
+&gt;&gt;&gt;
+</programlisting>
+ <para>
+ In the above example, we have invoked the <emphasis>echo</emphasis> method on
+ the instance of the broker designated by the proxy "br" with a
+ sequence argument of 1 and a body argument of "Message Body". The
+ result indicates success and contains the output arguments (in
+ this case copies of the input arguments).
+ </para><para>
+ To be more precise... Calling <emphasis>echo</emphasis> on the proxy causes
+ the input arguments to be marshalled and sent to the remote agent
+ where the method is executed. Once the method execution
+ completes, the output arguments are marshalled and sent back to
+ the console to be stored in the method result.
+ </para><para>
+ You are probably wondering how you are supposed to know what
+ types the arguments are and which arguments are input, which are
+ output, or which are both. This will be addressed later in the
+ "Discovering what Kinds of Objects are Available" section.
+ </para>
+<!--h3--></section>
+<!--h2--></section>
+<!--h1--></section>
+
+ <section role="h1" id="QMFPythonConsoleTutorial-AsynchronousConsoleOperations"><title>
+ Asynchronous
+ Console Operations
+ </title>
+
+ <para>
+ QMF is built on top of a middleware messaging layer (Qpid
+ Messaging). Because of this, QMF can use some communication
+ patterns that are difficult to implement using network transports
+ like UDP, TCP, or SSL. One of these patterns is called the
+ <emphasis>Publication and Subscription</emphasis> pattern (pub-sub for
+ short). In the pub-sub pattern, data sources <emphasis>publish</emphasis>
+ information without a particular destination in mind. Data sinks
+ (destinations) <emphasis>subscribe</emphasis> using a set of criteria that
+ describes what kind of data they are interested in receiving.
+ Data published by a source may be received by zero, one, or many
+ subscribers.
+ </para><para>
+ QMF uses the pub-sub pattern to distribute events, object
+ creation and deletion, and changes to properties and statistics.
+ A console application using the QMF Console API can receive these
+ asynchronous and unsolicited events and updates. This is useful
+ for applications that store and analyze events and/or statistics.
+ It is also useful for applications that react to certain events
+ or conditions.
+ </para><para>
+ Note that console applications may always use the synchronous
+ mechanisms.
+ </para>
+
+ <section role="h2" id="QMFPythonConsoleTutorial-CreatingaConsoleClasstoReceiveAsynchronousData"><title>
+ Creating a Console Class to Receive Asynchronous Data
+ </title>
+
+ <para>
+ Asynchronous API operation occurs when the console application
+ supplies a <emphasis>Console</emphasis> object to the session manager. The
+ <emphasis>Console</emphasis> object (which overrides the
+ <emphasis>qmf.console.Console</emphasis> class) handles all asynchronously
+ arriving data. The <emphasis>Console</emphasis> class has the following
+ methods. Any number of these methods may be overridden by the
+ console application. Any method that is not overridden defaults
+ to a null handler which takes no action when invoked.
+ </para><table><title>QMF Python Console Class Methods</title><tgroup cols="3">
+ <tbody>
+ <row>
+ <entry>
+ Method
+ </entry>
+ <entry>
+ Arguments
+ </entry>
+ <entry>
+ Invoked when...
+ </entry>
+ </row>
+ <row>
+ <entry>
+ brokerConnected
+ </entry>
+ <entry>
+ broker
+ </entry>
+ <entry>
+ a connection to a broker is established
+ </entry>
+ </row>
+ <row>
+ <entry>
+ brokerDisconnected
+ </entry>
+ <entry>
+ broker
+ </entry>
+ <entry>
+ a connection to a broker is lost
+ </entry>
+ </row>
+ <row>
+ <entry>
+ newPackage
+ </entry>
+ <entry>
+ name
+ </entry>
+ <entry>
+ a new package is seen on the QMF bus
+ </entry>
+ </row>
+ <row>
+ <entry>
+ newClass
+ </entry>
+ <entry>
+ kind, classKey
+ </entry>
+ <entry>
+ a new class (event or object) is seen on the QMF bus
+ </entry>
+ </row>
+ <row>
+ <entry>
+ newAgent
+ </entry>
+ <entry>
+ agent
+ </entry>
+ <entry>
+ a new agent appears on the QMF bus
+ </entry>
+ </row>
+ <row>
+ <entry>
+ delAgent
+ </entry>
+ <entry>
+ agent
+ </entry>
+ <entry>
+ an agent disconnects from the QMF bus
+ </entry>
+ </row>
+ <row>
+ <entry>
+ objectProps
+ </entry>
+ <entry>
+ broker, object
+ </entry>
+ <entry>
+ the properties of an object are published
+ </entry>
+ </row>
+ <row>
+ <entry>
+ objectStats
+ </entry>
+ <entry>
+ broker, object
+ </entry>
+ <entry>
+ the statistics of an object are published
+ </entry>
+ </row>
+ <row>
+ <entry>
+ event
+ </entry>
+ <entry>
+ broker, event
+ </entry>
+ <entry>
+ an event is published
+ </entry>
+ </row>
+ <row>
+ <entry>
+ heartbeat
+ </entry>
+ <entry>
+ agent, timestamp
+ </entry>
+ <entry>
+ a heartbeat is published by an agent
+ </entry>
+ </row>
+ <row>
+ <entry>
+ brokerInfo
+ </entry>
+ <entry>
+ broker
+ </entry>
+ <entry>
+ information about a connected broker is available to be
+ queried
+ </entry>
+ </row>
+ <row>
+ <entry>
+ methodResponse
+ </entry>
+ <entry>
+ broker, seq, response
+ </entry>
+ <entry>
+ the result of an asynchronous method call is received
+ </entry>
+ </row>
+ </tbody>
+ </tgroup></table><para>
+ Supplied with the API is a class called <emphasis>DebugConsole</emphasis>.
+ This is a test <emphasis>Console</emphasis> instance that overrides all of
+ the methods such that arriving asynchronous data is printed to
+ the screen. This can be used to see all of the arriving
+ asynchronous data.
+ </para>
+ <!--h2--></section>
+
+ <section role="h2" id="QMFPythonConsoleTutorial-ReceivingEvents"><title>
+ Receiving
+ Events
+ </title>
+
+ <para>
+ We'll start the example from the beginning to illustrate the
+ reception and handling of events. In this example, we will create
+ a <emphasis>Console</emphasis> class that handles broker-connect,
+ broker-disconnect, and event messages. We will also allow the
+ session manager to manage the broker connection for us.
+ </para><para>
+ Begin by importing the necessary classes:
+ </para>
+ <programlisting>
+&gt;&gt;&gt; from qmf.console import Session, Console
+</programlisting>
+ <para>
+ Now, create a subclass of <emphasis>Console</emphasis> that handles the three
+ message types:
+ </para>
+ <programlisting>
+&gt;&gt;&gt; class EventConsole(Console):
+... def brokerConnected(self, broker):
+... print "brokerConnected:", broker
+... def brokerDisconnected(self, broker):
+... print "brokerDisconnected:", broker
+... def event(self, broker, event):
+... print "event:", event
+...
+&gt;&gt;&gt;
+</programlisting>
+ <para>
+ Make an instance of the new class:
+ </para>
+ <programlisting>
+&gt;&gt;&gt; myConsole = EventConsole()
+</programlisting>
+ <para>
+ Create a <emphasis>Session</emphasis> class using the console instance. In
+ addition, we shall request that the session manager do the
+ connection management for us. Notice also that we are requesting
+ that the session manager not receive objects or heartbeats. Since
+ this example is concerned only with events, we can optimize the
+ use of the messaging bus by telling the session manager not to
+ subscribe for object updates or heartbeats.
+ </para>
+ <programlisting>
+&gt;&gt;&gt; sess = Session(myConsole, manageConnections=True, rcvObjects=False, rcvHeartbeats=False)
+&gt;&gt;&gt; broker = sess.addBroker()
+&gt;&gt;&gt;
+</programlisting>
+ <para>
+ Once the broker is added, we will begin to receive asynchronous
+ events (assuming there is a functioning broker available to
+ connect to).
+ </para>
+ <programlisting>
+brokerConnected: Broker connected at: localhost:5672
+event: Thu Jan 29 19:53:19 2009 INFO org.apache.qpid.broker:bind broker=localhost:5672 ...
+</programlisting>
+<!--h2--></section>
+
+ <section role="h2" id="QMFPythonConsoleTutorial-ReceivingObjects"><title>
+ Receiving
+ Objects
+ </title>
+
+ <para>
+ To illustrate asynchronous handling of objects, a small console
+ program is supplied. The entire program is shown below for
+ convenience. We will then go through it part-by-part to explain
+ its design.
+ </para><para>
+ This console program receives object updates and displays a set
+ of statistics as they change. It focuses on broker queue objects.
+ </para>
+ <programlisting>
+# Import needed classes
+from qmf.console import Session, Console
+from time import sleep
+
+# Declare a dictionary to map object-ids to queue names
+queueMap = {}
+
+# Customize the Console class to receive object updates.
+class MyConsole(Console):
+
+ # Handle property updates
+ def objectProps(self, broker, record):
+
+ # Verify that we have received a queue object. Exit otherwise.
+ classKey = record.getClassKey()
+ if classKey.getClassName() != "queue":
+ return
+
+ # If this object has not been seen before, create a new mapping from objectID to name
+ oid = record.getObjectId()
+ if oid not in queueMap:
+ queueMap[oid] = record.name
+
+ # Handle statistic updates
+ def objectStats(self, broker, record):
+
+ # Ignore updates for objects that are not in the map
+ oid = record.getObjectId()
+ if oid not in queueMap:
+ return
+
+ # Print the queue name and some statistics
+ print "%s: enqueues=%d dequeues=%d" % (queueMap[oid], record.msgTotalEnqueues, record.msgTotalDequeues)
+
+ # if the delete-time is non-zero, this object has been deleted. Remove it from the map.
+ if record.getTimestamps()[2] &gt; 0:
+ queueMap.pop(oid)
+
+# Create an instance of the QMF session manager. Set userBindings to True to allow
+# this program to choose which objects classes it is interested in.
+sess = Session(MyConsole(), manageConnections=True, rcvEvents=False, userBindings=True)
+
+# Register to receive updates for broker:queue objects.
+sess.bindClass("org.apache.qpid.broker", "queue")
+broker = sess.addBroker()
+
+# Suspend processing while the asynchronous operations proceed.
+try:
+ while True:
+ sleep(1)
+except:
+ pass
+
+# Disconnect the broker before exiting.
+sess.delBroker(broker)
+</programlisting>
+ <para>
+ Before going through the code in detail, it is important to
+ understand the differences between synchronous object access and
+ asynchronous object access. When objects are obtained
+ synchronously (using the <emphasis>getObjects</emphasis> function), the
+ resulting proxy contains all of the object's attributes, both
+ properties and statistics. When object data is published
+ asynchronously, the properties and statistics are sent separately
+ and only when the session first connects or when the content
+ changes.
+ </para><para>
+ The script wishes to print the queue name with the updated
+ statistics, but the queue name is only present with the
+ properties. For this reason, the program needs to keep some state
+ to correlate property updates with their corresponding statistic
+ updates. This can be done using the <emphasis>ObjectId</emphasis> that
+ uniquely identifies the object.
+ </para>
+ <programlisting>
+ # If this object has not been seen before, create a new mapping from objectID to name
+ oid = record.getObjectId()
+ if oid not in queueMap:
+ queueMap[oid] = record.name
+</programlisting>
+ <para>
+ The above code fragment gets the object ID from the proxy and
+ checks to see if it is in the map (i.e. has been seen before). If
+ it is not in the map, a new map entry is inserted mapping the
+ object ID to the queue's name.
+ </para>
+ <programlisting>
+ # if the delete-time is non-zero, this object has been deleted. Remove it from the map.
+ if record.getTimestamps()[2] &gt; 0:
+ queueMap.pop(oid)
+</programlisting>
+ <para>
+ This code fragment detects the deletion of a managed object.
+ After reporting the statistics, it checks the timestamps of the
+ proxy. <emphasis>getTimestamps</emphasis> returns a list of timestamps in the
+ order:
+ </para><itemizedlist>
+ <listitem><para>
+ <emphasis>Current</emphasis> - The timestamp of the sending of this update.
+ </para></listitem>
+ <listitem><para>
+ <emphasis>Create</emphasis> - The time of the object's creation
+ </para></listitem>
+ <listitem><para>
+ <emphasis>Delete</emphasis> - The time of the object's deletion (or zero if
+ not deleted)
+ </para></listitem>
+ </itemizedlist><para>
+ This code structure is useful for getting information about
+ very-short-lived objects. It is possible that an object will be
+ created, used, and deleted within an update interval. In this
+ case, the property update will arrive first, followed by the
+ statistic update. Both will indicate that the object has been
+ deleted but a full accounting of the object's existence and final
+ state is reported.
+ </para>
+ <programlisting>
+# Create an instance of the QMF session manager. Set userBindings to True to allow
+# this program to choose which objects classes it is interested in.
+sess = Session(MyConsole(), manageConnections=True, rcvEvents=False, userBindings=True)
+
+# Register to receive updates for broker:queue objects.
+sess.bindClass("org.apache.qpid.broker", "queue")
+</programlisting>
+ <para>
+ The above code is illustrative of the way a console application
+ can tune its use of the QMF bus. Note that <emphasis>rcvEvents</emphasis> is
+ set to False. This prevents the reception of events. Note also
+ the use of <emphasis>userBindings=True</emphasis> and the call to
+ <emphasis>sess.bindClass</emphasis>. If <emphasis>userBindings</emphasis> is set to False
+ (its default), the session will receive object updates for all
+ classes of object. In the case above, the application is only
+ interested in broker:queue objects and reduces its bus bandwidth
+ usage by requesting updates to only that class.
+ <emphasis>bindClass</emphasis> may be called as many times as desired to add
+ classes to the list of subscribed classes.
+ </para>
+<!--h2--></section>
+
+ <section role="h2" id="QMFPythonConsoleTutorial-AsynchronousMethodCallsandMethodTimeouts"><title>
+ Asynchronous Method Calls and Method Timeouts
+ </title>
+
+ <para>
+ Method calls can also be invoked asynchronously. This is useful
+ if a large number of calls needs to be made in a short time
+ because the console application will not need to wait for the
+ complete round-trip delay for each call.
+ </para><para>
+ Method calls are synchronous by default. They can be made
+ asynchronous by adding the keyword-argument _<emphasis>async=True</emphasis>
+ to the method call.
+ </para><para>
+ In a synchronous method call, the return value is the method
+ result. When a method is called asynchronously, the return value
+ is a sequence number that can be used to correlate the eventual
+ result to the request. This sequence number is passed as an
+ argument to the <emphasis>methodResponse</emphasis> function in the
+ <emphasis>Console</emphasis> interface.
+ </para><para>
+ It is important to realize that the <emphasis>methodResponse</emphasis>
+ function may be invoked before the asynchronous call returns.
+ Make sure your code is written to handle this possibility.
+ </para>
+ <!--h2--></section>
+ <!--h1--></section>
+
+ <section role="h1" id="QMFPythonConsoleTutorial-DiscoveringwhatKindsofObjectsareAvailable"><title>
+ Discovering what Kinds of Objects are Available
+ </title>
+ <para/>
+ <!--h1--></section>
+
+
+</section>
diff --git a/qpid/doc/book/src/QMan-Qpid-Management-bridge.xml b/qpid/doc/book/src/QMan-Qpid-Management-bridge.xml
new file mode 100644
index 0000000000..f2c366dcbb
--- /dev/null
+++ b/qpid/doc/book/src/QMan-Qpid-Management-bridge.xml
@@ -0,0 +1,166 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+
+ 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.
+
+-->
+
+<section><title>
+ QMan - Qpid Management bridge
+ </title><section role="h1" id="QMan-QpidManagementbridge-QMan-3AQpidManagementBridge"><title>
+ QMan
+ : Qpid Management Bridge
+ </title>
+ <para>
+ QMan is a management bridge for Qpid. It allows external clients
+ to manage and monitor one or more Qpid brokers.
+ </para>
+ <para>
+ Please note: All WS-DM related concerns have to be considered
+ part of M5 release.
+ </para><para>
+ QMan exposes the broker management interfaces using Java
+ Management Extensions (JMX) and / or OASIS Web Services
+ Distributed Management (WSDM). While the first one is supposed to
+ be used by java based clients only the latter is an interoperable
+ protocol that enables management clients to access and receive
+ notifications of management-enabled resources using Web Services.
+ </para><para>
+ QMan can be easily integrated in your preexisting system in
+ different ways :
+ </para><itemizedlist>
+ <listitem><para>As a standalone application : in this case it runs as a
+ server. More specifically it enables communication via RMI (for
+ JMX) or via HTTP (for WS-DM); Note that when the WS-DM adapter is
+ used the JMX interface is not exposed;
+ </para></listitem>
+ <listitem><para>As a deployable unit : it is also available as a standard
+ Java web application (war); This is useful when there's a
+ preexisting Application Server in your environment and you don't
+ want start another additional server in order to run QMan.
+ </para></listitem>
+ </itemizedlist>
+
+ <section role="h2" id="QMan-QpidManagementbridge-UserDocumentation"><title>
+ User
+ Documentation
+ </title>
+ <para>
+ With "User Documentation" we mean all information that you need
+ to know in order to use QMan from a user perspective. Those
+ information include :
+ </para><table><title/><tgroup cols="2">
+ <tbody>
+ <row>
+ <entry>
+ Section
+ </entry>
+ <entry>
+ Description
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <xref linkend="qpid_Get-me-up-and-running"/>
+ </entry>
+ <entry>
+ How to install &amp; start QMan.
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <xref linkend="qpid_QMan-User-Guide"/>
+ </entry>
+ <entry>
+ QMan (WS-DM version only) Administration Console.
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <xref linkend="qpid_JMX-Interface-Specification"/>
+ </entry>
+ <entry>
+ Describes each JMX interface exposed by QMan.
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <xref linkend="qpid_WS-DM-Interface-Specification"/>
+ </entry>
+ <entry>
+ Describes each WS-DM interface exposed by QMan.
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <xref linkend="qpid_QMan-Messages-Catalogue"/>
+ </entry>
+ <entry>
+ Informational / Debug / Error / Warning messages catalogue.
+ </entry>
+ </row>
+ </tbody>
+ </tgroup></table>
+ <!--h2--></section>
+
+
+ <section role="h2" id="QMan-QpidManagementbridge-TechnicalDocumentation"><title>
+ Technical
+ Documentation
+ </title>
+ <para>
+ If you are interested in technical details about QMan and related
+ technologies this is a good starting point. In general this
+ section provides information about QMan design, interfaces,
+ patterns and so on...
+ </para>
+
+ <table><title/><tgroup cols="2">
+ <tbody>
+ <row>
+ <entry>
+ Section
+ </entry>
+ <entry>
+ Description
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <xref linkend="qpid_QMan-System-Overview"/>
+ </entry>
+ <entry>
+ A short introduction about QMan deployment context.
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <xref linkend="qpid_QMan-Components-View"/>
+ </entry>
+ <entry>
+ Describes QMan components, their interactions and
+ responsibilities.
+ </entry>
+ </row>
+ </tbody>
+ </tgroup></table>
+
+<!--h2--></section>
+<!--h1--></section>
+
+</section>
diff --git a/qpid/doc/book/src/QmfBook.xml b/qpid/doc/book/src/QmfBook.xml
new file mode 100644
index 0000000000..64a6545fb5
--- /dev/null
+++ b/qpid/doc/book/src/QmfBook.xml
@@ -0,0 +1,101 @@
+<?xml version='1.0' encoding='utf-8' ?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
+]>
+
+<!--
+
+ 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.
+
+ -->
+
+<book id="qmf-book">
+ <title>QMF - The Qpid Management Framework</title>
+ <subtitle>Object and Service-Oriented Management Leveraging the Capabilities of Qpid Messaging</subtitle>
+
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="QmfIntroduction.xml"/>
+
+ <!-- As these chapters are fleshed out, move them into separate include files for easier text management -->
+ <chapter><title>QMF Architecture</title>
+ <section><title>Components: Agents and Consoles</title>
+ </section>
+ <section><title>QMF Domains</title>
+ </section>
+ <section><title>Data: Objects, Methods, Events, and Schemata</title>
+ </section>
+ <section><title>Agent Discovery</title>
+ </section>
+ <section><title>Data Access: Queries and Subscriptions</title>
+ </section>
+ </chapter>
+
+ <chapter><title>QMF Schema Definition</title>
+ <section><title>Packages, Objects, and Events</title>
+ </section>
+ <section><title>Data Types</title>
+ </section>
+ <section><title>Programmatic Schema Definition</title>
+ </section>
+ <section><title>XML Schema Definition</title>
+ </section>
+ </chapter>
+
+ <chapter><title>How to Write an Agent</title>
+ </chapter>
+
+ <chapter><title>How to Write a Console</title>
+ </chapter>
+
+ <chapter><title>QMF Queries</title>
+ </chapter>
+
+ <chapter><title>API Reference</title>
+ <section><title>C++ API</title>
+ </section>
+ <section><title>Python API</title>
+ </section>
+ <section><title>Ruby API</title>
+ </section>
+<!--
+ <section><title>.NET API</title>
+ </section>
+ <section><title>Java API</title>
+ </section>
+-->
+ </chapter>
+
+ <chapter><title>Scale: Large QMF Networks</title>
+ </chapter>
+
+ <chapter><title>Security</title>
+ </chapter>
+
+ <chapter><title>The QMF Protocol</title>
+ <section><title>Message Headers</title>
+ </section>
+ <section><title>Addressing</title>
+ </section>
+ <section><title>Message Protocol</title>
+ </section>
+ <section><title>Message Body Details</title>
+ </section>
+ </chapter>
+
+ <chapter><title>Using QMF Messages to Manage the Qpid Broker</title>
+ </chapter>
+
+</book>
diff --git a/qpid/doc/book/src/QmfIntroduction.xml b/qpid/doc/book/src/QmfIntroduction.xml
new file mode 100644
index 0000000000..db7b8949a5
--- /dev/null
+++ b/qpid/doc/book/src/QmfIntroduction.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+
+ 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.
+
+-->
+
+<chapter>
+<title>Introduction</title>
+
+<para>
+QMF enhances Qpid Messaging by providing a layer of functionality that makes it easy to implement common management patterns
+using messaging as the basis for communication. QMF consists of three primary parts:
+</para>
+
+<itemizedlist>
+ <listitem><para>
+A protocol definition defines conventions for the use of message addresses, message headers, and structured message bodies.
+ </para></listitem>
+
+ <listitem><para>
+A core QMF engine provides a C++ API and an implementation of a set of protocol handlers for QMF message communication.
+ </para></listitem>
+
+ <listitem><para>
+Bindings are provided that wrap the C++ API for use in other languages such as Python, Ruby, and .NET.
+ </para></listitem>
+</itemizedlist>
+
+</chapter>
diff --git a/qpid/doc/book/src/Qpid-ACLs.xml b/qpid/doc/book/src/Qpid-ACLs.xml
new file mode 100644
index 0000000000..a2b64061c3
--- /dev/null
+++ b/qpid/doc/book/src/Qpid-ACLs.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0"?>
+<!--
+
+ 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.
+
+-->
+
+<section>
+ <title>Qpid ACL Formats</title>
+ <para>
+ The Qpid project has two ACL implementations currently. The java broker
+ has a simple XML configuration mechanism icluded as part of the main
+ broker configuration. The C++ broker and the latest versions of the Java
+ broker also have a new, text based ACL file format.
+ </para>
+ <bridgehead id="QpidACLs-Specifications"><anchor id="QpidACLs-Specifications" />Specifications</bridgehead>
+ <para>
+ The specifications for each of the ACL formats are linked here:
+ </para>
+ <para>
+ <xref linkend="JavaXMLACLs-specification" />
+ <xref linkend="ACL-specification" />
+ </para>
+ <bridgehead id="QpidACLs-UserGuides"><anchor id="QpidACLs-UserGuides" />User Guides</bridgehead>
+ <para>
+ To aid users in defining their ACLs we have a user guide for each
+ of the ACL formats and a page describing the security plugin mechanism in the Java broker.
+ </para>
+ <para>
+ <xref linkend="JavaXMLACLs-userguide" />
+ <xref linkend="ACL-userguide" />
+ <xref linkend="Security-Plugins-Documentation" />
+ </para>
+</section>
diff --git a/qpid/doc/book/src/Qpid-Book.xml b/qpid/doc/book/src/Qpid-Book.xml
new file mode 100644
index 0000000000..ee69532152
--- /dev/null
+++ b/qpid/doc/book/src/Qpid-Book.xml
@@ -0,0 +1,93 @@
+<?xml version='1.0' encoding='utf-8' ?>
+
+<!--
+
+ 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.
+
+-->
+
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
+]>
+
+<book>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="Book-Info.xml"/>
+ <part>
+ <title>Basics</title>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="Introduction.xml"/>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="AMQP.xml"/>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="Getting-Started.xml"/>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="Download.xml"/>
+ </part>
+
+<!--
+ The broker sections define their own <part/> elements, with <partintro/> text.
+-->
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="AMQP-Messaging-Broker-CPP.xml"/>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="AMQP-Messaging-Broker-Java.xml"/>
+
+ <part>
+ <title>AMQP Messaging Clients Clients</title>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="AMQP-Java-JMS-Messaging-Client.xml"/>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="AMQP-C++-Messaging-Client.xml"/>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="AMQP-.NET-Messaging-Client.xml"/>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="AMQP-Python-Messaging-Client.xml"/>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="AMQP-Ruby-Messaging-Client.xml"/>
+
+ </part>
+ <part>
+ <title>Appendices</title>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="AMQP-Compatibility.xml"/>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="Qpid-Interoperability-Documentation.xml"/>
+<!-- <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="FAQ.xml"/> -->
+ </part>
+</book>
+
+<!--
+Documentation
+Getting Started
+
+ * Download
+ * Getting Started
+
+AMQP (Advanced Message Queueing Protocol)
+
+ * Toward a Commodity Enterprise Middleware
+ * AMQP (Advanced Message Queueing Protocol)
+
+Qpid AMQP Brokers
+
+ * AMQP Messaging Broker (implemented in C++)
+ * AMQP Messaging Broker (implemented in Java)
+
+Qpid AMQP Clients
+
+ * AMQP Java JMS Messaging Client
+ * AMQP C++ Messaging Client
+ * AMQP .NET Messaging Client
+ * AMQP Python Messaging Client
+ * AMQP Ruby Messaging Client
+
+Interoperability
+
+ * AMQP Compatibility
+ * SASL Interoperability
+
+FAQ
+
+ * Frequently Asked Questions
+-->
diff --git a/qpid/doc/book/src/Qpid-Compatibility-And-Interoperability-Book.xml b/qpid/doc/book/src/Qpid-Compatibility-And-Interoperability-Book.xml
new file mode 100644
index 0000000000..f382f390c7
--- /dev/null
+++ b/qpid/doc/book/src/Qpid-Compatibility-And-Interoperability-Book.xml
@@ -0,0 +1,36 @@
+<?xml version='1.0' encoding='utf-8' ?>
+
+<!--
+
+ 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.
+
+-->
+
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
+]>
+
+<book>
+ <chapter>
+ <title>AMQP Compatibility</title>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="AMQP-Compatibility.xml"/>
+ </chapter>
+ <chapter>
+ <title>Qpid Interoperability Documentation</title>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="Qpid-Interoperability-Documentation.xml"/>
+ </chapter>
+</book>
diff --git a/qpid/doc/book/src/Qpid-Interoperability-Documentation.xml b/qpid/doc/book/src/Qpid-Interoperability-Documentation.xml
new file mode 100644
index 0000000000..74546693df
--- /dev/null
+++ b/qpid/doc/book/src/Qpid-Interoperability-Documentation.xml
@@ -0,0 +1,377 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+
+ 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.
+
+-->
+
+<section role="h2" id="QpidInteroperabilityDocumentation-QpidInteroperabilityDocumentation">
+ <title>Qpid Interoperability Documentation</title>
+
+ <para>
+ This page documents the various interoperable features of the
+ Qpid clients.
+ </para>
+ <section role="h3" id="QpidInteroperabilityDocumentation-SASL"><title>
+ SASL
+ </title>
+
+ <para>
+
+ </para>
+ <section role="h4" id="QpidInteroperabilityDocumentation-StandardMechanisms"><title>
+ Standard
+ Mechanisms
+ </title>
+
+ <para>
+ <ulink url="http://en.wikipedia.org/wiki/Simple_Authentication_and_Security_Layer#SASL_mechanisms"/>
+ </para><para>
+ This table list the various SASL mechanisms that each component
+ supports. The version listed shows when this
+ functionality was added to the product.
+ </para><table><title>SASL Mechanism Support</title><tgroup cols="7">
+ <tbody>
+ <row>
+ <entry>
+ Component
+ </entry>
+ <entry>
+ ANONYMOUS
+ </entry>
+ <entry>
+ CRAM-MD5
+ </entry>
+ <entry>
+ DIGEST-MD5
+ </entry>
+ <entry>
+ EXTERNAL
+ </entry>
+ <entry>
+ GSSAPI/Kerberos
+ </entry>
+ <entry>
+ PLAIN
+ </entry>
+ </row>
+ <row>
+ <entry>
+ C++ Broker
+ </entry>
+ <entry>
+ M3[<xref linkend="QpidInteroperabilityDocumentation-1"/>]
+ </entry>
+ <entry>
+ M3[<xref linkend="QpidInteroperabilityDocumentation-1"/>,<xref linkend="QpidInteroperabilityDocumentation-2"/>]
+ </entry>
+ <entry>
+  
+ </entry>
+ <entry>
+  
+ </entry>
+ <entry>
+ M3[<xref linkend="QpidInteroperabilityDocumentation-1"/>,<xref linkend="QpidInteroperabilityDocumentation-2"/>]
+ </entry>
+ <entry>
+ M1
+ </entry>
+ </row>
+ <row>
+ <entry>
+ C++ Client
+ </entry>
+ <entry>
+ M3[<xref linkend="QpidInteroperabilityDocumentation-1"/>]
+ </entry>
+ <entry>
+  
+ </entry>
+ <entry>
+  
+ </entry>
+ <entry>
+  
+ </entry>
+ <entry>
+  
+ </entry>
+ <entry>
+ M1
+ </entry>
+ </row>
+ <row>
+ <entry>
+ Java Broker
+ </entry>
+ <entry>
+  
+ </entry>
+ <entry>
+ M1
+ </entry>
+ <entry>
+  
+ </entry>
+ <entry>
+  
+ </entry>
+ <entry>
+  
+ </entry>
+ <entry>
+ M1
+ </entry>
+ </row>
+ <row>
+ <entry>
+ Java Client
+ </entry>
+ <entry>
+  
+ </entry>
+ <entry>
+ M1
+ </entry>
+ <entry>
+  
+ </entry>
+ <entry>
+  
+ </entry>
+ <entry>
+  
+ </entry>
+ <entry>
+ M1
+ </entry>
+ </row>
+ <row>
+ <entry>
+ .Net Client
+ </entry>
+ <entry>
+ M2
+ </entry>
+ <entry>
+ M2
+ </entry>
+ <entry>
+ M2
+ </entry>
+ <entry>
+ M2
+ </entry>
+ <entry>
+  
+ </entry>
+ <entry>
+ M2
+ </entry>
+ </row>
+ <row>
+ <entry>
+ Python Client
+ </entry>
+ <entry>
+  
+ </entry>
+ <entry>
+  
+ </entry>
+ <entry>
+  
+ </entry>
+ <entry>
+  
+ </entry>
+ <entry>
+  
+ </entry>
+ <entry>
+ ?
+ </entry>
+ </row>
+ <row>
+ <entry>
+ Ruby Client
+ </entry>
+ <entry>
+  
+ </entry>
+ <entry>
+  
+ </entry>
+ <entry>
+  
+ </entry>
+ <entry>
+  
+ </entry>
+ <entry>
+  
+ </entry>
+ <entry>
+ ?
+ </entry>
+ </row>
+ </tbody>
+ </tgroup></table>
+
+ <para id="QpidInteroperabilityDocumentation-1">
+ 1: Support for these will be in M3 (currently available on
+ trunk).
+ </para>
+
+ <para id="QpidInteroperabilityDocumentation-2">2: C++ Broker uses <ulink url="http://freshmeat.net/projects/cyrussasl/">Cyrus SASL</ulink> which
+ supports CRAM-MD5 and GSSAPI but these have not been tested yet
+ </para>
+<!--h4--></section>
+
+ <section role="h4" id="QpidInteroperabilityDocumentation-CustomMechanisms"><title>
+ Custom
+ Mechanisms
+ </title>
+
+ <para>
+ There have been some custom mechanisms added to our
+ implementations.
+ </para><table><title>SASL Custom Mechanisms</title><tgroup cols="3">
+ <tbody>
+ <row>
+ <entry>
+ Component
+ </entry>
+ <entry>
+ AMQPLAIN
+ </entry>
+ <entry>
+ CRAM-MD5-HASHED
+ </entry>
+ </row>
+ <row>
+ <entry>
+ C++ Broker
+ </entry>
+ <entry>
+  
+ </entry>
+ <entry>
+  
+ </entry>
+ </row>
+ <row>
+ <entry>
+ C++ Client
+ </entry>
+ <entry>
+  
+ </entry>
+ <entry>
+  
+ </entry>
+ </row>
+ <row>
+ <entry>
+ Java Broker
+ </entry>
+ <entry>
+ M1
+ </entry>
+ <entry>
+ M2
+ </entry>
+ </row>
+ <row>
+ <entry>
+ Java Client
+ </entry>
+ <entry>
+ M1
+ </entry>
+ <entry>
+ M2
+ </entry>
+ </row>
+ <row>
+ <entry>
+ .Net Client
+ </entry>
+ <entry>
+  
+ </entry>
+ <entry>
+  
+ </entry>
+ </row>
+ <row>
+ <entry>
+ Python Client
+ </entry>
+ <entry>
+ M2
+ </entry>
+ <entry>
+  
+ </entry>
+ </row>
+ <row>
+ <entry>
+ Ruby Client
+ </entry>
+ <entry>
+ M2
+ </entry>
+ <entry>
+  
+ </entry>
+ </row>
+ </tbody>
+ </tgroup></table>
+
+ <section><title>AMQPLAIN</title>
+ <para/>
+ </section>
+
+ <section><title>CRAM-MD5-HASHED</title>
+ <para>
+ The Java SASL implementations require that you have the password
+ of the user to validate the incoming request. This then means
+ that the user's password must be stored on disk. For this to be
+ secure either the broker must encrypt the password file or the
+ need for the password being stored must be removed.
+ </para><para>
+ The CRAM-MD5-HASHED SASL plugin removes the need for the plain
+ text password to be stored on disk. The mechanism defers all
+ functionality to the build in CRAM-MD5 module the only change is
+ on the client side where it generates the hash of the password
+ and uses that value as the password. This means that the Java
+ Broker only need store the password hash on the file system.
+ While a one way hash is not very secure compared to other forms
+ of encryption in environments where the having the password in
+ plain text is unacceptable this will provide and additional layer
+ to protect the password. In particular this offers some
+ protection where the same password may be shared amongst many
+ systems. It offers no real extra protection against attacks on
+ the broker (the secret is now the hash rather than the password).
+ </para>
+ </section>
+<!--h4--></section>
+<!--h3--></section>
+<!--h2--></section>
diff --git a/qpid/doc/book/src/Qpid-JMX-Management-Console-FAQ.xml b/qpid/doc/book/src/Qpid-JMX-Management-Console-FAQ.xml
new file mode 100644
index 0000000000..1806ab01b1
--- /dev/null
+++ b/qpid/doc/book/src/Qpid-JMX-Management-Console-FAQ.xml
@@ -0,0 +1,96 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+
+ 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.
+
+-->
+
+<section><title>
+ Qpid JMX Management Console FAQ
+ </title>
+<!--
+h3. {toggle-cloak:id=qManagementConsoleSecurity} How do I connect the management console to my broker using security ?
+{cloak:id=qManagementConsoleSecurity}
+
+The [Management Console Security] page will give you the instructions that you should use to set this up.
+{cloak}
+
+
+h3. {toggle-cloak:id=rmiServerHostname} I am unable to connect Qpid JMX MC/JConsole to a remote broker running on Linux, but connecting to localhost on that machine works ?
+{cloak:id=rmiServerHostname}
+
+The RMI based JMX ConnectorServer used by the broker requries two ports to operate. The console connects to an RMI Registry running on the primary (default 8999) port and retrieves the information actually needed to connect to the JMX Server. This information embeds the hostname of the remote machine, and if this is incorrect or unreachable by the connecting client the connection will fail.
+
+This situation arises due to the hostname configuration on Linux and is generally encountered when the remote machine does not have a DNS hostname entry on the local network, causing the hostname command to return a loopback IP instead of a fully qualified domain name or IP address accessible by remote client machines. It is described in further detail at: http://java.sun.com/javase/6/docs/technotes/guides/management/faq.html#linux1
+
+To remedy this issue you can set the _java.rmi.server.hostname_ system property to control the hostname/ip reported to the RMI runtime when advertising the JMX ConnectorServer. This can also be used to dictate the address returned on a computer with multiple network interfaces to control reachability. To do so, add the value _-Djava.rmi.server.hostname=<desired hostname/ip>_ to the QPID_OPTS environment variable before starting the _qpid-server_ script.
+-->
+
+ <section role="h2" id="QpidJMXManagementConsoleFAQ-Errors"><title>
+ Errors
+ </title>
+
+ <section role="h3" id="QpidJMXManagementConsoleFAQ-HowdoIconnectthemanagementconsoletomybrokerusingsecurity-3F"><title>
+ How do I connect the management console to
+ my broker using security ?
+ </title>
+
+ <para>
+ The <xref linkend="qpid_Management-Console-Security"/> page will give you the instructions that you should
+ use to set this up.
+ </para>
+<!--h3--></section>
+
+ <section role="h3" id="QpidJMXManagementConsoleFAQ-IamunabletoconnectQpidJMXMC-2FJConsoletoaremotebrokerrunningonLinux-2Cbutconnectingtolocalhostonthatmachineworks-3F"><title>
+ I am unable to connect Qpid JMX MC/JConsole
+ to a remote broker running on Linux, but connecting to localhost
+ on that machine works ?
+ </title>
+
+ <para>
+ The RMI
+ based JMX ConnectorServer used by the broker requries two ports
+ to operate. The console connects to an RMI Registry running on
+ the primary (default 8999) port and retrieves the information
+ actually needed to connect to the JMX Server. This information
+ embeds the hostname of the remote machine, and if this is
+ incorrect or unreachable by the connecting client the connection
+ will fail.
+ </para><para>
+ This
+ situation arises due to the hostname configuration on Linux and
+ is generally encountered when the remote machine does not have a
+ DNS hostname entry on the local network, causing the hostname
+ command to return a loopback IP instead of a fully qualified
+ domain name or IP address accessible by remote client machines.
+ It is described in further detail at: <xref linkend="qpid_faq"/>
+ </para><para>
+ To
+ remedy this issue you can set the
+ <emphasis>java.rmi.server.hostname</emphasis> system property to control the
+ hostname/ip reported to the RMI runtime when advertising the JMX
+ ConnectorServer. This can also be used to dictate the address
+ returned on a computer with multiple network interfaces to
+ control reachability. To do so, add the value
+ <emphasis>-Djava.rmi.server.hostname=&lt;desired hostname/ip&gt;</emphasis>
+ to the QPID_OPTS environment variable before starting the
+ <emphasis>qpid-server</emphasis> script.
+ </para>
+<!--h3--></section>
+<!--h2--></section>
+</section>
diff --git a/qpid/doc/book/src/Qpid-JMX-Management-Console-User-Guide.xml b/qpid/doc/book/src/Qpid-JMX-Management-Console-User-Guide.xml
new file mode 100644
index 0000000000..55e1f8e829
--- /dev/null
+++ b/qpid/doc/book/src/Qpid-JMX-Management-Console-User-Guide.xml
@@ -0,0 +1,793 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+
+ 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.
+
+-->
+
+<section id="Qpid-JMX-Management-Console-User-Guide"><title>
+ Qpid JMX Management Console User Guide
+ </title><section role="h1" id="QpidJMXManagementConsoleUserGuide-QpidJMXManagementConsoleUserGuide"><title>
+ Qpid JMX Management Console User Guide
+ </title>
+
+
+ <para>
+
+ The Qpid JMX Management Console is a standalone Eclipse RCP
+ application for managing and monitoring the Qpid Java server
+ utilising its JMX management interfaces.
+ </para><para>
+ This guide will give an overview of configuring the console, the
+ features supported by it, and how to make use of the console in
+ managing the various JMX Management Beans (MBeans) offered by the
+ Qpid Java server.
+ </para>
+<!--h1--></section>
+
+
+ <section role="h1" id="QpidJMXManagementConsoleUserGuide-Startup-26Configuration"><title>
+
+ Startup &amp; Configuration
+ </title>
+
+ <para>
+
+ </para>
+ <section role="h2" id="QpidJMXManagementConsoleUserGuide-Startup"><title>
+ Startup
+ </title>
+
+ <para>
+
+ The console can be started in the following way, depending on
+ platform:
+ </para><itemizedlist>
+ <listitem><para>
+ <emphasis>Windows:</emphasis> by running the <emphasis>qpidmc.exe</emphasis> executable
+ file.
+ </para></listitem>
+ <listitem><para>
+ <emphasis>Linux:</emphasis> by running the <emphasis>qpidmc</emphasis> executable.
+ </para></listitem>
+ <listitem><para>
+ <emphasis>Mac OS X:</emphasis> by launching the <emphasis>Qpid Management
+ Console.app</emphasis> application bundle.
+ </para></listitem>
+ </itemizedlist><para>
+
+ </para>
+ </section>
+
+
+ <section role="h2" id="QpidJMXManagementConsoleUserGuide-SSLconfiguration"><title>
+ SSL
+ configuration
+ </title>
+
+ <para>
+
+ Newer Qpid Java servers can protect their JMX connections with
+ SSL, and this is enabled by default. When attempting to connect
+ to a server with this enabled, the console must be able to verify
+ the SSL certificate presented to it by the server or the
+ connection will fail.
+ </para><para>
+ If the server makes use of an SSL certificate signed by a known
+ Signing CA (Certification Authority) then the console needs no
+ extra configuration, and will make use of Java's default
+ system-wide CA TrustStore for certificate verification (you may
+ however have to update the system-wide default CA TrustStore if
+ your certified is signed by a less common CA that is not already
+ present in it).
+ </para><para>
+ If however the server is equipped with a self-signed SSL
+ certificate, then the management console must be provided with an
+ appropriate SSL TrustStore containing the public key for the SSL
+ certificate, so that it is able to validate it when presented by
+ the server. The server ships with a script to create an example
+ self-signed SSL certificate, and store the relevant entries in a
+ KeyStore and matching TrustStore. This script can serve as a
+ guide on how to use the Java Keytool security utility to
+ manipulate your own stores, and more information can be found in
+ the JSSE Reference Guide:
+ <ulink url="http://java.sun.com/javase/6/docs/technotes/guides/security/jsse/JSSERefGuide.html#CustomizingStores">http://java.sun.com/javase/6/docs/technotes/guides/security/jsse/JSSERefGuide.html#CustomizingStores</ulink>.
+ </para><para>
+ Supplying the necessary details to the console is performed by
+ setting the <emphasis>javax.net.ssl.trustStore</emphasis> and
+ <emphasis>javax.net.ssl.trustStorePassword</emphasis> environment variables
+ when starting it. This can be done at the command line, but the
+ preferred option is to set the configuration within the
+ <emphasis>qpidmc.ini</emphasis> launcher configuration file for repeated
+ usage. This file is equipped with a template to ease
+ configuration, this should be uncommented and edited to suit your
+ needs. It can be found in the root of the console releases for
+ Windows, and Linux. For Mac OS X the file is located within the
+ consoles <emphasis>.app</emphasis> application bundle, and to locate and edit
+ it you must select <emphasis>'Show Package Contents'</emphasis> when
+ accessing the context menu of the application, then browse to the
+ <emphasis>Contents/MacOS</emphasis> sub folder to locate the file.
+ </para>
+<!--h2--></section>
+
+ <section role="h2" id="QpidJMXManagementConsoleUserGuide-JMXMPconfiguration"><title>
+ JMXMP
+ configuration
+ </title>
+
+ <para>
+
+ Older releases of the Qpid Java server can make use of the Java
+ Management Extensions Messaging Protocol (JMXMP) to provide
+ protection for their JMX connections. This occurs when the server
+ has its main configuration set with the management
+ <emphasis>'security-enabled'</emphasis> property set to true.
+ </para><para>
+ In order to connect to this configuration of server, the console
+ needs an additional library that is not included within the Java
+ SE platform and cannot be distributed with the console due to
+ licensing restrictions.
+ </para><para>
+ You can download the JMX Remote API 1.0.1_04 Reference
+ Implementation from the Sun website <xref linkend="qpid_download.jsp"/>. The included
+ <emphasis>jmxremote-1_0_1-bin/lib/jmxremote_optional.jar</emphasis> file must
+ be added to the <emphasis>plugins/jmxremote.sasl_1.0.1</emphasis> folder of
+ the console release (again, in Mac OS X you will need to select
+ <emphasis>'Show package contents'</emphasis> from the context menu whilst
+ selecting the management console bundle in order to reveal the
+ inner file tree).
+ </para><para>
+ Following this the console will automatically load the JMX Remote
+ Optional classes and negotiate the SASL authentication profile
+ type when encountering a JMXMP enabled Qpid Java server.
+ </para>
+<!--h2--></section>
+<!--h1--></section>
+ <section role="h1" id="QpidJMXManagementConsoleUserGuide-ManagingServerConnections"><title>
+
+ Managing Server Connections
+ </title>
+
+ <para>
+
+ </para>
+ <section role="h2" id="QpidJMXManagementConsoleUserGuide-MainToolbar"><title>
+ Main Toolbar
+ </title>
+
+ <para>
+
+ The main toolbar of the console can be seen in the image below.
+ The left most buttons respectively allow for adding a new server
+ connection, reconnecting to an existing server selected in the
+ connection tree, disconnecting the selected server connection,
+ and removing the server from the connection tree.
+ </para><para>
+ <mediaobject><imageobject><imagedata fileref="images/jmx_console/3113098.png" format="PNG" scalefit="1"/></imageobject><textobject><phrase/></textobject><caption><para/></caption></mediaobject>
+
+
+ Beside these buttons is a combo for selecting the refresh
+ interval; that is, how often the console requests updated
+ information to display for the currently open area in the main
+ view. Finally, the right-most button enables an immediate update.
+ </para>
+ </section>
+
+ <section role="h2" id="QpidJMXManagementConsoleUserGuide-Connectingtoanewserver"><title>
+ Connecting
+ to a new server
+ </title>
+
+ <para>
+
+ To connect to a new server, press the <emphasis>Add New Server</emphasis>
+ toolbar button, or select the <emphasis>Qpid Manager -&gt; Add New
+ Connection</emphasis> menu item. At this point a dialog box will be
+ displayed requesting the server details, namely the server
+ hostname, management port, and a username and password. An
+ example is shown below:
+ </para><para>
+ <mediaobject><imageobject><imagedata fileref="images/jmx_console/3113099.png" format="PNG" scalefit="1"/></imageobject><textobject><phrase/></textobject><caption><para/></caption></mediaobject>
+ </para><para>
+
+ Once all the required details are entered, pressing Connect will
+ initiate a connection attempt to the server. It the attempt fails
+ a reason will be shown and the server will not be added to the
+ connection tree. If the attempt is successful the server will be
+ added to the connections list and the entry expanded to show the
+ initial administration MBeans the user has access to and any
+ VirtualHosts present on the server, as can be seen in the figure
+ below.
+ </para><para>
+ <mediaobject><imageobject><imagedata fileref="images/jmx_console/3113100.png" format="PNG" scalefit="1"/></imageobject><textobject><phrase/></textobject><caption><para/></caption></mediaobject>
+ </para><para>
+
+ If the server supports a newer management API than the console in
+ use, once connected this initial screen will contain a message on
+ the right, indicating an upgraded console should be sought by the
+ user to ensure all management functionality supported by the
+ server is being utilised.
+ </para>
+<!--h2--></section>
+
+ <section role="h2" id="QpidJMXManagementConsoleUserGuide-Reconnectingtoaserver"><title>
+ Reconnecting
+ to a server
+ </title>
+
+ <para>
+
+ If a server has been connected to previously, it will be saved as
+ an entry in the connection tree for further use. On subsequent
+ connections the server can simply be selected from the tree and
+ using the <emphasis>Reconnect</emphasis> toolbar button or <emphasis>Qpid Manager
+ -&gt; Reconnect</emphasis> menu item. At this stage the console will
+ prompt simply for the username and password with which the user
+ wishes to connect, and following a successful connection the
+ screen will appear as shown previously above.
+ </para>
+<!--h2--></section>
+
+
+ <section role="h2" id="QpidJMXManagementConsoleUserGuide-Disconnectingfromaserver"><title>
+ Disconnecting
+ from a server
+ </title>
+
+ <para>
+
+ To disconnect from a server, select the connection tree node for
+ the server and press the <emphasis>Disconnect</emphasis> toolbar button, or
+ use the <emphasis>Qpid Manager -&gt; Disconnect</emphasis> menu option.
+ </para>
+<!--h2--></section>
+
+ <section role="h2" id="QpidJMXManagementConsoleUserGuide-Removingaserver"><title>
+ Removing a
+ server
+ </title>
+
+ <para>
+
+ To remove a server from the connection list, select the
+ connection tree node for the server and press the <emphasis>Remove</emphasis>
+ toolbar button, or use the <emphasis>Qpid Manager -&gt; Remove
+ Connection</emphasis> menu option.
+ </para>
+<!--h2--></section>
+<!--h1--></section>
+
+
+ <section role="h1" id="QpidJMXManagementConsoleUserGuide-Navigatingaconnectedserver"><title>
+ Navigating a connected server
+ </title>
+
+ <para>
+
+ Once connected to a server, the various areas available for
+ administration are accessed using the Qpid Connections tree at
+ the left side of the application. To open a particular MBean from
+ the tree for viewing, simply select it in the tree and it will be
+ opened in the main view.
+ <mediaobject><imageobject><imagedata fileref="images/jmx_console/3113101.png" format="PNG" scalefit="1"/></imageobject><textobject><phrase/></textobject><caption><para/></caption></mediaobject>
+ </para><para>
+ As there may be vast numbers of Queues, Connections, and
+ Exchanges on the server these MBeans are not automatically added
+ to the tree along with the general administration MBeans.
+ Instead, dedicated selection areas are provided to allow users to
+ select which Queue/Connection/Exchange they wish to view or add
+ to the tree. These areas can be found by clicking on the
+ Connections, Exchanges, and Queues nodes in the tree under each
+ VirtualHost, as shown in the figure above. One or more MBeans may
+ be selected and added to the tree as Favourites using the button
+ provided. These settings are saved for future use, and each time
+ the console connects to the server it will check for the presence
+ of the MBean previously in the tree and add them if they are
+ still present. Queue/Connection/Exchange MBeans can be removed
+ from the tree by right clicking on them to expose a context menu
+ allowing deletion.
+ </para><para>
+ <mediaobject><imageobject><imagedata fileref="images/jmx_console/3113102.png" format="PNG" scalefit="1"/></imageobject><textobject><phrase/></textobject><caption><para/></caption></mediaobject>
+ </para><para>
+ As an alternative way to open a particular MBean for viewing,
+ without first adding it to the tree, you can simply double click
+ an entry in the table within the Queue/Connection/Exchange
+ selection areas to open it immediately. It is also possible to
+ open some MBeans like this whilst viewing certain other MBeans.
+ When opening an MBean in either of these ways, a Back button is
+ enabled in the top right corner of the main view. Using this
+ button will return you to the selection area or MBean you were
+ previously viewing. The history resets each time the tree is used
+ to open a new area or MBean.
+ </para>
+<!--h1--></section>
+
+
+ <section role="h1" id="QpidJMXManagementConsoleUserGuide-ConfigurationManagementMBean"><title>
+
+ ConfigurationManagement MBean
+ </title>
+
+ <para>
+
+ The ConfigurationManagement MBean is available on newer servers,
+ to users with admin level management rights. It offers the
+ ability to perform a live reload of the <emphasis>Security</emphasis>
+ sections defined in the main server configuration file (e.g.
+ defaults to: <emphasis>etc/config.xml</emphasis>). This is mainly to allow
+ updating the server Firewall configuration to new settings
+ without a restart, and can be performed by clicking the Execute
+ button and confirming the prompt which follows.
+ </para><para>
+ <mediaobject><imageobject><imagedata fileref="images/jmx_console/3113103.png" format="PNG" scalefit="1"/></imageobject><textobject><phrase/></textobject><caption><para/></caption></mediaobject>
+ </para>
+<!--h1--></section>
+
+ <section role="h1" id="QpidJMXManagementConsoleUserGuide-LoggingManagementMBean"><title>
+
+ LoggingManagement MBean
+ </title>
+
+ <para>
+
+ The LoggingManagement MBean is available on newer servers, and
+ accessible by admin level users. It allows live alteration of the
+ logging behaviour, both at a Runtime-only level and at the
+ configuration file level. The latter can optionally affect the
+ Runtime configuration, either through use of the servers
+ automated LogWatch ability which detects changes to the
+ configuration file and reloads it, or by manually requesting a
+ reload. This functionality is split across two management tabs,
+ Runtime Options and ConfigurationFile Options.
+ </para>
+ <section role="h2" id="QpidJMXManagementConsoleUserGuide-RuntimeOptions"><title>
+ Runtime
+ Options
+ </title>
+
+ <para>
+
+ <mediaobject><imageobject><imagedata fileref="images/jmx_console/3113104.png" format="PNG" scalefit="1"/></imageobject><textobject><phrase/></textobject><caption><para/></caption></mediaobject>
+ </para><para>
+ The Runtime Options tab allows manipulation of the logging
+ settings without affecting the configuration files (this means
+ the changes will be lost when the server restarts), and gives
+ individual access to every Logger active within the server.
+ </para><para>
+ As shown in the figure above, the table in this tab presents the
+ Effective Level of each Logger. This is because the Loggers form
+ a hierarchy in which those without an explicitly defined (in the
+ logging configuration file) Level will inherit the Level of their
+ immediate parent; that is, the Logger whose full name is a prefix
+ of their own, or if none satisfy that condition then the
+ RootLogger is their parent. As example, take the
+ <emphasis>org.apache.qpid</emphasis> Logger. It is parent to all those below
+ it which begin with <emphasis>org.apache.qpid</emphasis> and unless they have
+ a specific Level of their own, they will inherit its Level. This
+ can be seen in the figure, whereby all the children Loggers
+ visible have a level of WARN just like their parent, but the
+ RootLogger Level is INFO; the children have inherited the WARN
+ level from <emphasis>org.apache.qpid</emphasis> rather than INFO from the
+ RootLogger.
+ </para><para>
+ To aid with this distinction, the Logger Levels that are
+ currently defined in the configuration file are highlighted in
+ the List. Changing these levels at runtime will also change the
+ Level of all their children which haven't been set their own
+ Level using the runtime options. In the latest versions of the
+ LoggingManagement MBean, it is possible to restore a child logger
+ that has had an explicit level se, to inheriting that of its
+ parent by setting it to an INHERITED level that removes any
+ previously set Level of its own.
+ </para><para>
+ <mediaobject><imageobject><imagedata fileref="images/jmx_console/3113105.png" format="PNG" scalefit="1"/></imageobject><textobject><phrase/></textobject><caption><para/></caption></mediaobject>
+ </para><para>
+ In order to set one of more Loggers to a new Level, they should
+ be selected in the table (or double click an individual Logger to
+ modify it) and the <emphasis>Edit Selected Logger(s)</emphasis> button
+ pressed to load the dialog shown above. At this point, any of the
+ available Levels supported by the server can be applied to the
+ Loggers selected and they will immediately update, as will any
+ child Loggers without their own specific Level.
+ </para><para>
+ The RootLogger can be similarly edited using the button at the
+ bottom left of the window.
+ </para>
+<!--h2--></section>
+
+ <section role="h2" id="QpidJMXManagementConsoleUserGuide-ConfigurationFileOptions"><title>
+ ConfigurationFile
+ Options
+ </title>
+
+ <para>
+
+ The ConfigurationFile Options tab allows alteration of the Level
+ settings for the Loggers defined in the configuration file,
+ allowing changes to persist following a restart of the server.
+ Changes made to the configuration file are only applied
+ automatically while the sever is running if it was configured to
+ enable the LogWatch capability, meaning it will monitor the
+ configuration file for changes and apply the new configuration
+ when the change is detected. If this was not enabled, the changes
+ will be picked up when the server is restarted. The status of the
+ LogWatch feature is shown at the bottom of the tab.
+ Alternatively, in the latest versions of the LoggingManagement
+ MBean it is possible to reload the logging configuration file on
+ demand.
+ </para><para>
+ Manipulating the Levels is as on the Runtime Options tab, either
+ double-click an individual Logger entry or select multiple
+ Loggers and use the button to load the dialog to set the new
+ Level.
+ </para><para>
+ <mediaobject><imageobject><imagedata fileref="images/jmx_console/3113106.png" format="PNG" scalefit="1"/></imageobject><textobject><phrase/></textobject><caption><para/></caption></mediaobject>
+ </para><para>
+ One issue to note of when reloading the configuration file
+ settings, either automatically using LogWatch or manually, is
+ that any Logger set to a specific Level using the Runtime Options
+ tab that is not defined in the configuration file will maintain
+ that Level when the configuration file is reloaded. In other
+ words, if a Logger is defined in the configuration file, then the
+ configuration file will take precedence at reload, otherwise the
+ Runtime options take precedence.
+ </para><para>
+ This situation will be immediately obvious by examining the
+ Runtime Options tab to see the effective Level of each Logger
+ – unless it has been altered with the RuntimeOptions or
+ specifically set in the configuration file, a Logger Level should
+ match that of its parent. In the latest versions of the
+ LoggingManagement MBean, it is possible to use the RuntimeOptions
+ to restore a child logger to inheriting from its parent by
+ setting it with an INHERITED level that removes any previously
+ set Level of its own.
+
+ </para>
+<!--h2--></section>
+<!--h1--></section>
+
+
+
+ <section role="h1" id="QpidJMXManagementConsoleUserGuide-ServerInformationMBean"><title>
+ ServerInformation MBean
+ </title>
+
+ <para>
+
+ <mediaobject><imageobject><imagedata fileref="images/jmx_console/3113107.png" format="PNG" scalefit="1"/></imageobject><textobject><phrase/></textobject><caption><para/></caption></mediaobject>
+ </para><para>
+ The ServerInformation MBean currently only conveys various pieces
+ of version information to allow precise identification of the
+ server version and its management capabilities. In future it is
+ likely to convey additional server-wide details and/or
+ functionality.
+ </para>
+<!--h1--></section>
+
+ <section role="h1" id="QpidJMXManagementConsoleUserGuide-UserManagementMBean"><title>
+
+ UserManagement MBean
+ </title>
+
+ <para>
+
+ The UserManagement MBean is accessible by admin level users, and
+ allows manipulation of existing user accounts and creation of new
+ user accounts.
+ </para><para>
+ <mediaobject><imageobject><imagedata fileref="images/jmx_console/3113108.png" format="PNG" scalefit="1"/></imageobject><textobject><phrase/></textobject><caption><para/></caption></mediaobject>
+ </para><para>
+
+ To add a new user, press the <emphasis>Add New User</emphasis> button, which
+ will load the dialog shown below.
+ </para><para>
+ <mediaobject><imageobject><imagedata fileref="images/jmx_console/3113109.png" format="PNG" scalefit="1"/></imageobject><textobject><phrase/></textobject><caption><para/></caption></mediaobject>
+ </para><para>
+ Here you may enter the new users Username, Password, and select
+ their JMX Management Rights. This controls whether or not they
+ have access to the management interface, and if so what
+ capabilities are accessible. <emphasis>Read Only</emphasis> access allows
+ undertaking any operations that do not alter the server state,
+ such as viewing messages. <emphasis>Read + Write</emphasis> access allows use
+ of all operations which are not deemed admin-only (such as those
+ in the UserManagement MBean itself). <emphasis>Admin</emphasis> access allows
+ a user to utilize any operation, and view the admin-only MBeans
+ (currently these are ConfigurationManagement, LoggingManagement,
+ and UserManagement).
+ </para><para>
+ One or more users at a time may be deleted by selecting them in
+ the table and clicking the <emphasis>Delete User(s)</emphasis> button. The
+ console will then prompt for confirmation before undertaking the
+ removals. Similarly, the access rights for one or more users may
+ be updated by selecting them in the table and clicking the
+ <emphasis>Set Rights</emphasis> button. The console will then display a
+ dialog enabling selection of the new access level and
+ confirmation to undertake the update.
+ </para><para>
+ An individual user password may be updated by selecting the user
+ in the table in and clicking the <emphasis>Set Password</emphasis> button.
+ The console will then display a dialog enabling input of the new
+ password and confirmation to undertake the update.
+ </para><para>
+
+ The server caches the user details in memory to aid performance.
+ If may sometimes be necessary to externally modify the password
+ and access right files on disk. In order for these changes to be
+ known to the server without a restart, it must be instructed to
+ reload the file contents. This can be done using the provided
+ <emphasis>Reload User Details</emphasis> button (on older servers, only the
+ management rights file is reloaded, on newer servers both files
+ are. The description on screen will indicate the behaviour).
+ After pressing this button the console will seek confirmation
+ before proceeding.
+ </para>
+<!--h1--></section>
+
+
+ <section role="h1" id="QpidJMXManagementConsoleUserGuide-VirtualHostManagerMBean"><title>
+
+ VirtualHostManager MBean
+ </title>
+
+ <para>
+
+ Each VirtualHost in the server has an associated
+ VirtualHostManager MBean. This allows viewing, creation, and
+ deletion of Queues and Exchanges within the VirtualHost.
+ </para><para>
+ Clicking the <emphasis>Create</emphasis> button in the Queue section will
+ open a dialog allowing specification of the Name, Owner
+ (optional), and durability properties of the new Queue, and
+ confirmation of the operation.
+ </para><para>
+ One or more Queues may be deleted by selecting them in the table
+ and clicking the <emphasis>Delete</emphasis> button. This will unregister the
+ Queue bindings, remove the subscriptions and delete the Queue(s).
+ The console will prompt for confirmation before undertaking the
+ operation.
+ </para><para>
+ <mediaobject><imageobject><imagedata fileref="images/jmx_console/3113110.png" format="PNG" scalefit="1"/></imageobject><textobject><phrase/></textobject><caption><para/></caption></mediaobject>
+ </para><para>
+ Clicking the <emphasis>Create</emphasis> button in the Exchange section will
+ open a dialog allowing specification of the Name, Type, and
+ Durable attributes of the new Exchange, and confirmation of the
+ operation.
+ </para><para>
+ One or more Exchanges may be deleted by selecting them in the
+ table and clicking the <emphasis>Delete</emphasis> button. This will
+ unregister all the related channels and Queue bindings then
+ delete the Exchange(s). The console will prompt for confirmation
+ before undertaking the operation.
+ </para><para>
+
+ Double-clicking on a particular Queue or Exchange name in the
+ tables will open the MBean representing it.
+ </para>
+<!--h1--></section>
+
+
+
+ <section role="h1" id="QpidJMXManagementConsoleUserGuide-Notifications"><title>
+
+ Notifications
+ </title>
+
+ <para>
+
+ MBeans on the server can potentially send Notifications that
+ users may subscribe to. When managing an individual MBean that
+ offers Notifications types for subscription, the console supplies
+ a Notifications tab to allow (un)subscription to the
+ Notifications if desired and viewing any that are received
+ following subscription.
+ </para><para>
+ In order to provide quicker access to/awareness of any received
+ Notifications, each VirtualHost area in the connection tree has a
+ Notifications area that aggregates all received Notifications for
+ MBeans in that VirtualHost. An example of this can be seen in the
+ figure below.
+ </para><para>
+ <mediaobject><imageobject><imagedata fileref="images/jmx_console/3113111.png" format="PNG" scalefit="1"/></imageobject><textobject><phrase/></textobject><caption><para/></caption></mediaobject>
+ </para><para>
+ All received Notifications will be displayed until such time as
+ the user removes them, either in this aggregated view, or in the
+ Notifications area of the individual MBean that generated the
+ Notification.
+ </para><para>
+ They may be cleared selectively or all at once. To clear
+ particular Notifications, they should be selected in the table
+ before pressing the <emphasis>Clear</emphasis> button. To clear all
+ Notifications, simply press the <emphasis>Clear</emphasis> button without
+ anything selected in the table, at which point the console will
+ request confirmation of this clear-all action.
+ </para>
+<!--h1--></section>
+
+ <section role="h1" id="QpidJMXManagementConsoleUserGuide-ManagingQueues"><title>
+ Managing
+ Queues
+ </title>
+
+ <para>
+
+ As mentioned in earlier discussion of Navigation, Queue MBeans
+ can be opened either by double clicking an entry in the Queues
+ selection area, or adding a queue to the tree as a favourite and
+ clicking on its tree node. Unique to the Queue selection screen
+ is the ability to view additional attributes beyond just that of
+ the Queue Name. This is helpful for determining which Queues
+ satisfy a particular condition, e.g. having &lt;X&gt; messages on
+ the queue. The example below shows the selection view with
+ additional attributes <emphasis>Consumer Count, Durable, MessageCount,
+ and QueueDepth</emphasis> (selected using the <emphasis>Select
+ Attributes</emphasis> button at the bottom right corner of the
+ table)<emphasis>.</emphasis>
+ </para><para>
+ <mediaobject><imageobject><imagedata fileref="images/jmx_console/3113112.png" format="PNG" scalefit="1"/></imageobject><textobject><phrase/></textobject><caption><para/></caption></mediaobject>
+ </para><para>
+ Upon opening a Queue MBean, the Attributes tab is displayed, as
+ shown below. This allows viewing the value all attributes,
+ editing those which are writable values (highlighted in blue) if
+ the users management permissions allow, viewing descriptions of
+ their purpose, and graphing certain numerical attribute values as
+ they change over time.
+ </para><para>
+ <mediaobject><imageobject><imagedata fileref="images/jmx_console/3113113.png" format="PNG" scalefit="1"/></imageobject><textobject><phrase/></textobject><caption><para/></caption></mediaobject>
+ </para><para>
+ The next tab contains the operations that can be performed on the
+ queue. The main table serves as a means of viewing the messages
+ on the queue, and later for selecting specific messages to
+ operate upon. It is possible to view any desired range of
+ messages on the queue by specifying the visible range using the
+ fields at the top and pressing the <emphasis>Set</emphasis> button. Next to
+ this there are helper buttons to enable faster browsing through
+ the messages on the queue; these allow moving forward and back by
+ whatever number of messages is made visible by the viewing range
+ set. The Queue Position column indicates the position of each
+ message on the queue, but is only present when connected to newer
+ servers as older versions cannot provide the necessary
+ information to show this (unless only a single message position
+ is requested).
+ </para><para>
+ <mediaobject><imageobject><imagedata fileref="images/jmx_console/3113114.png" format="PNG" scalefit="1"/></imageobject><textobject><phrase/></textobject><caption><para/></caption></mediaobject>
+ </para><para>
+ Upon selecting a message in the table, its header properties and
+ redelivery status are updated in the area below the table. Double
+ clicking a message in the table (or using the <emphasis>View Message
+ Content</emphasis> button to its right) will open a dialog window
+ displaying the contents of the message.
+ </para><para>
+ One or more messages can be selected in the table and moved to
+ another queue in the VirtualHost by using the <emphasis>Move
+ Message(s)</emphasis> button, which opens a dialog to enable selection
+ of the destination and confirmation of the operation. Newer
+ servers support the ability to similarly copy the selected
+ messages to another queue in a similar fashion, or delete the
+ selected messages from the queue after prompting for
+ confirmation.
+ </para><para>
+ Finally, all messages (that have not been acquired by consumers)
+ on the queue can be deleted using the <emphasis>Clear Queue</emphasis>
+ button, which will generate a prompt for confirmation. On newer
+ servers, the status bar at the lower left of the application will
+ report the number of messages actually removed.
+ </para>
+<!--h1--></section>
+
+
+ <section role="h1" id="QpidJMXManagementConsoleUserGuide-ManagingExchanges"><title>
+
+ Managing Exchanges
+ </title>
+
+ <para>
+ Exchange MBeans are opened for management operations in similar
+ fashion as described for Queues, again showing an Attributes tab
+ initially, with the Operations tab next:
+ </para><para>
+ <mediaobject><imageobject><imagedata fileref="images/jmx_console/3113115.png" format="PNG" scalefit="1"/></imageobject><textobject><phrase/></textobject><caption><para/></caption></mediaobject>
+ </para><para>
+ Of the four default Exchange Types <emphasis>(direct, fanout, headers,
+ and topic)</emphasis> all but <emphasis>headers</emphasis> have their bindings
+ presented in the format shown above. The left table provides the
+ binding/routing keys present in the exchange. Selecting one of
+ these entries in the table prompts the right table to display all
+ the queues associated with this key. Pressing the <emphasis>Create</emphasis>
+ button opens a dialog allowing association of an existing queue
+ with the entered Binding.
+ </para><para>
+ <mediaobject><imageobject><imagedata fileref="images/jmx_console/3113116.png" format="PNG" scalefit="1"/></imageobject><textobject><phrase/></textobject><caption><para/></caption></mediaobject>
+ </para><para>
+ The <emphasis>headers</emphasis> Exchange type (default instantiation
+ <emphasis>amq.match or amq.headers</emphasis>) is presented as below:
+ </para><para>
+ <mediaobject><imageobject><imagedata fileref="images/jmx_console/3113117.png" format="PNG" scalefit="1"/></imageobject><textobject><phrase/></textobject><caption><para/></caption></mediaobject>
+ </para><para>
+ In the previous figure, the left table indicates the binding
+ number, and the Queue associated with the binding. Selecting one
+ of these entries in the table prompts the right table to display
+ the header values that control when the binding matches an
+ incoming message.
+ </para><para>
+ <mediaobject><imageobject><imagedata fileref="images/jmx_console/3113118.png" format="PNG" scalefit="1"/></imageobject><textobject><phrase/></textobject><caption><para/></caption></mediaobject>
+ </para><para>
+ Pressing the <emphasis>Create</emphasis> button when managing a
+ <emphasis>headers</emphasis> Exchange opens a dialog allowing creation of a
+ new binding, associating an existing Queue with a particular set
+ of header keys and values. The <emphasis>x-match</emphasis> key is required,
+ and instructs the server whether to match the binding with
+ incoming messages based on ANY or ALL of the further key-value
+ pairs entered. If it is desired to enter more than 4 pairs, you
+ may press the <emphasis>Add additional field</emphasis> button to create a
+ new row as many times as is required.
+
+ When managing a <emphasis>headers</emphasis> Exchange, double clicking an
+ entry in the left-hand table will open the MBean for the Queue
+ specified in the binding properties.
+ </para><para>
+ When managing another Exchange Type, double clicking the Queue
+ Name in the right-hand table will open the MBean of the Queue
+ specified.
+ </para>
+<!--h1--></section>
+
+ <section role="h1" id="QpidJMXManagementConsoleUserGuide-ManagingConnections"><title>
+
+ Managing Connections
+ </title>
+
+ <para>
+
+ Exchange MBeans are opened for management operations in similar
+ fashion as described for Queues, again showing an Attributes tab
+ initially, with the Operations tab next, and finally a
+ Notifications tab allowing subscription and viewing of
+ Notifications. The Operations tab can be seen in the figure
+ below.
+ </para><para>
+ <mediaobject><imageobject><imagedata fileref="images/jmx_console/3113119.png" format="PNG" scalefit="1"/></imageobject><textobject><phrase/></textobject><caption><para/></caption></mediaobject>
+ The main table shows the properties of all the Channels that are
+ present on the Connection, including whether they are
+ <emphasis>Transactional</emphasis>, the <emphasis>Number of Unacked Messages</emphasis>
+ on them, and the <emphasis>Default Queue</emphasis> if there is one (or
+ <emphasis>null</emphasis> if there is not).
+ </para><para>
+ The main operations supported on a connection are Commiting and
+ Rolling Back of Transactions on a particular Channel, if the
+ Channel is Transactional. This can be done by selecting a
+ particular Channel in the table and pressing the <emphasis>Commit
+ Transactions</emphasis> or <emphasis>Rollback Transactions</emphasis> buttons at
+ the lower right corner of the table, at which point the console
+ will prompt for confirmation of the action. These buttons are
+ only active when the selected Channel in the table is
+ Transactional.
+ </para><para>
+ The final operation supported is closing the Connection. After
+ pressing the <emphasis>Close Connection</emphasis> button, the console will
+ prompt for confirmation of the action. If this is carried out,
+ the MBean for the Connection being managed will be removed from
+ the server. The console will be notified of this by the server
+ and display an information dialog to that effect, as it would if
+ any other MBean were to be unregistered whilst being viewed.
+ </para><para>
+ Double clicking a row in the table will open the MBean of the
+ associated <emphasis>Default Queue</emphasis> if there is one.
+ </para>
+
+<!--h1--></section>
+</section>
diff --git a/qpid/doc/book/src/Qpid-JMX-Management-Console.xml b/qpid/doc/book/src/Qpid-JMX-Management-Console.xml
new file mode 100644
index 0000000000..fb46f4a01a
--- /dev/null
+++ b/qpid/doc/book/src/Qpid-JMX-Management-Console.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+
+ 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.
+
+-->
+
+<chapter id="Qpid-JMX-Management-Console">
+
+ <title>
+ Qpid JMX Management Console
+ </title>
+
+ <section role="h2" id="QpidJMXManagementConsole-QpidJMXManagementConsole">
+
+ <title> Qpid JMX Management Console </title>
+
+ <section role="h3" id="QpidJMXManagementConsole-Overview">
+
+ <title>
+ Overview
+ </title>
+
+ <para>
+ The Qpid JMX Management Console is a standalone Eclipse
+ RCP application that communicates with the broker using
+ JMX.
+ </para>
+
+ <xi:include href="Configuring-Management-Users.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+ <xi:include href="Configuring-Qpid-JMX-Management-Console.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+ <xi:include href="Management-Console-Security.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+ <xi:include href="Qpid-JMX-Management-Console-FAQ.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+ <xi:include href="Qpid-JMX-Management-Console-User-Guide.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+ <xi:include href="Qpid-Management-Features.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+<!--h3--></section>
+<!--h2--></section>
+</chapter>
diff --git a/qpid/doc/book/src/Qpid-Java-Broker-Management-CLI.xml b/qpid/doc/book/src/Qpid-Java-Broker-Management-CLI.xml
new file mode 100644
index 0000000000..3042e53a3f
--- /dev/null
+++ b/qpid/doc/book/src/Qpid-Java-Broker-Management-CLI.xml
@@ -0,0 +1,159 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+
+ 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.
+
+-->
+
+<section><title>
+ Qpid Java Broker Management CLI
+ </title>
+ <section role="h2" id="QpidJavaBrokerManagementCLI-HowtobuildApacheQpidCLI"><title>
+ How to
+ build Apache Qpid CLI
+ </title>
+
+
+ <section role="h3" id="QpidJavaBrokerManagementCLI-BuildInstructionsGeneral"><title>
+ Build
+ Instructions - General
+ </title>
+
+ <para>
+ At the very beginning please build Apache Qpid by refering this
+ installation guide from here <xref linkend="qpid_qpid-java-build-how-to"/>.
+ </para><para>
+ After successfully build Apache Qpid you'll be able to start
+ Apache Qpid Java broker,then only you are in a position to use
+ Qpid CLI.
+ </para>
+<!--h3--></section>
+
+ <section role="h3" id="QpidJavaBrokerManagementCLI-CheckouttheSource"><title>
+ Check
+ out the Source
+ </title>
+
+ <para>
+ First check out the source from subversion repository. Please
+ visit the following link for more information about different
+ versions of Qpid CLI.
+ </para><para>
+ <xref linkend="qpid_list"/>
+ </para>
+<!--h3--></section>
+
+ <section role="h3" id="QpidJavaBrokerManagementCLI-Prerequisites"><title>
+ Prerequisites
+ </title>
+
+ <para>
+ For the broker code you need JDK 1.5.0_15 or later. You should
+ set JAVA_HOME and include the bin directory in your PATH.
+ </para><para>
+ Check it's ok by executing java -v !
+ </para>
+<!--h3--></section>
+
+ <section role="h3" id="QpidJavaBrokerManagementCLI-BuildingApacheQpidCLI"><title>
+ Building
+ Apache Qpid CLI
+ </title>
+
+ <para>
+ This project is currently having only an ant build system.Please
+ install ant build system before trying to install Qpid CLI.
+ </para>
+<!--h3--></section>
+
+
+
+ <section role="h3" id="QpidJavaBrokerManagementCLI-Compiling"><title>
+ Compiling
+ </title>
+
+ <para>
+ To compile the source please run following command
+ </para>
+ <programlisting>
+ant compile
+</programlisting>
+ <para>
+ To compile the test source run the following command
+ </para>
+ <programlisting>
+ant compile-tests
+</programlisting>
+<!--h3--></section>
+
+
+ <section role="h3" id="QpidJavaBrokerManagementCLI-RunningCLI"><title>
+ Running CLI
+ </title>
+
+ <para>
+ After successful compilation set QPID_CLI environment variable to
+ the main source directory.(set the environment variable to the
+ directory where ant build script stored in the SVN
+ checkout).Please check whether the Qpid Java broker is up an
+ running in the appropriate location and run the following command
+ to start the Qpid CLI by running the qpid-cli script in the bin
+ directory.
+ </para><para>
+ $QPID_CLI/bin/qpid-cli -h &lt;hostname of the broker&gt; -p
+ &lt;broker running port&gt;
+ For more details please have a look in to README file which ships
+ with source package of Qpid CLI.
+ </para>
+<!--h3--></section>
+
+
+ <section role="h3" id="QpidJavaBrokerManagementCLI-Otheranttargets"><title>
+ Other
+ ant targets
+ </title>
+
+ <para>For now we are supporting those ant targets.</para>
+
+ <variablelist>
+ <varlistentry>
+ <term>ant clean</term>
+ <listitem><para>Clean the complete build including CLI build and test build.</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>ant jar</term>
+ <listitem><para>Create the jar file for the project without test cases.</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>ant init</term>
+ <listitem><para>Create the directory structure for build.</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>ant compile-tests </term>
+ <listitem><para>This compiles all the test source.</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>ant test </term>
+ <listitem><para>Run all the test cases.</para></listitem>
+ </varlistentry>
+
+ </variablelist>
+
+<!--h3--></section>
+<!--h2--></section>
+</section>
diff --git a/qpid/doc/book/src/Qpid-Java-Build-How-To.xml b/qpid/doc/book/src/Qpid-Java-Build-How-To.xml
new file mode 100644
index 0000000000..f38109a3fb
--- /dev/null
+++ b/qpid/doc/book/src/Qpid-Java-Build-How-To.xml
@@ -0,0 +1,365 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+
+ 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.
+
+-->
+
+<section><title>
+ Qpid Java Build How To
+ </title>
+
+ <section role="h1" id="QpidJavaBuildHowTo-BuildInstructionsGeneral"><title>
+ Build
+ Instructions - General
+ </title>
+
+ <section role="h2" id="QpidJavaBuildHowTo-Checkoutthesource"><title>
+ Check out the
+ source
+ </title>
+ <para>
+ Firstly, check the source for Qpid out of our subversion
+ repository:
+ </para><para>
+ <xref linkend="qpid_trunk"/>
+ </para>
+<!--h2--></section>
+ <section role="h2" id="QpidJavaBuildHowTo-Prerequisites"><title>
+ Prerequisites
+ </title>
+ <para>
+ For the broker code you need JDK 1.5.0_15 or later. You should
+ set JAVA_HOME and include the bin directory in your PATH.
+ </para><para>
+ Check it's ok by executing java -v !
+ </para><para>
+ If you are wanting to run the python tests against the broker you
+ will of course need a version of python.
+ </para>
+<!--h2--></section>
+<!--h1--></section>
+
+ <section role="h1" id="QpidJavaBuildHowTo-BuildInstructionsTrunk"><title>
+ Build
+ Instructions - Trunk
+ </title>
+ <para>
+ Our build system has reverted to ant as of May 2008.
+ </para><para>
+ The ant target 'help' will tell you what you need to know about
+ the build system.
+ </para>
+ <section role="h2" id="QpidJavaBuildHowTo-AntBuildScripts"><title>
+ Ant Build
+ Scripts
+ </title>
+ <para>
+ Currently the Qpid java project builds using ant.
+ </para><para>
+ The ant build system is set up in a modular way, with a top level
+ build script and template for module builds and then a module
+ level build script which inherits from the template.
+ </para><para>
+ So, at the top level there are:
+ </para><table><title/><tgroup cols="2">
+ <tbody>
+ <row>
+ <entry>
+ File
+ </entry>
+ <entry>
+ Description
+ </entry>
+ </row>
+ <row>
+ <entry>
+ build.xml
+ </entry>
+ <entry>
+ Top level build file for the project which defines all the
+ build targets
+ </entry>
+ </row>
+ <row>
+ <entry>
+ common.xml
+ </entry>
+ <entry>
+ Common properties used throughout the build system
+ </entry>
+ </row>
+ <row>
+ <entry>
+ module.xml
+ </entry>
+ <entry>
+ Template used by all modules which sets up properties for
+ module builds
+ </entry>
+ </row>
+ </tbody>
+ </tgroup></table><para>
+ Then, in each module subdirectory there is:
+ </para><table><title/><tgroup cols="2">
+ <tbody>
+ <row>
+ <entry>
+ File
+ </entry>
+ <entry>
+ Description
+ </entry>
+ </row>
+ <row>
+ <entry>
+ build.xml
+ </entry>
+ <entry>
+ Defines all the module values for template properties
+ </entry>
+ </row>
+ </tbody>
+ </tgroup></table>
+<!--h2--></section>
+ <section role="h2" id="QpidJavaBuildHowTo-Buildtargets"><title>
+ Build targets
+ </title>
+ <para>
+ The main build targets you are probably interested in are:
+ </para><table><title/><tgroup cols="2">
+ <tbody>
+ <row>
+ <entry>
+ Target
+ </entry>
+ <entry>
+ Description
+ </entry>
+ </row>
+ <row>
+ <entry>
+ build
+ </entry>
+ <entry>
+ Builds all source code for Qpid
+ </entry>
+ </row>
+ <row>
+ <entry>
+ test
+ </entry>
+ <entry>
+ Runs the testsuite for Qpid
+ </entry>
+ </row>
+ </tbody>
+ </tgroup></table><para>
+ So, if you just want to compile everything you should run the
+ build target in the top level build.xml file.
+ </para><para>
+ If you want to build an installable version of Qpid, run the
+ archive task from the top level build.xml file.
+ </para><para>
+ If you want to compile an individual module, simply run the build
+ target from the appropriate module e.g. to compile the broker
+ source
+ </para>
+<!--h2--></section>
+ <section role="h2" id="QpidJavaBuildHowTo-ConfiguringEclipse"><title>
+ Configuring
+ Eclipse
+ </title>
+ <para>
+ 1. Run the ant build from the root directory of Java trunk.
+ 2. New project -&gt; create from existing file system for broker,
+ common, client, junit-toolkit, perftests, systests and each
+ directory under management
+ 4. Add the contents of lib/ to the build path
+ 5. Setup Generated Code
+ 6. Setup Dependencies
+ </para>
+ <section role="h3" id="QpidJavaBuildHowTo-GeneratedCode"><title>
+ Generated Code
+ </title>
+ <para>
+ The Broker and Common packages both depend on generated code.
+ After running 'ant' the build/scratch directory will contain this
+ generated code.
+ For the broker module add build/scratch/broker/src
+ For the common module add build/scratch/common/src
+ </para>
+<!--h3--></section>
+ <section role="h3" id="QpidJavaBuildHowTo-Dependencies"><title>
+ Dependencies
+ </title>
+ <para>
+ These dependencies are correct at the time of writting however,
+ if things are not working you can check the dependencies by
+ looking in the modules build.xml file:
+ </para>
+ <programlisting>
+for i in `find . -name build.xml` ; do echo "$i:"; grep module.depends $i ; done
+</programlisting>
+ <para>
+ The <emphasis>module.depend</emphasis> value will detail which other modules
+ are dependencies.
+ </para><para>
+ broker
+ </para><itemizedlist>
+ <listitem><para>common
+ </para></listitem>
+ <listitem><para>management/common
+ </para></listitem>
+ </itemizedlist><para>
+ client
+ </para><itemizedlist>
+ <listitem><para>Common
+ </para></listitem>
+ </itemizedlist><para>
+ systest
+ </para><itemizedlist>
+ <listitem><para>client
+ </para></listitem>
+ <listitem><para>management/common
+ </para></listitem>
+ <listitem><para>broker
+ </para></listitem>
+ <listitem><para>broker/test
+ </para></listitem>
+ <listitem><para>common
+ </para></listitem>
+ <listitem><para>junit-toolkit
+ </para></listitem>
+ <listitem><para>management/tools/qpid-cli
+ </para></listitem>
+ </itemizedlist><para>
+ perftests
+ </para><itemizedlist>
+ <listitem><para>systests
+ </para></listitem>
+ <listitem><para>client
+ </para></listitem>
+ <listitem><para>broker
+ </para></listitem>
+ <listitem><para>common
+ </para></listitem>
+ <listitem><para>junit-toolkit
+ </para></listitem>
+ </itemizedlist><para>
+ management/eclipse-plugin
+ </para><itemizedlist>
+ <listitem><para>broker
+ </para></listitem>
+ <listitem><para>common
+ </para></listitem>
+ <listitem><para>management/common
+ </para></listitem>
+ </itemizedlist><para>
+ management/console
+ </para><itemizedlist>
+ <listitem><para>common
+ </para></listitem>
+ <listitem><para>client
+ </para></listitem>
+ </itemizedlist><para>
+ management/agent
+ </para><itemizedlist>
+ <listitem><para>common
+ </para></listitem>
+ <listitem><para>client
+ </para></listitem>
+ </itemizedlist><para>
+ management/tools/qpid-cli
+ </para><itemizedlist>
+ <listitem><para>common
+ </para></listitem>
+ <listitem><para>management/common
+ </para></listitem>
+ </itemizedlist><para>
+ management/client
+ </para><itemizedlist>
+ <listitem><para>common
+ </para></listitem>
+ <listitem><para>client
+ </para></listitem>
+ </itemizedlist><para>
+ integrationtests
+ </para><itemizedlist>
+ <listitem><para>systests
+ </para></listitem>
+ <listitem><para>client
+ </para></listitem>
+ <listitem><para>common
+ </para></listitem>
+ <listitem><para>junit-toolkit
+ </para></listitem>
+ </itemizedlist><para>
+ testkit
+ </para><itemizedlist>
+ <listitem><para>client
+ </para></listitem>
+ <listitem><para>broker
+ </para></listitem>
+ <listitem><para>common
+ </para></listitem>
+ </itemizedlist><para>
+ tools
+ </para><itemizedlist>
+ <listitem><para>client
+ </para></listitem>
+ <listitem><para>common
+ </para></listitem>
+ </itemizedlist><para>
+ client/examples
+ </para><itemizedlist>
+ <listitem><para>common
+ </para></listitem>
+ <listitem><para>client
+ </para></listitem>
+ </itemizedlist><para>
+ broker-plugins
+ </para><itemizedlist>
+ <listitem><para>client
+ </para></listitem>
+ <listitem><para>management/common
+ </para></listitem>
+ <listitem><para>broker
+ </para></listitem>
+ <listitem><para>common
+ </para></listitem>
+ <listitem><para>junit-toolkit
+ </para></listitem>
+ </itemizedlist>
+<!--h3--></section>
+<!--h2--></section>
+
+ <section role="h2" id="QpidJavaBuildHowTo-Whatnext-3F"><title>
+ What next ?
+ </title>
+ <para>
+ If you want to run your built Qpid package, see our <xref linkend="qpid_Getting-Started-Guide"/> for details of
+ how to do that.
+ </para><para>
+ If you want to run our tests, you can use the ant test or
+ testreport (produces a useful report) targets.
+ </para>
+
+<!--h2--></section>
+<!--h1--></section>
+</section>
diff --git a/qpid/doc/book/src/Qpid-Java-FAQ.xml b/qpid/doc/book/src/Qpid-Java-FAQ.xml
new file mode 100644
index 0000000000..7a28703774
--- /dev/null
+++ b/qpid/doc/book/src/Qpid-Java-FAQ.xml
@@ -0,0 +1,949 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+
+ 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.
+
+-->
+
+<section><title>
+ Qpid Java FAQ
+ </title>
+
+ <section role="h2" id="QpidJavaFAQ-Purpose">
+ <title>Purpose</title>
+ <para>
+ Here are a list of commonly asked questions and answers. Click on
+ the the bolded questions for the answer to unfold. If you have
+ any questions which are not on this list, please email our
+ qpid-user list.
+ </para>
+
+ <section role="h3" id="QpidJavaFAQ-WhatisQpid-3F"><title>
+ What is Qpid ?
+ </title>
+
+ <para>
+ The java implementation of Qpid is a pure Java message broker
+ that implements the AMQP protocol. Essentially, Qpid is a robust,
+ performant middleware component that can handle your messaging
+ traffic.
+ </para><para>
+ It currently supports the following features:
+ </para><itemizedlist>
+ <listitem><para>High performance header-based routing for messages
+ </para></listitem>
+ <listitem><para>All features required by the JMS 1.1 specification. Qpid
+ passes all tests in the Sun JMS compliance test suite
+ </para></listitem>
+ <listitem><para>Transaction support
+ </para></listitem>
+ <listitem><para>Persistence using the high performance Berkeley DB Java
+ Edition. The persistence layer is also pluggable should an
+ alternative implementation be required. The BDB store is
+ available from the <xref linkend="qpid_3rd-Party-Libraries"/> page
+ </para></listitem>
+ <listitem><para>Pluggable security using SASL. Any Java SASL provider can be
+ used
+ </para></listitem>
+ <listitem><para>Management using JMX and a custom management console built
+ using Eclipse RCP
+ </para></listitem>
+ <listitem><para>Naturally, interoperability with other clients including the
+ Qpid .NET, Python, Ruby and C++ implementations
+ </para></listitem>
+ </itemizedlist>
+ <!--h3--></section>
+
+ <section role="h3" id="QpidJavaFAQ-WhyamIgettingaConfigurationExceptionatbrokerstartup-3F"><title>
+ Why am I getting a ConfigurationException at broker startup ?
+ </title>
+
+ <section role="h4" id="QpidJavaFAQ-InvocationTargetException"><title>
+ InvocationTargetException
+ </title>
+ <para>
+ If you get a java.lang.reflect.InvocationTargetException on
+ startup, wrapped as ConfigurationException like this:
+ </para>
+ <programlisting>
+Error configuring message broker: org.apache.commons.configuration.ConfigurationException: java.lang.reflect.InvocationTargetException
+2008-09-26 15:14:56,529 ERROR [main] server.Main (Main.java:206) - Error configuring message broker: org.apache.commons.configuration.ConfigurationException: java.lang.reflect.InvocationTargetException
+org.apache.commons.configuration.ConfigurationException: java.lang.reflect.InvocationTargetException
+at org.apache.qpid.server.security.auth.database.ConfigurationFilePrincipalDatabaseManager.initialisePrincipalDatabase(ConfigurationFilePrincipalDatabaseManager.java:158)
+at org.apache.qpid.server.security.auth.database.ConfigurationFilePrincipalDatabaseManager.initialisePrincipalDatabases(ConfigurationFilePrincipalDatabaseManager.java:87)
+at org.apache.qpid.server.security.auth.database.ConfigurationFilePrincipalDatabaseManager.&lt;init&gt;(ConfigurationFilePrincipalDatabaseManager.java:56)
+at org.apache.qpid.server.registry.ConfigurationFileApplicationRegistry.initialise(ConfigurationFileApplicationRegistry.java:117)
+at org.apache.qpid.server.registry.ApplicationRegistry.initialise(ApplicationRegistry.java:79)
+at org.apache.qpid.server.registry.ApplicationRegistry.initialise(ApplicationRegistry.java:67)
+at org.apache.qpid.server.Main.startup(Main.java:260)
+at org.apache.qpid.server.Main.execute(Main.java:196)
+at org.apache.qpid.server.Main.&lt;init&gt;(Main.java:96)
+at org.apache.qpid.server.Main.main(Main.java:454)
+at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
+at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
+at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
+at java.lang.reflect.Method.invoke(Method.java:597)
+at com.intellij.rt.execution.application.AppMain.main(AppMain.java:90)
+Caused by: java.lang.reflect.InvocationTargetException
+at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
+at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
+at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
+at java.lang.reflect.Method.invoke(Method.java:597)
+at org.apache.qpid.server.security.auth.database.ConfigurationFilePrincipalDatabaseManager.initialisePrincipalDatabase(ConfigurationFilePrincipalDatabaseManager.java:148)
+</programlisting>
+ <para>
+ .. then it means you have a missing password file.
+ </para><para>
+ You need to create a password file for your deployment and update
+ your config.xml to reflect the location of the password file for
+ your instance.
+ </para><para>
+ The config.xml can be a little confusing in terms of element
+ names and file names for passwords.
+ </para><para>
+ To do this, you need to edit the passwordDir element for the
+ broker, which may have a comment to that effect:
+ </para>
+ <programlisting>
+&lt;passwordDir&gt;&lt;!-- Change to the location --&gt;&lt;/passwordDir&gt;
+</programlisting>
+ <para>
+ The file should be named passwd by default but if you want to you
+ can change this by editing this element:
+ </para>
+ <programlisting>
+&lt;value&gt;${passwordDir}/passwd&lt;/value&gt;
+</programlisting>
+ <!--h4--></section>
+
+
+ <section role="h4" id="QpidJavaFAQ-Cannotlocateconfigurationsourcenull-2Fvirtualhosts.xml"><title>
+ Cannot locate configuration source null/virtualhosts.xml
+ </title>
+
+ <para>
+ If you get this message, wrapped inside a ConfigurationException
+ then you've come across a known issue, see JIRA <xref linkend="qpid_QPID-431"/>
+ </para><para>
+ The work around is to use a qualified path as the parameter value
+ for your -c option, rather than (as you migth be) starting the
+ broker from your installed etc directory. Even going up one level
+ and using a path relative to your £QPID_HOME directory
+ would sort this e.g qpid-server -c ./etc/myconfig.xml
+ </para>
+<!--h4--></section>
+<!--h3--></section>
+
+ <section role="h3" id="QpidJavaFAQ-HowdoIruntheQpidbroker-3F"><title>
+ How do I run
+ the Qpid broker ?
+ </title>
+
+ <para>
+ The broker comes with a script for unix/linux/cygwin called
+ qpid-server, which can be found in the bin directory of the
+ installed package. This command can be executed without any
+ paramters and will then use the default configuration file
+ provided on install.
+ </para><para>
+ For the Windows OS, please use qpid-server.bat.
+ </para><para>
+ There's no need to set your classpath for QPID as the scripts
+ take care of that by adding jar's with classpath defining
+ manifest files to your classpath.
+ </para><para>
+ For more information on running the broker please see our
+ <xref linkend="Getting-Started"/> page.
+ </para>
+<!--h3--></section>
+
+ <section role="h3" id="QpidJavaFAQ-HowcanIcreateaconnectionusingaURL-3F"><title>
+ How can I
+ create a connection using a URL ?
+ </title>
+
+ <para>
+ Please see the <xref linkend="qpid_Connection-URL-Format"/> documentation.
+ </para>
+<!--h3--></section>
+
+ <section role="h3" id="QpidJavaFAQ-HowdoIrepresentaJMSDestinationstringwithQPID-3F"><title>
+ How
+ do I represent a JMS Destination string with QPID ?
+ </title>
+
+ <section role="h4" id="QpidJavaFAQ-Queues"><title>
+ Queues
+ </title>
+
+ <para>
+ A queue can be created in QPID using the following URL format.
+ </para><para>
+ direct://amq.direct/&lt;Destination&gt;/&lt;Queue
+ Name&gt;
+ </para><para>
+ For example:
+ direct://amq.direct/&lt;Destination&gt;/simpleQueue
+ </para><para>
+ Queue names may consist of any mixture of digits, letters, and
+ underscores.
+ </para><para>
+ The <xref linkend="BindingURLFormat"/> is described in more
+ detail on it's own page.
+ </para>
+<!--h4--></section>
+
+ <section role="h4" id="QpidJavaFAQ-Topics"><title>
+ Topics
+ </title>
+
+ <para>
+ A topic can be created in QPID using the following URL format.
+ </para><para>
+ topic://amq.topic/&lt;Topic Subscription&gt;/
+ </para><para>
+ The topic subscription may only contain the letters A-Z and a-z
+ and digits 0-9.
+ </para><para>
+ The topic subscription is formed from a series of words that may
+ only contain the letters A-Z and a-z and digits 0-9.
+ The words are delimited by dots. Each dot represents a new level.
+ </para><para>
+ For example: stocks.nyse.ibm
+ </para><para>
+ Wildcards can be used on subscription with the following meaning.
+ </para><itemizedlist>
+ <listitem><para>match a single level
+ # match zero or more levels
+ </para></listitem>
+ </itemizedlist><para>
+ For example:
+ With two clients
+ 1 - stocks.*.ibm
+ 2 - stocks.#.ibm
+ </para><para>
+ Publishing stocks.nyse.ibm will be received by both
+ clients but stocks.ibm and stocks.world.us.ibm
+ will only be received by client 2.
+ </para><para>
+ The topic currently does not support wild cards.
+ </para>
+<!--h4--></section>
+<!--h3--></section>
+
+ <section role="h3" id="QpidJavaFAQ-HowdoIconnecttothebrokerusingJNDI-3F"><title>
+ How do I
+ connect to the broker using JNDI ?
+ </title>
+
+ <para>
+ see <xref linkend="How-to-Use-JNDI"/>
+ </para>
+<!--h3--></section>
+
+ <section role="h3" id="QpidJavaFAQ-I-27musingSpringandWeblogiccanyouhelpmewiththeconfigurationformovingovertoQpid-3F"><title>
+ I'm using Spring and Weblogic - can you help me with the
+ configuration for moving over to Qpid ?
+ </title>
+
+ <para>
+ Here is a donated Spring configuration file <ulink
+ url="http://qpid.apache.org/qpid-java-faq.data/appContext.zip">appContext.zip</ulink>
+ which shows the config for Qpid side by side with
+ Weblogic. HtH !
+ </para>
+<!--h3--></section>
+
+ <section role="h3" id="QpidJavaFAQ-HowdoIconfigurethelogginglevelforQpid-3F"><title>
+ How do
+ I configure the logging level for Qpid ?
+ </title>
+
+ <para>
+ The system property
+ </para>
+ <programlisting>
+amqj.logging.level
+</programlisting>
+ <para>
+ can be used to configure the logging level.
+ For the broker, you can use the environment variable
+ AMQJ_LOGGING_LEVEL which is picked up by the qpid-run script
+ (called by qpid-server to start the broker) at runtime.
+ </para><para>
+ For client code that you've written, simply pass in a system
+ property to your command line to set it to the level you'd like
+ i.e.
+ </para>
+ <programlisting>
+-Damqj.logging.level=INFO
+</programlisting>
+ <para>
+ The log level for the broker defaults to INFO if the env variable
+ is not set, but you may find that your log4j properties affect
+ this. Setting the property noted above should address this.
+ </para>
+<!--h3--></section>
+
+ <section role="h3" id="QpidJavaFAQ-HowcanIconfiguremyapplicationtouseQpidclientlogging-3F"><title>
+ How can I configure my application to use Qpid client
+ logging?
+ </title>
+
+ <para>
+ If you don't already have a logging implementation in your
+ classpath you should add slf4-log4j12-1.4.0.jar and
+ log4j-1.2.12.jar.
+ </para>
+<!--h3--></section>
+
+ <section role="h3" id="QpidJavaFAQ-HowcanIconfigurethebroker-3F"><title>
+ How can I
+ configure the broker ?
+ </title>
+
+ <para>
+ The broker configuration is contained in the
+ &lt;installed-dir&gt;/etc/config.xml file. You can copy and edit
+ this file and then specify your own configuration file as a
+ parameter to the startup script using the -c flag i.e.
+ qpid-server -c &lt;your_config_file's_path&gt;
+ </para><para>
+ For more detailed information on configuration, please see
+ <xref linkend="qpid_Qpid-Design---Configuration"/>
+ </para><para>
+
+ </para>
+<!--h3--></section>
+
+ <section role="h3" id="QpidJavaFAQ-Whatportsdoesthebrokeruse"><title>
+ What ports
+ does the broker use?
+ </title>
+
+ <para>
+ The broker defaults to use port 5672 at startup for AMQP
+ traffic.
+ If the management interface is enabled it starts on port 8999 by
+ default.
+ </para><para>
+ The JMX management interface actually requires 2 ports to
+ operate, the second of which is indicated to the client
+ application during connection initiation to the main (default:
+ 8999) port. Previously this second port has been chosen at random
+ during broker startup, however since Qpid 0.5 this has been fixed
+ to a port 100 higher than the main port(ie Default:9099) in order
+ to ease firewall navigation.
+ </para>
+<!--h3--></section>
+
+ <section role="h3" id="QpidJavaFAQ-HowcanIchangetheportthebrokerusesatruntime-3F"><title>
+ How
+ can I change the port the broker uses at runtime ?
+ </title>
+
+ <para>
+ The broker defaults to use port 5672 at startup for AMQP
+ traffic.
+ The broker also uses port 8999 for the JMX Management interface.
+ </para><para>
+ To change the AMQP traffic port use the -p flag at startup. To
+ change the management port use -m
+ i.e. qpid-server -p &lt;port_number_to_use&gt; -m
+ &lt;port_number_to_use&gt;
+ </para><para>
+ Use this to get round any issues on your host server with port
+ 5672/8999 being in use/unavailable.
+ </para><para>
+ For additional details on what ports the broker uses see <xref linkend="QpidJavaFAQ-Whatportsdoesthebrokeruse"/> FAQ
+ entry.
+ For more detailed information on configuration, please see
+ <xref linkend="qpid_Qpid-Design---Configuration"/>
+ </para>
+<!--h3--></section>
+
+ <section role="h3" id="QpidJavaFAQ-WhatcommandlineoptionscanIpassintotheqpidserverscript-3F"><title>
+ What command line options can I pass into the qpid-server
+ script ?
+ </title>
+
+ <para>
+ The following command line options are available:
+ </para>
+
+ <para>
+ The following options are available:
+ </para><table>
+ <title>
+ Command Line Options
+ </title>
+
+ <tgroup cols="3">
+ <tbody>
+ <row>
+ <entry>
+ Option
+ </entry>
+ <entry>
+ Long Option
+ </entry>
+ <entry>
+ Description
+ </entry>
+ </row>
+ <row>
+ <entry>
+ b
+ </entry>
+ <entry>
+ bind
+ </entry>
+ <entry>
+ Bind to the specified address overriding any value in the
+ config file
+ </entry>
+ </row>
+ <row>
+ <entry>
+ c
+ </entry>
+ <entry>
+ config
+ </entry>
+ <entry>
+ Use the given configuration file
+ </entry>
+ </row>
+ <row>
+ <entry>
+ h
+ </entry>
+ <entry>
+ help
+ </entry>
+ <entry>
+ Prints list of options
+ </entry>
+ </row>
+ <row>
+ <entry>
+ l
+ </entry>
+ <entry>
+ logconfig
+ </entry>
+ <entry>
+ Use the specified log4j.xml file rather than that in the
+ etc directory
+ </entry>
+ </row>
+ <row>
+ <entry>
+ m
+ </entry>
+ <entry>
+ mport
+ </entry>
+ <entry>
+ Specify port to listen on for the JMX Management. Overrides
+ value in config file
+ </entry>
+ </row>
+ <row>
+ <entry>
+ p
+ </entry>
+ <entry>
+ port
+ </entry>
+ <entry>
+ Specify port to listen on. Overrides value in config file
+ </entry>
+ </row>
+ <row>
+ <entry>
+ v
+ </entry>
+ <entry>
+ version
+ </entry>
+ <entry>
+ Print version information and exit
+ </entry>
+ </row>
+ <row>
+ <entry>
+ w
+ </entry>
+ <entry>
+ logwatch
+ </entry>
+ <entry>
+ Specify interval for checking for logging config changes.
+ Zero means no checking
+ </entry>
+ </row>
+ </tbody>
+ </tgroup></table>
+ </section>
+
+ <section role="h3" id="QpidJavaFAQ-HowdoIauthenticatewiththebroker-3FWhatuserid-26passwordshouldIuse-3F"><title>
+ How do I authenticate with the broker ? What user id &amp;
+ password should I use ?
+ </title>
+
+ <para>
+ You should login as user guest with password guest
+ </para>
+<!--h3--></section>
+
+ <section role="h3" id="QpidJavaFAQ-HowdoIcreatequeuesthatwillalwaysbeinstantiatedatbrokerstartup-3F"><title>
+ How do I create queues that will always be instantiated at
+ broker startup ?
+ </title>
+
+ <para>
+ You can configure queues which will be created at broker startup
+ by tailoring a copy of the virtualhosts.xml file provided in the
+ installed qpid-version/etc directory.
+ </para><para>
+ So, if you're using a queue called 'devqueue' you can ensure that
+ it is created at startup by using an entry something like this:
+ </para>
+ <programlisting>
+&lt;virtualhosts&gt;
+ &lt;default&gt;test&lt;/default&gt;
+ &lt;virtualhost&gt;
+ &lt;name&gt;test&lt;/name&gt;
+ &lt;test&gt;
+ &lt;queue&gt;
+ &lt;name&gt;devqueue&lt;/name&gt;
+ &lt;devqueue&gt;
+ &lt;exchange&gt;amq.direct&lt;/exchange&gt;
+ &lt;maximumQueueDepth&gt;4235264&lt;/maximumQueueDepth&gt; &lt;!-- 4Mb --&gt;
+ &lt;maximumMessageSize&gt;2117632&lt;/maximumMessageSize&gt; &lt;!-- 2Mb --&gt;
+ &lt;maximumMessageAge&gt;600000&lt;/maximumMessageAge&gt; &lt;!-- 10 mins --&gt;
+ &lt;/devqueue&gt;
+ &lt;/queue&gt;
+ &lt;/test&gt;
+ &lt;/virtualhost&gt;
+&lt;/virtualhosts&gt;
+</programlisting>
+ <para>
+ Note that the name (in thie example above the name is 'test')
+ element should match the virtualhost that you're using to create
+ connections to the broker. This is effectively a namespace used
+ to prevent queue name clashes etc. You can also see that we've
+ set the 'test' virtual host to be the default for any connections
+ which do not specify a virtual host (in the &lt;default&gt; tag).
+ </para><para>
+ You can amend the config.xml to point at a different
+ virtualhosts.xml file by editing the &lt;virtualhosts/&gt;
+ element.
+ </para><para>
+ So, for example, you could tell the broker to use a file in your
+ home directory by creating a new config.xml file with the
+ following entry:
+ </para><para>
+ &lt;virtualhosts&gt;/home/myhomedir/virtualhosts.xml&lt;/virtualhosts&gt;
+ </para><para>
+ You can then pass this amended config.xml into the broker at
+ startup using the -c flag i.e.
+ qpid-server -c &lt;path&gt;/config.xml
+ </para>
+<!--h3--></section>
+
+ <section role="h3" id="QpidJavaFAQ-HowdoIcreatequeuesatruntime-3F"><title>
+ How do I
+ create queues at runtime?
+ </title>
+
+ <para>
+ Queues can be dynamically created at runtime by creating a
+ consumer for them. After they have been created and bound (which
+ happens automatically when a JMS Consumer is created) a publisher
+ can send messages to them.
+ </para>
+<!--h3--></section>
+
+ <section role="h3" id="QpidJavaFAQ-HowdoItunethebroker-3F"><title>
+ How do I tune
+ the broker?
+ </title>
+
+ <para>
+ There are a number of tuning options available, please see the
+ <xref linkend="How-to-Tune-M3-Java-Broker-Performance"/> page for more information.
+ </para>
+<!--h3--></section>
+
+ <section role="h3" id="QpidJavaFAQ-Wheredoundeliverablemessagesendup-3F"><title>
+ Where do
+ undeliverable messages end up ?
+ </title>
+
+ <para>
+ At present, messages with an invalid routing key will be returned
+ to the sender. If you register an exception listener for your
+ publisher (easiest to do by making your publisher implement the
+ ExceptionListener interface and coding the onException method)
+ you'll see that you end up in onException in this case. You can
+ expect to be catching a subclass of
+ org.apache.qpid.AMQUndeliveredException.
+ </para>
+<!--h3--></section>
+
+ <section role="h3" id="QpidJavaFAQ-CanIconfigurethenameoftheQpidbrokerlogfileatruntime-3F"><title>
+ Can I configure the name of the Qpid broker log file at
+ runtime ?
+ </title>
+
+ <para>
+ If you simply start the Qpid broker using the default
+ configuration, then the log file is written to
+ $QPID_WORK/log/qpid.log
+ </para><para>
+ This is not ideal if you want to run several instances from one
+ install, or acrhive logs to a shared drive from several hosts.
+ </para><para>
+ To make life easier, there are two optional ways to configure the
+ naming convention used for the broker log.
+ </para>
+
+ <section role="h4" id="QpidJavaFAQ-Settingaprefixorsuffix"><title>
+ Setting a prefix
+ or suffix
+ </title>
+
+ <para>
+ Users should set the following environment variables before
+ running qpid-server:
+ </para><para>
+ QPID_LOG_PREFIX - will prefix the log file name with the
+ specified value e.g. if you set this value to be the name of your
+ host (for example) it could look something like host123qpid.log
+ </para><para>
+ QPID_LOG_SUFFIX - will suffix the file name with the specified
+ value e.g. if you set this value to be the name of your
+ application (for example) if could look something like
+ qpidMyApp.log
+ </para>
+<!--h4--></section>
+
+ <section role="h4" id="QpidJavaFAQ-IncludingthePID"><title>
+ Including the PID
+ </title>
+
+ <para>
+ Setting either of these variables to the special value PID will
+ introduce the process id of the java process into the file name
+ as a prefix or suffix as specified**
+ </para>
+<!--h4--></section>
+<!--h3--></section>
+
+ <section role="h3" id="QpidJavaFAQ-Myclientapplicationappearstohavehung-3F"><title>
+ My
+ client application appears to have hung?
+ </title>
+
+ <para>
+ The client code currently has various timeouts scattered
+ throughout the code. These can cause your client to appear like
+ it has hung when it is actually waiting for the timeout ot
+ compelete. One example is when the broker becomes non-responsive,
+ the client code has a hard coded 2 minute timeout that it will
+ wait when closing a connection. These timeouts need to be
+ consolidated and exposed. see <xref linkend="qpid_QPID-429"/>
+ </para>
+<!--h3--></section>
+
+ <section role="h3" id="QpidJavaFAQ-HowdoIcontacttheQpidteam-3F"><title>
+ How do I
+ contact the Qpid team ?
+ </title>
+
+ <para>
+ For general questions, please subscribe to the
+ <ulink url="mailto:users@qpid.apache.org">users@qpid.apache.org</ulink> mailing list.
+ </para><para>
+ For development questions, please subscribe to the
+ <ulink url="mailto:dev@qpid.apache.org">dev@qpid.apache.org</ulink> mailing list.
+ </para><para>
+ More details on these lists are available on our <xref linkend="qpid_Mailing-Lists"/>
+ page.
+ </para>
+<!--h3--></section>
+
+ <section role="h3" id="QpidJavaFAQ-HowcanIchangeauser-27spasswordwhilethebrokerisup-3F"><title>
+ How can I change a user's password while the broker is up ?
+ </title>
+
+ <para>
+ You can do this via the <xref linkend="qpid_Qpid-JMX-Management-Console"/>. To
+ do this simply log in to the management console as an admin user
+ (you need to have created an admin account in the
+ jmxremote.access file first) and then select the 'UserManagement'
+ mbean. Select the user in the table and click the Set Password
+ button. Alternatively, update the password file and use the
+ management console to reload the file with the button at the
+ bottom of the 'UserManagement' view. In both cases, this will
+ take effect when the user next logs in i.e. will not cause them
+ to be disconnected if they are already connected.
+ </para><para>
+ For more information on the Management Console please see our
+ <xref linkend="Qpid-JMX-Management-Console-User-Guide"/>
+ </para>
+<!--h3--></section>
+
+ <section role="h3" id="QpidJavaFAQ-HowdoIknowifthereisaconsumerforamessageIamgoingtosend-3F"><title>
+ How do I know if there is a consumer for a message I am going
+ to send?
+ </title>
+
+ <para>
+ Knowing that there is a consumer for a message is quite tricky.
+ That said using the qpid.jms.Session#createProducer with
+ immediate and mandatory set to true will get you part of the way
+ there.
+ </para><para>
+ If you are publishing to a well known queue then immediate will
+ let you know if there is any consumer able to pre-fetch that
+ message at the time you send it. If not it will be returned to
+ you on your connection listener.
+ </para><para>
+ If you are sending to a queue that the consumer creates then the
+ mandatory flag will let you know if they have not yet created
+ that queue.
+ </para><para>
+ These flags will not be able to tell you if the consuming
+ application has received the message and is able to process it.
+ </para>
+<!--h3--></section>
+
+ <section role="h3" id="QpidJavaFAQ-HowdoIuseanInVMBrokerformyowntests-3F"><title>
+ How do I
+ use an InVM Broker for my own tests?
+ </title>
+
+ <para>
+ I would take a look at the testPassiveTTL in
+ <ulink url="https://svn.apache.org/repos/asf/qpid/trunk/qpid/java/systests/src/main/java/org/apache/qpid/server/queue/TimeToLiveTest.java">TimeToLiveTest.java</ulink>
+ </para><para>
+ The setUp and tearDown methods show how to correctly start up a
+ broker for InVM testing. If you write your tests using a file for
+ the JNDI you can then very easily swap between running your tests
+ InVM and against a real broker.
+ </para><para>
+ See our <xref linkend="How-to-Use-JNDI"/> on how to confgure it
+ </para><para>
+ Basically though you just need to set two System Properites:
+ </para><para>
+ java.naming.factory.initial =
+ org.apache.qpid.jndi.PropertiesFileInitialContextFactory
+ java.naming.provider.url = &lt;your JNDI file&gt;
+ </para><para>
+ and call getInitialContext() in your code.
+ </para><para>
+ You will of course need to have the broker libraries on your
+ class path for this to run.
+ </para>
+<!--h3--></section>
+
+ <section role="h3" id="QpidJavaFAQ-HowcanIinspectthecontentsofmyMessageStore-3F"><title>
+ How
+ can I inspect the contents of my MessageStore?
+ </title>
+
+ <para>
+ There are two possibilities here:
+ </para><para>
+ 1) The management console can be used to interogate an active
+ broker and browse the contents of a queue.See the <xref linkend="qpid_Qpid-JMX-Management-Console"/>
+ page for further details.
+ </para><para>
+ 2) The <xref linkend="qpid_MessageStore-Tool"/> can be used to inspect
+ the contents of a persistent message store. Note: this can
+ currently only be used when the broker is offline.
+ </para>
+<!--h3--></section>
+
+ <section role="h3" id="QpidJavaFAQ-Whyaremytransientmessagesbeingsoslow-3F"><title>
+ Why are
+ my transient messages being so slow?
+ </title>
+
+ <para>
+ You should check that you aren't sending persistent messages,
+ this is the default. If you want to send transient messages you
+ must explicitly set this option when instantiating your
+ MessageProducer or on the send() method.
+ </para>
+<!--h3--></section>
+
+ <section role="h3" id="QpidJavaFAQ-Whydoesmyproducerfillupthebrokerwithmessages-3F"><title>
+ Why
+ does my producer fill up the broker with messages?
+ </title>
+
+ <para>
+ The Java broker does not currently implement producer flow
+ control. Publishes are currently asynchronous, so there is no
+ ability to rate limit this automatically. While this is something
+ which will be addressed in the future, it is currently up to
+ applications to ensure that they do not publish faster than the
+ messages are being consumed for signifcant periods of time.
+ </para>
+<!--h3--></section>
+
+ <section role="h3" id="QpidJavaFAQ-ThebrokerkeepsthrowinganOutOfMemoryexception-3F"><title>
+ The
+ broker keeps throwing an OutOfMemory exception?
+ </title>
+
+ <para>
+ The broker can no longer store any more messages in memory. This
+ is particular evident if you are using the MemoryMessageStore. To
+ alleviate this issue you should ensure that your clients are
+ consuming all the messages from the broker.
+ </para><para>
+ You may also want to increase the memory allowance to the broker
+ though this will only delay the exception if you are publishing
+ messages faster than you are consuming. See <xref linkend="qpid_Java-Environment-Variables"/> for
+ details of changing the memory settings.
+ </para>
+<!--h3--></section>
+
+ <section role="h3" id="QpidJavaFAQ-WhyamIgettingabrokersideexceptionwhenItrytopublishtoaqueueoratopic-3F"><title>
+ Why am I getting a broker side exception when I try to
+ publish to a queue or a topic ?
+ </title>
+
+ <para>
+ If you get a stack trace like this when you try to publish, then
+ you may have typo'd the exchange type in your queue or topic
+ declaration. Open your virtualhosts.xml and check that the
+ </para>
+ <programlisting>
+&lt;exchange&gt;amq.direct&lt;/exchange&gt;
+</programlisting>
+
+ <programlisting>
+2009-01-12 15:26:27,957 ERROR [pool-11-thread-2] protocol.AMQMinaProtocolSession (AMQMinaProtocolSession.java:365) - Unexpected exception while processing frame. Closing connection.
+java.lang.NullPointerException
+ at org.apache.qpid.server.security.access.PrincipalPermissions.authorise(PrincipalPermissions.java:398)
+ at org.apache.qpid.server.security.access.plugins.SimpleXML.authorise(SimpleXML.java:302)
+ at org.apache.qpid.server.handler.QueueBindHandler.methodReceived(QueueBindHandler.java:111)
+ at org.apache.qpid.server.handler.ServerMethodDispatcherImpl.dispatchQueueBind(ServerMethodDispatcherImpl.java:498)
+ at org.apache.qpid.framing.amqp_8_0.QueueBindBodyImpl.execute(QueueBindBodyImpl.java:167)
+ at org.apache.qpid.server.state.AMQStateManager.methodReceived(AMQStateManager.java:204)
+ at org.apache.qpid.server.protocol.AMQMinaProtocolSession.methodFrameReceived(AMQMinaProtocolSession.java:295)
+ at org.apache.qpid.framing.AMQMethodBodyImpl.handle(AMQMethodBodyImpl.java:93)
+ at org.apache.qpid.server.protocol.AMQMinaProtocolSession.frameReceived(AMQMinaProtocolSession.java:235)
+ at org.apache.qpid.server.protocol.AMQMinaProtocolSession.dataBlockReceived(AMQMinaProtocolSession.java:191)
+ at org.apache.qpid.server.protocol.AMQPFastProtocolHandler.messageReceived(AMQPFastProtocolHandler.java:244)
+ at org.apache.mina.common.support.AbstractIoFilterChain$TailFilter.messageReceived(AbstractIoFilterChain.java:703)
+ at org.apache.mina.common.support.AbstractIoFilterChain.callNextMessageReceived(AbstractIoFilterChain.java:362)
+ at org.apache.mina.common.support.AbstractIoFilterChain.access$1200(AbstractIoFilterChain.java:54)
+ at org.apache.mina.common.support.AbstractIoFilterChain$EntryImpl$1.messageReceived(AbstractIoFilterChain.java:800)
+ at org.apache.qpid.pool.PoolingFilter.messageReceived(PoolingFilter.java:371)
+ at org.apache.mina.filter.ReferenceCountingIoFilter.messageReceived(ReferenceCountingIoFilter.java:96)
+ at org.apache.mina.common.support.AbstractIoFilterChain.callNextMessageReceived(AbstractIoFilterChain.java:362)
+ at org.apache.mina.common.support.AbstractIoFilterChain.access$1200(AbstractIoFilterChain.java:54)
+ at org.apache.mina.common.support.AbstractIoFilterChain$EntryImpl$1.messageReceived(AbstractIoFilterChain.java:800)
+ at org.apache.mina.filter.codec.support.SimpleProtocolDecoderOutput.flush(SimpleProtocolDecoderOutput.java:60)
+ at org.apache.mina.filter.codec.QpidProtocolCodecFilter.messageReceived(QpidProtocolCodecFilter.java:174)
+ at org.apache.mina.common.support.AbstractIoFilterChain.callNextMessageReceived(AbstractIoFilterChain.java:362)
+ at org.apache.mina.common.support.AbstractIoFilterChain.access$1200(AbstractIoFilterChain.java:54)
+ at org.apache.mina.common.support.AbstractIoFilterChain$EntryImpl$1.messageReceived(AbstractIoFilterChain.java:800)
+ at org.apache.qpid.pool.Event$ReceivedEvent.process(Event.java:86)
+ at org.apache.qpid.pool.Job.processAll(Job.java:110)
+ at org.apache.qpid.pool.Job.run(Job.java:149)
+ at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:885)
+ at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:907)
+ at java.lang.Thread.run(Thread.java:619)
+</programlisting>
+<!--h3--></section>
+
+ <section role="h3" id="QpidJavaFAQ-WhyistherealotofAnonymousIoServicethreads"><title>
+ Why
+ is there a lot of AnonymousIoService threads
+ </title>
+
+ <para>
+ These threads are part of the thread pool used by Mina to process
+ the socket. In the future we may provide tuning guidelines but at
+ this point we have seen no performance implications from the
+ current configuration. As the threads are part of a pool they
+ should remain inactive until required.
+ </para>
+<!--h3--></section>
+
+ <section role="h3" id="QpidJavaFAQ--22unabletocertifytheprovidedSSLcertificateusingthecurrentSSLtruststore-22whenconnectingtheManagementConsoletothebroker."><title>
+ "unable to certify the provided SSL certificate using the
+ current SSL trust store" when connecting the Management Console
+ to the broker.
+ </title>
+
+ <para>
+ You have not configured the console's SSL trust store properly,
+ see <xref linkend="qpid_Management-Console-Security"/> for
+ more details.
+ </para>
+<!--h3--></section>
+
+ <section role="h3" id="QpidJavaFAQ-Clientkeepsthrowing-27Serverdidnotrespondinatimelyfashion-27-5Cerrorcode408-3ARequestTimeout-5C."><title>
+ Client keeps throwing 'Server did not respond in a timely
+ fashion' [error code 408: Request Timeout].
+ </title>
+
+ <para>
+ Certain operations wait for a response from the Server. One such
+ operations is commit. If the server does not respond to the
+ commit request within a set time a Request Timeout [error code:
+ 408] exception is thrown (Server did not respond in a timely
+ fashion). This is to ensure that a server that has hung does not
+ cause the client process to be come unresponsive.
+ </para><para>
+ However, it is possible that the server just needs a long time to
+ process a give request. For example, sending a large persistent
+ message when using a persistent store will take some time to a)
+ Transfer accross the network and b) to be fully written to disk.
+ </para><para>
+ These situations require that the default timeout value be
+ increased. A cilent <xref linkend="qpid_System-Properties"/> 'amqj.default_syncwrite_timeout' can be set
+ on the client to increase the wait time. The default in 0.5 is
+ 30000 (30s).
+ </para>
+<!--h3--></section>
+
+ <section role="h3" id="QpidJavaFAQ-CanauseTCPKEEPALIVEorAMQPheartbeatingtokeepmyconnectionopen-3F"><title>
+ Can a use TCP_KEEPALIVE or AMQP heartbeating to keep my
+ connection open?
+ </title>
+
+ <para>
+ See <xref linkend="qpid_Configure-Broker-and-Client-Heartbeating"/>
+ </para>
+
+<!--h3--></section>
+<!--h2--></section>
+
+
+
+</section>
diff --git a/qpid/doc/book/src/Qpid-Management-Features.xml b/qpid/doc/book/src/Qpid-Management-Features.xml
new file mode 100644
index 0000000000..c90d7e97c6
--- /dev/null
+++ b/qpid/doc/book/src/Qpid-Management-Features.xml
@@ -0,0 +1,185 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+
+ 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.
+
+-->
+
+<section>
+ <title>
+ Qpid Management Features
+ </title>
+ <para>
+ <emphasis>Management tool:</emphasis> See our <xref linkend="qpid_Qpid-JMX-Management-Console"/> for
+ details of how to use various console options with the Qpid
+ management features.
+ </para>
+ <para>
+ The management of QPID is categorised into following types-
+ </para>
+ <orderedlist>
+ <listitem><para>Exchange
+ </para></listitem>
+ <listitem><para>Queue
+ </para></listitem>
+ <listitem><para>Connection
+ </para></listitem>
+ <listitem><para>Broker
+ </para></listitem>
+ </orderedlist>
+ <para>
+  <emphasis>1) Managing and Monitoring Exchanges</emphasis>: Following is
+ the list of features, which we can have available for managing
+ and monitoring an Exchange running on a Qpid Server Domain-
+ </para>
+ <orderedlist>
+ <listitem><para>Displaying the following information for monitoring purpose-
+ <orderedlist>
+ <listitem><para>The list of queues bound to the exchange along with the
+ routing keys.
+ </para></listitem>
+ <listitem><para>
+ General Exchange properties(like name,
+ durable etc).
+ </para></listitem>
+ </orderedlist>
+ </para></listitem>
+ <listitem><para>
+ Binding an existing queue with the
+ exchange.
+ </para></listitem>
+ </orderedlist>
+ <para>
+ <emphasis>2) Managing and Monitoring
+ Queues</emphasis>:  Following are the
+ features, which we can have for a Queue on a Qpid Server
+ Domain-
+ </para>
+ <orderedlist>
+ <listitem><para>
+ Displaying the following information about
+ the queue for monitoring purpose-
+ <orderedlist>
+ <listitem><para>
+ General Queue properties(like name,
+ durable, etc.)
+ </para></listitem>
+ <listitem><para>
+ The maximum size of a message that can
+ be accepted from the message producer.
+ </para></listitem>
+ <listitem><para>
+ The number of the active consumers
+ accessing the Queue.
+ </para></listitem>
+ <listitem><para>
+ The total number of
+ consumers (Active and Suspended).
+ </para></listitem>
+ <listitem><para>
+ The number of undelivered messages
+ in the Queue.
+ </para></listitem>
+ <listitem><para>
+ The total number of messages received
+ on the Queue since startup.
+ </para></listitem>
+ <listitem><para>
+ The maximum number of bytes for
+ the Queue that can be stored on the Server.
+ </para></listitem>
+ <listitem><para>The maximum number of messages for the Queue that can be
+ stored on the Server.
+ </para></listitem>
+ </orderedlist>
+ </para></listitem>
+ <listitem><para>
+ Viewing the messages on the Queue.
+ </para></listitem>
+ <listitem><para>
+ Deleting message from top of the
+ Queue.
+ </para></listitem>
+ <listitem><para>
+ Clearing the Queue.
+ </para></listitem>
+ <listitem><para>
+ Browsing the DeadMessageQueue - Messages
+ which are expired or undelivered because of some reason are
+ routed to the DeadMessageQueue.  This queue can not be
+ deleted.  [Note: The is open because it depends on how
+ these kind of messages will be handeled?]
+ </para></listitem>
+ </orderedlist>
+ <para>
+ <emphasis>3) Managing and Monitoring
+ Connections</emphasis>: Following are the
+ features, which we can have for a connection on a QPID
+ Server Domain-
+ </para>
+ <orderedlist>
+ <listitem><para>
+ Displaying general connection
+ properties(like remote address, etc.).
+ </para></listitem>
+ <listitem><para>Setting maximum number of channels allowed for a
+ connection.
+ </para></listitem>
+ <listitem><para>View all related channels and channel properties.
+ </para></listitem>
+ <listitem><para>Closing a channel.
+ </para></listitem>
+ <listitem><para>Commit or Rollback transactions of a channel, if the channel
+ is transactional.
+ </para></listitem>
+ <listitem><para>Notification for exceeding the maximum number of
+ channels.
+ </para></listitem>
+ <listitem><para>Dropping a connection.
+ </para></listitem>
+ <listitem><para>The work for <xref linkend="qpid_Network-IO-Interface"/> implies that
+ there are potentially some additional requirements
+ <orderedlist>
+ <listitem><para>Alert when tcp flow control kicks in
+ </para></listitem>
+ <listitem><para>Information available about current memory usage
+ available through JMX interface
+ </para></listitem>
+ <listitem><para>Dynamic removal of buffer bounds? (fundamentally not
+ possible with TransportIO)
+ </para></listitem>
+ <listitem><para>Management functionality added to JMX interface - UI
+ changes?
+ </para></listitem>
+ </orderedlist>
+ </para></listitem>
+ </orderedlist>
+ <para>
+ <emphasis>4) Managing the Broker</emphasis>: Features for the Broker-
+ </para>
+ <orderedlist>
+ <listitem><para>Creating an Exchange.
+ </para></listitem>
+ <listitem><para>Unregistering an Exchange.
+ </para></listitem>
+ <listitem><para>Creating a Queue.
+ </para></listitem>
+ <listitem><para>Deleting a Queue.
+ </para></listitem>
+ </orderedlist>
+</section>
diff --git a/qpid/doc/book/src/Qpid-Management-Framework.xml b/qpid/doc/book/src/Qpid-Management-Framework.xml
new file mode 100644
index 0000000000..89bfe9d95e
--- /dev/null
+++ b/qpid/doc/book/src/Qpid-Management-Framework.xml
@@ -0,0 +1,944 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+
+ 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.
+
+-->
+
+<section><title>
+ Qpid Management Framework
+ </title>
+ <itemizedlist>
+ <listitem><para>
+ <xref linkend="QpidManagementFramework-WhatIsQMF"/>
+ </para></listitem>
+ <listitem><para>
+ <xref linkend="QpidManagementFramework-GettingStartedwithQMF"/>
+ </para></listitem>
+ <listitem><para>
+ <xref linkend="QpidManagementFramework-QMFConcepts"/>
+ </para></listitem>
+ <listitem><para>
+ <itemizedlist>
+ <listitem><para>
+ <xref linkend="QpidManagementFramework-Console-2CAgent-2CandBroker"/>
+ </para></listitem>
+ <listitem><para>
+ <xref linkend="QpidManagementFramework-Schema"/>
+ </para></listitem>
+ <listitem><para>
+ <xref linkend="QpidManagementFramework-ClassKeysandClassVersioning"/>
+ </para></listitem>
+ </itemizedlist>
+ </para></listitem>
+ <listitem><para>
+ <xref linkend="QpidManagementFramework-TheQMFProtocol"/>
+ </para></listitem>
+ <listitem><para>
+ <xref linkend="QpidManagementFramework-HowtoWriteaQMFConsole"/>
+ </para></listitem>
+ <listitem><para>
+ <xref linkend="QpidManagementFramework-HowtoWriteaQMFAgent"/>
+ </para></listitem>
+ </itemizedlist>
+
+ <para>
+ Please visit the <xref linkend="qpid_QMFv2-Project-Page"/> for information
+ about the future of QMF.
+ </para>
+ <section role="h1" id="QpidManagementFramework-WhatIsQMF"><title>
+ What Is QMF
+ </title>
+
+ <para>
+ QMF (Qpid Management Framework) is a general-purpose management
+ bus built on Qpid Messaging. It takes advantage of the
+ scalability, security, and rich capabilities of Qpid to provide
+ flexible and easy-to-use manageability to a large set of
+ applications.
+ </para>
+ <!--h1--></section>
+
+ <section role="h1" id="QpidManagementFramework-GettingStartedwithQMF"><title>
+ Getting
+ Started with QMF
+ </title>
+
+ <para>
+ QMF is used through two primary APIs. The <emphasis>console</emphasis> API is
+ used for console applications that wish to access and manipulate
+ manageable components through QMF. The <emphasis>agent</emphasis> API is used
+ for application that wish to be managed through QMF.
+ </para><para>
+ The fastest way to get started with QMF is to work through the
+ "How To" tutorials for consoles and agents. For a deeper
+ understanding of what is happening in the tutorials, it is
+ recommended that you look at the <emphasis>Qmf Concepts</emphasis> section.
+ </para>
+ <!--h1--></section>
+
+ <section role="h1" id="QpidManagementFramework-QMFConcepts"><title>
+ QMF Concepts
+ </title>
+
+ <para>
+ This section introduces important concepts underlying QMF.
+ </para>
+
+
+ <section role="h2" id="QpidManagementFramework-Console-2CAgent-2CandBroker"><title>
+ Console,
+ Agent, and Broker
+ </title>
+
+ <para>
+ The major architectural components of QMF are the Console, the
+ Agent, and the Broker. Console components are the "managing"
+ components of QMF and agent components are the "managed" parts.
+ The broker is a central (possibly distributed, clustered and
+ fault-tolerant) component that manages name spaces and caches
+ schema information.
+ </para><para>
+ A console application may be a command-line utility, a
+ three-tiered web-based GUI, a collection and storage device, a
+ specialized application that monitors and reacts to events and
+ conditions, or anything else somebody wishes to develop that uses
+ QMF management data.
+ </para><para>
+ An agent application is any application that has been enhanced to
+ allow itself to be managed via QMF.
+ </para>
+ <programlisting>
+ +-------------+ +---------+ +---------------+ +-------------------+
+ | CLI utility | | Web app | | Audit storage | | Event correlation |
+ +-------------+ +---------+ +---------------+ +-------------------+
+ ^ ^ ^ ^ |
+ | | | | |
+ v v v v v
+ +---------------------------------------------------------------------------------+
+ | Qpid Messaging Bus (with QMF Broker capability) |
+ +---------------------------------------------------------------------------------+
+ ^ ^ ^
+ | | |
+ v v v
+ +----------------+ +----------------+ +----------------+
+ | Manageable app | | Manageable app | | Manageable app |
+ +----------------+ +----------------+ +----------------+
+</programlisting>
+ <para>
+ In the above diagram, the <emphasis>Manageable apps</emphasis> are agents,
+ the <emphasis>CLI utility</emphasis>, <emphasis>Web app</emphasis>, and <emphasis>Audit
+ storage</emphasis> are consoles, and <emphasis>Event correlation</emphasis> is both
+ a console and an agent because it can create events based on the
+ aggregation of what it sees.
+ </para>
+<!--h2--></section>
+
+ <section role="h2" id="QpidManagementFramework-Schema"><title>
+ Schema
+ </title>
+
+ <para>
+ A <emphasis>schema</emphasis> describes the structure of management data.
+ Each <emphasis>agent</emphasis> provides a schema that describes its
+ management model including the object classes, methods, events,
+ etc. that it provides. In the current QMF distribution, the
+ agent's schema is codified in an XML document. In the near
+ future, there will also be ways to programatically create QMF
+ schemata.
+ </para><section role="h3" id="QpidManagementFramework-Package"><title>
+ Package
+ </title>
+
+ <para>
+ Each agent that exports a schema identifies itself using a
+ <emphasis>package</emphasis> name. The package provides a unique namespace
+ for the classes in the agent's schema that prevent collisions
+ with identically named classes in other agents' schemata.
+ </para><para>
+ Package names are in "reverse domain name" form with levels of
+ hierarchy separated by periods. For example, the Qpid messaging
+ broker uses package "org.apache.qpid.broker" and the Access
+ Control List plugin for the broker uses package
+ "org.apache.qpid.acl". In general, the package name should be the
+ reverse of the internet domain name assigned to the organization
+ that owns the agent software followed by identifiers to uniquely
+ identify the agent.
+ </para><para>
+ The XML document for a package's schema uses an enclosing
+ &lt;schema&gt; tag. For example:
+ </para>
+ <programlisting>
+&lt;schema package="org.apache.qpid.broker"&gt;
+
+&lt;/schema&gt;
+</programlisting>
+<!--h3--></section>
+
+ <section role="h3" id="QpidManagementFramework-ObjectClasses"><title>
+ Object
+ Classes
+ </title>
+
+ <para>
+ <emphasis>Object classes</emphasis> define types for manageable objects. The
+ agent may create and destroy objects which are instances of
+ object classes in the schema. An object class is defined in the
+ XML document using the &lt;class&gt; tag. An object class is
+ composed of properties, statistics, and methods.
+ </para>
+ <programlisting>
+ &lt;class name="Exchange"&gt;
+ &lt;property name="vhostRef" type="objId" references="Vhost" access="RC" index="y" parentRef="y"/&gt;
+ &lt;property name="name" type="sstr" access="RC" index="y"/&gt;
+ &lt;property name="type" type="sstr" access="RO"/&gt;
+ &lt;property name="durable" type="bool" access="RC"/&gt;
+ &lt;property name="arguments" type="map" access="RO" desc="Arguments supplied in exchange.declare"/&gt;
+
+ &lt;statistic name="producerCount" type="hilo32" desc="Current producers on exchange"/&gt;
+ &lt;statistic name="bindingCount" type="hilo32" desc="Current bindings"/&gt;
+ &lt;statistic name="msgReceives" type="count64" desc="Total messages received"/&gt;
+ &lt;statistic name="msgDrops" type="count64" desc="Total messages dropped (no matching key)"/&gt;
+ &lt;statistic name="msgRoutes" type="count64" desc="Total routed messages"/&gt;
+ &lt;statistic name="byteReceives" type="count64" desc="Total bytes received"/&gt;
+ &lt;statistic name="byteDrops" type="count64" desc="Total bytes dropped (no matching key)"/&gt;
+ &lt;statistic name="byteRoutes" type="count64" desc="Total routed bytes"/&gt;
+ &lt;/class&gt;
+</programlisting>
+<!--h3--></section>
+
+
+ <section role="h3" id="QpidManagementFramework-PropertiesandStatistics"><title>
+ Properties
+ and Statistics
+ </title>
+
+ <para>
+ &lt;property&gt; and &lt;statistic&gt; tags must be placed within
+ &lt;schema&gt; and &lt;/schema&gt; tags.
+ </para><para>
+ Properties, statistics, and methods are the building blocks of an
+ object class. Properties and statistics are both object
+ attributes, though they are treated differently. If an object
+ attribute is defining, seldom or never changes, or is large in
+ size, it should be defined as a <emphasis>property</emphasis>. If an
+ attribute is rapidly changing or is used to instrument the object
+ (counters, etc.), it should be defined as a <emphasis>statistic</emphasis>.
+ </para><para>
+ The XML syntax for &lt;property&gt; and &lt;statistic&gt; have
+ the following XML-attributes:
+ </para><table><title>XML Attributes for QMF Properties and Statistics</title><tgroup cols="4">
+ <tbody>
+ <row>
+ <entry>
+ Attribute
+ </entry>
+ <entry>
+ &lt;property&gt;
+ </entry>
+ <entry>
+ &lt;statistic&gt;
+ </entry>
+ <entry>
+ Meaning
+ </entry>
+ </row>
+ <row>
+ <entry>
+ name
+ </entry>
+ <entry>
+ Y
+ </entry>
+ <entry>
+ Y
+ </entry>
+ <entry>
+ The name of the attribute
+ </entry>
+ </row>
+ <row>
+ <entry>
+ type
+ </entry>
+ <entry>
+ Y
+ </entry>
+ <entry>
+ Y
+ </entry>
+ <entry>
+ The data type of the attribute
+ </entry>
+ </row>
+ <row>
+ <entry>
+ unit
+ </entry>
+ <entry>
+ Y
+ </entry>
+ <entry>
+ Y
+ </entry>
+ <entry>
+ Optional unit name - use the singular (i.e. MByte)
+ </entry>
+ </row>
+ <row>
+ <entry>
+ desc
+ </entry>
+ <entry>
+ Y
+ </entry>
+ <entry>
+ Y
+ </entry>
+ <entry>
+ Description to annotate the attribute
+ </entry>
+ </row>
+ <row>
+ <entry>
+ references
+ </entry>
+ <entry>
+ Y
+ </entry>
+ <entry>
+  
+ </entry>
+ <entry>
+ If the type is "objId", names the referenced class
+ </entry>
+ </row>
+ <row>
+ <entry>
+ access
+ </entry>
+ <entry>
+ Y
+ </entry>
+ <entry>
+  
+ </entry>
+ <entry>
+ Access rights (RC, RW, RO)
+ </entry>
+ </row>
+ <row>
+ <entry>
+ index
+ </entry>
+ <entry>
+ Y
+ </entry>
+ <entry>
+  
+ </entry>
+ <entry>
+ "y" if this property is used to uniquely identify the
+ object. There may be more than one index property in a
+ class
+ </entry>
+ </row>
+ <row>
+ <entry>
+ parentRef
+ </entry>
+ <entry>
+ Y
+ </entry>
+ <entry>
+  
+ </entry>
+ <entry>
+ "y" if this property references an object in which this
+ object is in a child-parent relationship.
+ </entry>
+ </row>
+ <row>
+ <entry>
+ optional
+ </entry>
+ <entry>
+ Y
+ </entry>
+ <entry>
+  
+ </entry>
+ <entry>
+ "y" if this property is optional (i.e. may be
+ NULL/not-present)
+ </entry>
+ </row>
+ <row>
+ <entry>
+ min
+ </entry>
+ <entry>
+ Y
+ </entry>
+ <entry>
+  
+ </entry>
+ <entry>
+ Minimum value of a numeric attribute
+ </entry>
+ </row>
+ <row>
+ <entry>
+ max
+ </entry>
+ <entry>
+ Y
+ </entry>
+ <entry>
+  
+ </entry>
+ <entry>
+ Maximum value of a numeric attribute
+ </entry>
+ </row>
+ <row>
+ <entry>
+ maxLen
+ </entry>
+ <entry>
+ Y
+ </entry>
+ <entry>
+  
+ </entry>
+ <entry>
+ Maximum length of a string attribute
+ </entry>
+ </row>
+ </tbody>
+ </tgroup></table>
+<!--h3--></section>
+
+
+ <section role="h3" id="QpidManagementFramework-Methods"><title>
+ Methods
+ </title>
+
+ <para>
+ &lt;method&gt; tags must be placed within &lt;schema&gt; and
+ &lt;/schema&gt; tags.
+ </para><para>
+ A <emphasis>method</emphasis> is an invokable function to be performed on
+ instances of the object class (i.e. a Remote Procedure Call). A
+ &lt;method&gt; tag has a name, an optional description, and
+ encloses zero or more arguments. Method arguments are defined by
+ the &lt;arg&gt; tag and have a name, a type, a direction, and an
+ optional description. The argument direction can be "I", "O", or
+ "IO" indicating input, output, and input/output respectively. An
+ example:
+ </para>
+ <programlisting>
+ &lt;method name="echo" desc="Request a response to test the path to the management broker"&gt;
+ &lt;arg name="sequence" dir="IO" type="uint32"/&gt;
+ &lt;arg name="body" dir="IO" type="lstr"/&gt;
+ &lt;/method&gt;
+</programlisting>
+<!--h3--></section>
+
+ <section role="h3" id="QpidManagementFramework-EventClasses"><title>
+ Event Classes
+ </title>
+ <para/>
+ <!--h3--></section>
+
+ <section role="h3" id="QpidManagementFramework-DataTypes"><title>
+ Data Types
+ </title>
+
+ <para>
+ Object attributes, method arguments, and event arguments have
+ data types. The data types are based on the rich data typing
+ system provided by the AMQP messaging protocol. The following
+ table describes the data types available for QMF:
+ </para><table><title>QMF Datatypes</title><tgroup cols="2">
+ <tbody>
+ <row>
+ <entry>
+ QMF Type
+ </entry>
+ <entry>
+ Description
+ </entry>
+ </row>
+ <row>
+ <entry>
+ REF
+ </entry>
+ <entry>
+ QMF Object ID - Used to reference another QMF object.
+ </entry>
+ </row>
+ <row>
+ <entry>
+ U8
+ </entry>
+ <entry>
+ 8-bit unsigned integer
+ </entry>
+ </row>
+ <row>
+ <entry>
+ U16
+ </entry>
+ <entry>
+ 16-bit unsigned integer
+ </entry>
+ </row>
+ <row>
+ <entry>
+ U32
+ </entry>
+ <entry>
+ 32-bit unsigned integer
+ </entry>
+ </row>
+ <row>
+ <entry>
+ U64
+ </entry>
+ <entry>
+ 64-bit unsigned integer
+ </entry>
+ </row>
+ <row>
+ <entry>
+ S8
+ </entry>
+ <entry>
+ 8-bit signed integer
+ </entry>
+ </row>
+ <row>
+ <entry>
+ S16
+ </entry>
+ <entry>
+ 16-bit signed integer
+ </entry>
+ </row>
+ <row>
+ <entry>
+ S32
+ </entry>
+ <entry>
+ 32-bit signed integer
+ </entry>
+ </row>
+ <row>
+ <entry>
+ S64
+ </entry>
+ <entry>
+ 64-bit signed integer
+ </entry>
+ </row>
+ <row>
+ <entry>
+ BOOL
+ </entry>
+ <entry>
+ Boolean - True or False
+ </entry>
+ </row>
+ <row>
+ <entry>
+ SSTR
+ </entry>
+ <entry>
+ Short String - String of up to 255 bytes
+ </entry>
+ </row>
+ <row>
+ <entry>
+ LSTR
+ </entry>
+ <entry>
+ Long String - String of up to 65535 bytes
+ </entry>
+ </row>
+ <row>
+ <entry>
+ ABSTIME
+ </entry>
+ <entry>
+ Absolute time since the epoch in nanoseconds (64-bits)
+ </entry>
+ </row>
+ <row>
+ <entry>
+ DELTATIME
+ </entry>
+ <entry>
+ Delta time in nanoseconds (64-bits)
+ </entry>
+ </row>
+ <row>
+ <entry>
+ FLOAT
+ </entry>
+ <entry>
+ Single precision floating point number
+ </entry>
+ </row>
+ <row>
+ <entry>
+ DOUBLE
+ </entry>
+ <entry>
+ Double precision floating point number
+ </entry>
+ </row>
+ <row>
+ <entry>
+ UUID
+ </entry>
+ <entry>
+ UUID - 128 bits
+ </entry>
+ </row>
+ <row>
+ <entry>
+ FTABLE
+ </entry>
+ <entry>
+ Field-table - std::map in C++, dictionary in Python
+ </entry>
+ </row>
+ </tbody>
+ </tgroup></table><para>
+ In the XML schema definition, types go by different names and
+ there are a number of special cases. This is because the XML
+ schema is used in code-generation for the agent API. It provides
+ options that control what kind of accessors are generated for
+ attributes of different types. The following table enumerates the
+ types available in the XML format, which QMF types they map to,
+ and other special handling that occurs.
+ </para><table><title>XML Schema Mapping for QMF Types</title><tgroup cols="4">
+ <tbody>
+ <row>
+ <entry>
+ XML Type
+ </entry>
+ <entry>
+ QMF Type
+ </entry>
+ <entry>
+ Accessor Style
+ </entry>
+ <entry>
+ Special Characteristics
+ </entry>
+ </row>
+ <row>
+ <entry>
+ objId
+ </entry>
+ <entry>
+ REF
+ </entry>
+ <entry>
+ Direct (get, set)
+ </entry>
+ <entry>
+  
+ </entry>
+ </row>
+ <row>
+ <entry>
+ uint8,16,32,64
+ </entry>
+ <entry>
+ U8,16,32,64
+ </entry>
+ <entry>
+ Direct (get, set)
+ </entry>
+ <entry>
+  
+ </entry>
+ </row>
+ <row>
+ <entry>
+ int8,16,32,64
+ </entry>
+ <entry>
+ S8,16,32,64
+ </entry>
+ <entry>
+ Direct (get, set)
+ </entry>
+ <entry>
+  
+ </entry>
+ </row>
+ <row>
+ <entry>
+ bool
+ </entry>
+ <entry>
+ BOOL
+ </entry>
+ <entry>
+ Direct (get, set)
+ </entry>
+ <entry>
+  
+ </entry>
+ </row>
+ <row>
+ <entry>
+ sstr
+ </entry>
+ <entry>
+ SSTR
+ </entry>
+ <entry>
+ Direct (get, set)
+ </entry>
+ <entry>
+  
+ </entry>
+ </row>
+ <row>
+ <entry>
+ lstr
+ </entry>
+ <entry>
+ LSTR
+ </entry>
+ <entry>
+ Direct (get, set)
+ </entry>
+ <entry>
+  
+ </entry>
+ </row>
+ <row>
+ <entry>
+ absTime
+ </entry>
+ <entry>
+ ABSTIME
+ </entry>
+ <entry>
+ Direct (get, set)
+ </entry>
+ <entry>
+  
+ </entry>
+ </row>
+ <row>
+ <entry>
+ deltaTime
+ </entry>
+ <entry>
+ DELTATIME
+ </entry>
+ <entry>
+ Direct (get, set)
+ </entry>
+ <entry>
+  
+ </entry>
+ </row>
+ <row>
+ <entry>
+ float
+ </entry>
+ <entry>
+ FLOAT
+ </entry>
+ <entry>
+ Direct (get, set)
+ </entry>
+ <entry>
+  
+ </entry>
+ </row>
+ <row>
+ <entry>
+ double
+ </entry>
+ <entry>
+ DOUBLE
+ </entry>
+ <entry>
+ Direct (get, set)
+ </entry>
+ <entry>
+  
+ </entry>
+ </row>
+ <row>
+ <entry>
+ uuid
+ </entry>
+ <entry>
+ UUID
+ </entry>
+ <entry>
+ Direct (get, set)
+ </entry>
+ <entry>
+  
+ </entry>
+ </row>
+ <row>
+ <entry>
+ map
+ </entry>
+ <entry>
+ FTABLE
+ </entry>
+ <entry>
+ Direct (get, set)
+ </entry>
+ <entry>
+  
+ </entry>
+ </row>
+ <row>
+ <entry>
+ hilo8,16,32,64
+ </entry>
+ <entry>
+ U8,16,32,64
+ </entry>
+ <entry>
+ Counter (inc, dec)
+ </entry>
+ <entry>
+ Generates value, valueMin, valueMax
+ </entry>
+ </row>
+ <row>
+ <entry>
+ count8,16,32,64
+ </entry>
+ <entry>
+ U8,16,32,64
+ </entry>
+ <entry>
+ Counter (inc, dec)
+ </entry>
+ <entry>
+  
+ </entry>
+ </row>
+ <row>
+ <entry>
+ mma32,64
+ </entry>
+ <entry>
+ U32,64
+ </entry>
+ <entry>
+ Direct
+ </entry>
+ <entry>
+ Generates valueMin, valueMax, valueAverage, valueSamples
+ </entry>
+ </row>
+ <row>
+ <entry>
+ mmaTime
+ </entry>
+ <entry>
+ DELTATIME
+ </entry>
+ <entry>
+ Direct
+ </entry>
+ <entry>
+ Generates valueMin, valueMax, valueAverage, valueSamples
+ </entry>
+ </row>
+ </tbody>
+ </tgroup></table>
+
+ <note><title>Important</title>
+ <para>
+ When writing a schema using the XML format, types used in
+ &lt;property&gt; or &lt;arg&gt; must be types that have
+ <emphasis>Direct</emphasis> accessor style. Any type may be used in
+ &lt;statistic&gt; tags.
+ </para>
+ </note>
+
+<!--h3--></section>
+<!--h2--></section>
+
+ <section role="h2" id="QpidManagementFramework-ClassKeysandClassVersioning"><title>
+ Class
+ Keys and Class Versioning
+ </title>
+
+ <para/>
+
+<!--h2--></section>
+
+ <!--h1--></section>
+
+ <section role="h1" id="QpidManagementFramework-TheQMFProtocol"><title>
+ The QMF
+ Protocol
+ </title>
+
+ <para>
+ The QMF protocol defines the message formats and communication
+ patterns used by the different QMF components to communicate with
+ one another.
+ </para><para>
+ A description of the current version of the QMF protocol can be
+ found at <xref linkend="qpid_QMF-Protocol"/>.
+ </para><para>
+ A proposal for an updated protocol based on map-messages is in
+ progress and can be found at <xref linkend="qpid_QMF-Map-Message-Protocol"/>.
+ </para>
+<!--h1--></section>
+
+ <section role="h1" id="QpidManagementFramework-HowtoWriteaQMFConsole"><title>
+ How
+ to Write a QMF Console
+ </title>
+
+ <para>
+ Please see the <xref linkend="qpid_QMF-Python-Console-Tutorial"/> for information about using the console API with
+ Python.
+ </para>
+<!--h1--></section>
+
+ <section role="h1" id="QpidManagementFramework-HowtoWriteaQMFAgent"><title>
+ How to
+ Write a QMF Agent
+ </title>
+ <para/>
+ <!--h1--></section>
+
+
+</section>
diff --git a/qpid/doc/book/src/Qpid-Troubleshooting-Guide.xml b/qpid/doc/book/src/Qpid-Troubleshooting-Guide.xml
new file mode 100644
index 0000000000..cc642f2cdb
--- /dev/null
+++ b/qpid/doc/book/src/Qpid-Troubleshooting-Guide.xml
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+
+ 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.
+
+-->
+
+<section>
+
+ <title>
+ Qpid Troubleshooting Guide
+ </title>
+
+ <section role="h2" id="QpidTroubleshootingGuide-I-27mgettingajava.lang.UnsupportedClassVersionErrorwhenItrytostartthebroker.Whatdoesthismean-3F"><title>
+ I'm getting a java.lang.UnsupportedClassVersionError when I
+ try to start the broker. What does this mean ?
+ </title>
+
+ <para>
+ The QPID broker requires JDK 1.5 or later. If you're seeing this
+ exception you don't have that version in your path. Set JAVA_HOME
+ to the correct version and ensure the bin directory is on your
+ path.
+ </para><para>
+ java.lang.UnsupportedClassVersionError:
+ org/apache/qpid/server/Main (Unsupported major.minor version
+ 49.0)
+ at
+ java.lang.ClassLoader.defineClass(Ljava.lang.String;[BIILjava.security.ProtectionDomain;)Ljava.lang.Class;(Unknown
+ Source)
+ at
+ java.security.SecureClassLoader.defineClass(Ljava.lang.String;[BIILjava.security.CodeSource;)Ljava.lang.Class;(SecureClassLoader.java:123)
+
+ at
+ java.net.URLClassLoader.defineClass(Ljava.lang.String;Lsun.misc.Resource;)Ljava.lang.Class;(URLClassLoader.java:251)
+
+ at
+ java.net.URLClassLoader.access$100(Ljava.net.URLClassLoader;Ljava.lang.String;Lsun.misc.Resource;)Ljava.lang.Class;(URLClassLoader.java:55)
+
+ at java.net.URLClassLoader$1.run()Ljava.lang.Object;
+ (URLClassLoader.java:194)
+ at
+ jrockit.vm.AccessController.do_privileged_exc(Ljava.security.PrivilegedExceptionAction;Ljava.security.AccessControlContext;I)Ljava.lang.Object;(Unknown
+ Source)
+ at
+ jrockit.vm.AccessController.doPrivileged(Ljava.security.PrivilegedExceptionAction;Ljava.security.AccessControlContext;)Ljava.lang.Object;(Unknown
+ Source)
+ at
+ java.net.URLClassLoader.findClass(Ljava.lang.String;)Ljava.lang.Class;(URLClassLoader.java:187)
+
+ at
+ java.lang.ClassLoader.loadClass(Ljava.lang.String;Z)Ljava.lang.Class;
+ (Unknown Source)
+ at
+ sun.misc.Launcher$AppClassLoader.loadClass(Ljava.lang.String;Z)Ljava.lang.Class;(Launcher.java:274)
+
+ at
+ java.lang.ClassLoader.loadClass(Ljava.lang.String;)Ljava.lang.Class;
+
+ (Unknown Source)
+ at
+ java.lang.ClassLoader.loadClassFromNative(II)Ljava.lang.Class;
+
+ (Unknown Source)
+ </para>
+
+<!--h2--></section>
+
+ <section role="h2" id="QpidTroubleshootingGuide-I-27mhavingaproblembindingtotherequiredhost-3Aportatbrokerstartup-3F"><title>
+ I'm having a problem binding to the required host:port at
+ broker startup ?
+ </title>
+ <para>
+ This error probably indicates that another process is using the
+ port you the broker is trying to listen on. If you haven't
+ amended the default configuration this will be 5672. To check
+ what process is using the port you can use 'netstat -an |grep
+ 5672'.
+ </para><para>
+ To change the port your broker uses, either edit the config.xml
+ you are using. You can specify an alternative config.xml from the
+ one provided in /etc by using the -c flag i.e. qpid-server -c
+ &lt;my config file path&gt;.
+ </para><para>
+ You can also amend the port more simply using the -p option to
+ qpid-server i.e. qpid-server -p &lt;my port number'
+ </para>
+<!--h2--></section>
+
+ <section role="h2" id="QpidTroubleshootingGuide-I-27mhavingproblemswithmyclasspath.HowcanIensurethatmyclasspathisok-3F"><title>
+ I'm having problems with my classpath. How can I ensure that
+ my classpath is ok ?
+ </title>
+ <para>
+ When you are running the broker the classpath is taken care of
+ for you, via the manifest entries in the launch jars that the
+ qpid-server configuration file adds to the classpath.
+ </para><para>
+ However, if you are running your own client code and experiencing
+ classspath errors you need to ensure that the client-launch.jar
+ from the installed Qpid lib directory is on your classpath. The
+ manifest for this jar includes the common-launch.jar, and thus
+ all the code you need to run a client application.
+ </para>
+ </section>
+
+ <section role="h2" id="QpidTroubleshootingGuide-Ican-27tgetthebrokertostart.HowcanIdiagnosetheproblem-3F"><title>
+ I can't get the broker to start. How can I diagnose the
+ problem ?
+ </title>
+ <para>
+ Firstly have a look at the broker log file - either on stdout or
+ in $QPID_WORK/log/qpid.log or in $HOME/log/qpid.log if you
+ haven't set QPID_WORK.
+ </para><para>
+ You should see the problem logged in here via log4j and a stack
+ trace. Have a look at the other entries on this page for common
+ problems. If the log file includes a line like:
+ </para><para>
+ "2006-10-13 09:58:14,672 INFO [main] server.Main (Main.java:343)
+ - Qpid.AMQP listening on non-SSL address 0.0.0.0/0.0.0.0:5672"
+ </para><para>
+ ... then you know the broker started up. If not, then it didn't.
+ </para>
+<!--h2--></section>
+
+ <section role="h2" id="QpidTroubleshootingGuide-WhenItrytosendmessagestoaqueueI-27mgettingaerrorasthequeuedoesnotexist.WhatcanIdo-3F"><title>
+ When I try to send messages to a queue I'm getting a error as
+ the queue does not exist. What can I do ?
+ </title>
+ <para>
+ In Qpid queues need a consumer before they really exist, unless
+ you have used the virtualhosts.xml file to specify queues which
+ should always be created at broker startup. If you don't want to
+ use this config, then simply ensure that you consume first from
+ queue before staring to publish to it. See the entry on our
+ <xref linkend="qpid_Qpid-Java-FAQ"/> for more details of using the virtualhosts.xml route.
+ </para>
+<!--h2--></section>
+
+</section>
diff --git a/qpid/doc/book/src/Running-CPP-Broker.xml b/qpid/doc/book/src/Running-CPP-Broker.xml
new file mode 100644
index 0000000000..151f0cfa33
--- /dev/null
+++ b/qpid/doc/book/src/Running-CPP-Broker.xml
@@ -0,0 +1,317 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+
+ 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.
+
+-->
+
+<section id="section-Running-a-Qpid-CPP-Broker">
+ <title>
+ Running a Qpid C++ Broker
+ </title>
+
+ <section role="h2" id="RASC-BuildingtheCppBrokerandClientLibraries"><title>
+ Building the
+ C++ Broker and Client Libraries
+ </title>
+ <para>
+ The root directory for the C++ distribution is named
+ qpidc-0.4. The README file in that directory gives
+ instructions for building the broker and client libraries. In
+ most cases you will do the following:
+ </para>
+ <programlisting>
+[qpidc-0.4]$ ./configure
+[qpidc-0.4]$ make
+</programlisting>
+ <!--h2--></section>
+ <section role="h2" id="RASC-RunningtheCppBroker"><title>
+ Running the C++ Broker
+ </title>
+ <para>
+ Once you have built the broker and client libraries, you can
+ start the broker from the command line:
+ </para>
+ <programlisting>
+[qpidc-0.4]$ src/qpidd
+</programlisting>
+ <para>
+ Use the --daemon option to run the broker as a daemon
+ process:
+ </para>
+ <programlisting>
+[qpidc-0.4]$ src/qpidd --daemon
+</programlisting>
+ <para>
+ You can stop a running daemon with the --quit option:
+ </para>
+ <programlisting>
+[qpidc-0.4]$ src/qpidd --quit
+</programlisting>
+ <para>
+ You can see all available options with the --help option
+ </para>
+ <programlisting>
+[qpidc-0.4]$ src/qpidd --help
+</programlisting>
+ <!--h2--></section>
+ <section role="h2" id="RASC-Mostcommonquestionsgettingqpiddrunning"><title>
+ Most
+ common questions getting qpidd running
+ </title>
+ <section role="h3" id="RASC-Errorwhenstartingbroker-3A-22nodatadirectory-22"><title>
+ Error
+ when starting broker: "no data directory"
+ </title>
+ <para>
+ The qpidd broker requires you to set a data directory or specify
+ --no-data-dir (see help for more details). The data
+ directory is used for the journal, so it is important when
+ reliability counts. Make sure your process has write permission
+ to the data directory.
+ </para><para>
+ The default location is
+ </para>
+ <programlisting>
+/lib/var/qpidd
+</programlisting>
+ <para>
+ An alternate location can be set with --data-dir
+ </para>
+ <!--h3--></section>
+ <section role="h3" id="RASC-Errorwhenstartingbroker-3A-22thatprocessislocked-22"><title>
+ Error
+ when starting broker: "that process is locked"
+ </title>
+ <para>
+ Note that when qpidd starts it creates a lock file is data
+ directory are being used. If you have a un-controlled exit,
+ please mail
+ the trace from the core to the dev@qpid.apache.org mailing list.
+ To clear the lock run
+ </para>
+ <programlisting>
+./qpidd -q
+</programlisting>
+ <para>
+ It should also be noted that multiple brokers can be run on the
+ same host. To do so set alternate data directories for each qpidd
+ instance.
+ </para>
+ <!--h3--></section>
+ <section role="h3" id="RASC-Usingaconfigurationfile"><title>
+ Using a configuration
+ file
+ </title>
+ <para>
+ Each option that can be specified on the command line can also be
+ specified in a configuration file. To see available options, use
+ --help on the command line:
+ </para>
+ <programlisting>
+./qpidd --help
+</programlisting>
+ <para>
+ A configuration file uses name/value pairs, one on each line. To
+ convert a command line option to a configuration file entry:
+ </para><para>
+ a.) remove the '--' from the beginning of the option.
+ b.) place a '=' between the option and the value (use
+ <emphasis>yes</emphasis> or <emphasis>true</emphasis> to enable options that take no
+ value when specified on the command line).
+ c.) place one option per line.
+ </para><para>
+ For instance, the --daemon option takes no value, the
+ --log-to-syslog option takes the values yes or
+ no. The following configuration file sets these two
+ options:
+ </para>
+ <programlisting>
+daemon=yes
+log-to-syslog=yes
+</programlisting>
+ <!--h3--></section>
+ <section role="h3" id="RASC-CanIuseanyLanguageclientwiththeCppBroker-3F"><title>
+ Can I use
+ any Language client with the C++ Broker?
+ </title>
+ <para>
+ Yes, all the clients work with the C++ broker; it is written in
+ C+<emphasis>, but uses the AMQP wire protocol. Any broker can be used
+ with any client that uses the same AMQP version. When running the
+ C</emphasis>+ broker, it is highly recommended to run AMQP 0-10.
+ </para><para>
+ Note that JMS also works with the C++ broker.
+ </para>
+ <!--h3--></section>
+ <!--h2--></section>
+ <section role="h2" id="RASC-Authentication"><title>
+ Authentication
+ </title>
+ <section role="h3" id="RASC-Linux"><title>
+ Linux
+ </title>
+ <para>
+ The PLAIN authentication is done on a username+password, which is
+ stored in the sasldb_path file. Usernames and passwords can be
+ added to the file using the command:
+ </para>
+ <programlisting>
+saslpasswd2 -f /var/lib/qpidd/qpidd.sasldb -u &lt;REALM&gt; &lt;USER&gt;
+</programlisting>
+ <para>
+ The REALM is important and should be the same as the
+ --auth-realm
+ option to the broker. This lets the broker properly find the user
+ in
+ the sasldb file.
+ </para><para>
+ Existing user accounts may be listed with:
+ </para>
+ <programlisting>
+sasldblistusers2 -f /var/lib/qpidd/qpidd.sasldb
+</programlisting>
+ <para>
+ NOTE: The sasldb file must be readable by the user running the
+ qpidd daemon, and should be readable only by that user.
+ </para>
+ <!--h3--></section>
+ <section role="h3" id="RASC-Windows"><title>
+ Windows
+ </title>
+ <para>
+ On Windows, the users are authenticated against the local
+ machine. You should add the appropriate users using the standard
+ Windows tools (Control Panel-&gt;User Accounts). To run many of
+ the examples, you will need to create a user "guest" with
+ password "guest".
+ </para><para>
+ If you cannot or do not want to create new users, you can run
+ without authentication by specifying the no-auth option to the
+ broker.
+ </para>
+ <!--h3--></section>
+ <!--h2--></section>
+
+ <section role="h2" id="RASC-Slightlymorecomplexconfiguration"><title>
+ Slightly more
+ complex configuration
+ </title>
+ <para>
+ The easiest way to get a full listing of the broker's options are
+ to use the --help command, run it locally for the latest set of
+ options. These options can then be set in the conf file for
+ convenience (see above)
+ </para>
+ <programlisting>
+./qpidd --help
+
+Usage: qpidd OPTIONS
+Options:
+ -h [ --help ] Displays the help message
+ -v [ --version ] Displays version information
+ --config FILE (/etc/qpidd.conf) Reads configuration from FILE
+
+Module options:
+ --module-dir DIR (/usr/lib/qpidd) Load all .so modules in this directory
+ --load-module FILE Specifies additional module(s) to be loaded
+ --no-module-dir Don't load modules from module directory
+
+Broker Options:
+ --data-dir DIR (/var/lib/qpidd) Directory to contain persistent data generated by the broker
+ --no-data-dir Don't use a data directory. No persistent
+ configuration will be loaded or stored
+ -p [ --port ] PORT (5672) Tells the broker to listen on PORT
+ --worker-threads N (3) Sets the broker thread pool size
+ --max-connections N (500) Sets the maximum allowed connections
+ --connection-backlog N (10) Sets the connection backlog limit for the
+ server socket
+ --staging-threshold N (5000000) Stages messages over N bytes to disk
+ -m [ --mgmt-enable ] yes|no (1) Enable Management
+ --mgmt-pub-interval SECONDS (10) Management Publish Interval
+ --ack N (0) Send session.ack/solicit-ack at least every
+ N frames. 0 disables voluntary ack/solitict
+ -ack
+
+Daemon options:
+ -d [ --daemon ] Run as a daemon.
+ -w [ --wait ] SECONDS (10) Sets the maximum wait time to initialize the
+ daemon. If the daemon fails to initialize, prints
+ an error and returns 1
+ -c [ --check ] Prints the daemon's process ID to stdout and
+ returns 0 if the daemon is running, otherwise
+ returns 1
+ -q [ --quit ] Tells the daemon to shut down
+Logging options:
+ --log-output FILE (stderr) Send log output to FILE. FILE can be a file name
+ or one of the special values:
+ stderr, stdout, syslog
+ -t [ --trace ] Enables all logging
+ --log-enable RULE (error+) Enables logging for selected levels and component
+ s. RULE is in the form 'LEVEL+:PATTERN'
+ Levels are one of:
+ trace debug info notice warning error critical
+ For example:
+ '--log-enable warning+' logs all warning, error
+ and critical messages.
+ '--log-enable debug:framing' logs debug messages
+ from the framing namespace. This option can be
+ used multiple times
+ --log-time yes|no (1) Include time in log messages
+ --log-level yes|no (1) Include severity level in log messages
+ --log-source yes|no (0) Include source file:line in log messages
+ --log-thread yes|no (0) Include thread ID in log messages
+ --log-function yes|no (0) Include function signature in log messages
+</programlisting>
+ <!--h2--></section>
+ <section role="h2" id="RASC-Loadingextramodules"><title>
+ Loading extra modules
+ </title>
+ <para>
+ By default the broker will load all the modules in the module
+ directory, however it will NOT display options for modules that
+ are not loaded. So to see the options for extra modules loaded
+ you need to load the module and then add the help command like
+ this:
+ </para>
+ <programlisting>
+./qpidd --load-module libbdbstore.so --help
+Usage: qpidd OPTIONS
+Options:
+ -h [ --help ] Displays the help message
+ -v [ --version ] Displays version information
+ --config FILE (/etc/qpidd.conf) Reads configuration from FILE
+
+
+ / .... non module options would be here ... /
+
+
+Store Options:
+ --store-directory DIR Store directory location for persistence (overrides
+ --data-dir)
+ --store-async yes|no (1) Use async persistence storage - if store supports
+ it, enables AIO O_DIRECT.
+ --store-force yes|no (0) Force changing modes of store, will delete all
+ existing data if mode is changed. Be SURE you want
+ to do this!
+ --num-jfiles N (8) Number of files in persistence journal
+ --jfile-size-pgs N (24) Size of each journal file in multiples of read
+ pages (1 read page = 64kiB)
+</programlisting>
+<!--h2--></section>
+</section>
diff --git a/qpid/doc/book/src/SASL-Compatibility.xml b/qpid/doc/book/src/SASL-Compatibility.xml
new file mode 100644
index 0000000000..ad223792b5
--- /dev/null
+++ b/qpid/doc/book/src/SASL-Compatibility.xml
@@ -0,0 +1,70 @@
+<!--
+ -
+ - 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.
+ -
+ -->
+h2. Qpid Interoperability Documentation
+
+This page documents the various interoperable features of the Qpid clients.
+
+
+h3. SASL
+{anchor:sasl}
+h4. Standard Mechanisms
+[SASL Mechanisms |http://en.wikipedia.org/wiki/Simple_Authentication_and_Security_Layer#SASL_Mechanisms]
+
+This table list the various SASL mechanisms that each component supports. The version listed shows when this
+functionality was added to the product.
+
+|| Component || ANONYMOUS || CRAM-MD5 || DIGEST-MD5 || EXTERNAL || GSSAPI/Kerberos || PLAIN ||
+| C++ Broker |M3 |M3 | M3 |0.8\[[#1]\]|M3 | M1 |
+| C++ Client |M3 |0.5 | 0.5 |0.8\[[#1]\]| | M1 |
+| Java Broker | | M1 | | | | M1 |
+| Java Client | | M1 | | M1 | | M1 |
+| .Net Client | M2 | M2 | M2 | M2 | | M2 |
+| Python Client |0.6\[[#2]\]|0.6\[[#2]\]|0.6\[[#2]\] |0.6\[[#2]\]|0.6\[[#2]\] | M4 |
+| Ruby Client |0.6\[[#2]\]|0.6\[[#2]\]|0.6\[[#2]\] |0.6\[[#2]\]|0.6\[[#2]\] | M4 |
+
+{anchor:1}
+1: Only enabled for client authenticated SSL connections.
+{anchor:2}
+2: On linux only via cyrus-sasl integration.
+
+h4. Custom Mechanisms
+
+There have been some custom mechanisms added to our implementations.
+
+|| Component || AMQPLAIN || CRAM-MD5-HASHED ||
+| C++ Broker | | |
+| C++ Client | | |
+| Java Broker | M1 | M2 |
+| Java Client | M1 | M2 |
+| .Net Client | | |
+| Python Client | M2 | |
+| Ruby Client | M2 | |
+
+
+h5. AMQPLAIN
+
+h5. CRAM-MD5-HASHED
+
+The Java SASL implementations require that you have the password of the user to validate the incoming request. This then means that the user's password must be stored on disk. For this to be secure either the broker must encrypt the password file or the need for the password being stored must be removed.
+
+The CRAM-MD5-HASHED SASL plugin removes the need for the plain text password to be stored on disk. The mechanism defers all functionality to the build in CRAM-MD5 module the only change is on the client side where it generates the hash of the password and uses that value as the password. This means that the Java Broker only need store the password hash on the file system. While a one way hash is not very secure compared to other forms of encryption in environments where the having the password in plain text is unacceptable this will provide and additional layer to protect the password. In particular this offers some protection where the same password may be shared amongst many systems. It offers no real extra protection against attacks on the broker (the secret is now the hash rather than the password).
+
+
diff --git a/qpid/doc/book/src/SSL.xml b/qpid/doc/book/src/SSL.xml
new file mode 100644
index 0000000000..a9a5cb953a
--- /dev/null
+++ b/qpid/doc/book/src/SSL.xml
@@ -0,0 +1,180 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+
+ 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.
+
+-->
+
+<section><title>
+ SSL
+ </title>
+
+ <section role="h1" id="SSL-SSLHowto"><title>
+ SSL How to
+ </title>
+
+ <section role="h2" id="SSL-C-5Cbroker-28M4andup-29"><title>
+ C++ broker (M4 and up)
+ </title>
+ <itemizedlist>
+ <listitem><para>You need to get a certificate signed by a CA, trusted by your
+ client.
+ </para></listitem>
+ </itemizedlist><itemizedlist>
+ <listitem><para>If you require client authentication, the clients certificate
+ needs to be signed by a CA trusted by the broker.
+ </para></listitem>
+ </itemizedlist><itemizedlist>
+ <listitem><para>Setting up the certificates for testing.
+ <itemizedlist>
+ <listitem><para>For testing purposes you could use the <xref linkend="qpid_gtstd"/> to setup your certificates.
+ </para></listitem>
+ <listitem><para>In summary you need to create a root CA and import it to
+ the brokers certificate data base.
+ </para></listitem>
+ <listitem><para>Create a certificate for the broker, sign it using the
+ root CA and then import it into the brokers certificate data
+ base.
+ </para></listitem>
+ </itemizedlist>
+ </para></listitem>
+ </itemizedlist><itemizedlist>
+ <listitem><para>Load the acl module using --load-module or if loading more
+ than one module, copy ssl.so to the location pointed by
+ --module-dir
+
+ <programlisting>
+Ex if running from source. ./qpidd --load-module /libs/ssl.so
+</programlisting>
+
+ </para></listitem>
+ </itemizedlist><itemizedlist>
+ <listitem><para>Specify the password file (a plain text file with the
+ password), certificate database and the brokers certificate name
+ using the following options
+
+ <programlisting>
+Ex ./qpidd ... --ssl-cert-password-file ~/pfile --ssl-cert-db ~/server_db/ --ssl-cert-name localhost.localdomain
+</programlisting>
+
+ </para></listitem>
+ </itemizedlist><itemizedlist>
+ <listitem><para>If you require client authentication you need to add
+ --ssl-require-client-authentication as a command line argument.
+ </para></listitem>
+ </itemizedlist><itemizedlist>
+ <listitem><para>Please note that the default port for SSL connections is
+ 5671, unless specified by --ssl-port
+ </para></listitem>
+ </itemizedlist><para>
+ Here is an example of a broker instance that requires SSL client
+ side authenticaiton
+ </para>
+ <programlisting>
+./qpidd ./qpidd --load-module /libs/ssl.so --ssl-cert-password-file ~/pfile --ssl-cert-db ~/server_db/ --ssl-cert-name localhost.localdomain --ssl-require-client-authentication
+</programlisting>
+ <!--h2--></section>
+ <section role="h2" id="SSL-JavaClient-28M4andup-29"><title>
+ Java Client (M4 and up)
+ </title>
+ <itemizedlist>
+ <listitem><para>This guide is for connecting with the Qpid c++ broker.
+ </para></listitem>
+ </itemizedlist><itemizedlist>
+ <listitem><para>Setting up the certificates for testing. In summary,
+ <itemizedlist>
+ <listitem><para>You need to import the trusted CA in your trust store and
+ keystore
+ </para></listitem>
+ <listitem><para>Generate keys for the certificate in your key store
+ </para></listitem>
+ <listitem><para>Create a certificate request using the generated keys
+ </para></listitem>
+ <listitem><para>Create a certficate using the request, signed by the
+ trusted CA.
+ </para></listitem>
+ <listitem><para>Import the signed certificate into your keystore.
+ </para></listitem>
+ </itemizedlist>
+ </para></listitem>
+ </itemizedlist><itemizedlist>
+ <listitem><para>Pass the following JVM arguments to your client.
+
+ <programlisting>
+-Djavax.net.ssl.keyStore=/home/bob/ssl_test/keystore.jks
+ -Djavax.net.ssl.keyStorePassword=password
+ -Djavax.net.ssl.trustStore=/home/bob/ssl_test/certstore.jks
+ -Djavax.net.ssl.trustStorePassword=password
+</programlisting>
+
+ </para></listitem>
+ </itemizedlist>
+ <!--h2--></section>
+
+ <section role="h2" id="SSL-.NetClient-28M4andup-29"><title>
+ .Net Client (M4 and up)
+ </title>
+ <itemizedlist>
+ <listitem><para>If the Qpid broker requires client authentication then you
+ need to get a certificate signed by a CA, trusted by your client.
+ </para></listitem>
+ </itemizedlist><para>
+ Use the connectSSL instead of the standard connect method of the
+ client interface.
+ </para><para>
+ connectSSL signature is as follows:
+ </para>
+ <programlisting>
+public void connectSSL(String host, int port, String virtualHost, String username, String password, String serverName, String certPath, bool rejectUntrusted)
+</programlisting>
+ <para>
+ Where
+ </para><itemizedlist>
+ <listitem><para>host: Host name on which a Qpid broker is deployed
+ </para></listitem>
+ <listitem><para>port: Qpid broker port
+ </para></listitem>
+ <listitem><para>virtualHost: Qpid virtual host name
+ </para></listitem>
+ <listitem><para>username: User Name
+ </para></listitem>
+ <listitem><para>password: Password
+ </para></listitem>
+ <listitem><para>serverName: Name of the SSL server
+ </para></listitem>
+ </itemizedlist><itemizedlist>
+ <listitem><para>certPath: Path to the X509 certificate to be used when the
+ broker requires client authentication
+ </para></listitem>
+ <listitem><para>rejectUntrusted: If true connection will not be established
+ if the broker is not trusted (the server certificate must be
+ added in your truststore)
+ </para></listitem>
+ </itemizedlist>
+ <!--h2--></section>
+
+ <section role="h2" id="SSL-Python-26RubyClient-28M4andup-29"><title>
+ Python &amp;
+ Ruby Client (M4 and up)
+ </title>
+ <para>
+ Simply use amqps:// in the URL string as defined above
+ </para>
+ <!--h2--></section>
+ <!--h1--></section>
+</section>
diff --git a/qpid/doc/book/src/Security-Plugins.xml b/qpid/doc/book/src/Security-Plugins.xml
new file mode 100644
index 0000000000..55cd651bb5
--- /dev/null
+++ b/qpid/doc/book/src/Security-Plugins.xml
@@ -0,0 +1,624 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+
+ 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.
+
+-->
+<section xmlns="http://docbook.org/ns/docbook"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://docbook.org/ns/docbook http://www.docbook.org/xml/5.0/xsd/docbook.xsd"
+ version="5.0"
+ label="Security-Plugins-Documentation">
+ <title>Security Plugins Documentation</title>
+
+ <section role="h2" label="SPD-Introduction">
+ <title>Introduction</title>
+ <para>
+ This document describes the structure and design of Qpid security plugins, for
+ the Java broker. In particular, the new <emphasis>Access Control</emphasis> plugin, which implements
+ the same ACL file syntax as the C++ broker, is examined in detail. The security
+ plugins use the broker's OSGi bundle functionality to manage their lifecycle,
+ and the <code>ConfigurationPlugin</code> mechanism to manage their configuration via the
+ Apache commons configuration XML configuration file.
+ </para>
+ <para>
+ The Java interfaces and packages used by the security plugins are described here,
+ although the Javadoc documentation generated from the source should also be
+ consulted, and as always reading the source should provide further insight and information.
+ </para>
+ </section>
+ <section role="h2" label="SPD-Use-Cases">
+ <title>Use Cases</title>
+ <para>
+ The following use cases were identified and used to drive the design and development
+ of both the security plugin mechanism in general, and the access control plugin in particular.
+ </para>
+ <itemizedlist>
+ <listitem>
+ <para>
+ Allow access to broker functions to be controlled by an ACL, with the checks being
+ carried out independently of the mechanism used to access the broker. This would
+ mean that a single <literal>CREATE </literal> permission would apply whether the queue was
+ created when a user logged in and used it, or if that user connected to the broker
+ via JMX or QMF and used the management operations to create the queue.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Permissions must be definable at a virtualhost level, with fallback to global
+ permissions. This allows access to be granted for operations only on a certain
+ host, while global operations such as broker administration can be defined at
+ the global level. It also allows default behaviour to be specified globally and
+ then overridden on a per-host basis.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ The ACL mechanism controls access to operations on particular objects for all users,
+ if at least one user has a rule controlling access to that operation on that type of
+ object. This means that all users requiring access to a particular operation must be
+ configured. The default behaviour will be to deny access.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ It should be possible for the addition of one access control rule to trigger the
+ addition of other rules, to simplify creation of rulesets.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ The behaviour of the access control mechanism should be configurable.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ The Java and C++ brokers should share a common configuration file format.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ It should be possible to configure access to not just internal broker application
+ objects, but to the management operations and attributes of the broker, as well
+ as to external objects such as plugins.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ As long as a suitably authenticated channel is used to connect, access control
+ rules should be applied when performing operations on broker objects. This does
+ not hold when, for example, an operator has local access and is using JConsole
+ to manage the broker.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </section>
+ <section role="h2" label="SPD-Java-Interfaces-Packages-Classes">
+ <title>Java Interfaces, Packages and Classes</title>
+ <para>
+ This section describes the Java artifacts that are involved in security plugin development.
+ They are mostly contained in the package <code>org.apache.qpid.server.security</code> which
+ is part of the broker code. It is recommended that a package prefix is chosen for new
+ security plugins, and this should be used to form the packages for the implementing classes.
+ </para>
+ <para>
+ In general, when creating a new plugin, you need three classes. These would be the main
+ <code>PluginName</code> class, which should implement the <code>SecurityPlugin</code>
+ interface and have a public static instance of an anonymous internal classes that implements
+ <code>SecurityPluginfactory</code>. Additionally, the <code>PluginNameConfiguration</code>
+ class, which should implement the <code>ConfigurationPlugin</code> interface and have a
+ public static instance of an anonymous internal classes that implements
+ <code>ConfigurationPluginfactory</code>, and finally the <code>PluginNameActivator</code>
+ class, which should extend the <code>SecurityPluginActivator</code> abstract class
+ and implement the required methods exposing the factories from the other classes.
+ </para>
+ <para>
+ These classes need to be visible from the broker, so they should be placed in the
+ <code>org.apache.qpid.server.security.pluginname.plugins</code> package, which should be
+ listed in the manifest file. Any internal classes for the plugin should be placed in
+ the <code>org.apache.qpid.server.security.pluginname.config</code> package which
+ should be marked as provate in the manifest.
+ </para>
+ <para>
+ If logging using the actor and subject framework is required, the property file should
+ be located in the <code>org.apache.qpid.server.security.pluginname.logging</code>
+ package, and this should also be exported in the manifest file.
+ </para>
+ <section role="h3" label="SPD-OSGi">
+ <title>OSGi</title>
+ <para>
+ The security plugins are now loaded using the <emphasis>Felix</emphasis> OSGi container, which is started
+ as an embedded process inside the broker. This loads all plugin .jar files from the
+ directory named in the <code>plugin-directory</code> configuration element, cacheing them in the
+ <code>cache-directory</code> directory. Note that, at present, the cache directory is cleared at
+ startup, although this behaviour may change. To create OSGi plugin bundles, a manifest
+ file - <code>MANIFEST.MF</code> is created that specifies certain attributes of the bundle. A
+ sample manifest file for one of the security plugins is shown below.
+ </para>
+ <programlisting>
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Qpid Broker-Plugins PluginName
+Bundle-SymbolicName: broker-plugins-pluginname
+Bundle-Description: Name description.
+Bundle-License: http://www.apache.org/licenses/LICENSE-2.0.txt
+Bundle-DocURL: http://www.apache.org/qpid/pluginname.html
+Bundle-Version: 1.0.0
+Bundle-Activator: org.apache.qpid.server.security.pluginname.plugins.PluginNameActivator
+Bundle-RequiredExecutionEnvironment: JavaSE-1.5
+Bundle-ActivationPolicy: lazy
+Import-Package: org.apache.qpid
+Private-Package: org.apache.qpid.server.security.pluginname.config,
+ org.apache.qpid.server.security.pluginname.logging
+Export-Package: org.apache.qpid.server.security.pluginname.plugins
+ </programlisting>
+ <para>
+ The complete list of packages to import will be determined by the actual operation of
+ the plugin, however the number of exported packages should be kept to a minimum.
+ </para>
+ </section>
+ <section role="h3" label="SPD-Plugin">
+ <title>Plugin</title>
+ <para>
+ This is the main interface to be extended by all plugins. It contains a
+ method that allows configuration via the <code>ConfigurationPlugin</code>
+ mechanism.
+ </para>
+ <programlisting>
+public void configure(ConfigurationPlugin config);
+ </programlisting>
+ </section>
+ <section role="h3" label="SPD-PluginFactory">
+ <title>PluginFactory and SecurityPluginFactory</title>
+ <para>
+ These factories are used to initialise instances of plugins and configure them appropriately.
+ The factories are managed by the OSGI framework started by the <code>PluginManager</code>,
+ which is also used to retrieve the instances.
+ </para>
+ <programlisting>
+public Class&lt;P&gt; getPluginClass();
+public String getPluginName();
+public P newInstance(ConfigurationPlugin config) throws ConfigurationException;
+ </programlisting>
+ </section>
+ <section role="h3" label="SPD-SecurityPlugin">
+ <title>SecurityPlugin</title>
+ <para>
+ This is the interface that defines security plugins. The <code>getDefault</code> method
+ returns the default result for the plugin when no configuration is found for some
+ situation.
+ </para>
+ <para>
+ The <code>authorise</code> method is the main entry-point to the plugin, and is called
+ by the <code>SecurityManager</code> with the relevant paramaters. Similarly, the
+ <code>access</code> method is used for the special case of controlling access to
+ the entire virtual host, and the <code></code>
+ </para>
+ <programlisting>
+Result getDefault();
+Result access(ObjectType objectType, Object instance);
+Result authorise(Operation operation, ObjectType objectType, ObjectProperties properties);
+ </programlisting>
+ </section>
+ <section role="h3" label="SPD-SecurityPluginActivator">
+ <title>SecurityPluginActivator</title>
+ <para>
+ The activator registers the factories with the OSGI framework, based on the
+ implementations of the abstract methods.
+ </para>
+ <programlisting>
+public abstract SecurityPluginFactory getFactory();
+public abstract ConfigurationPluginFactory getConfigurationFactory();
+ </programlisting>
+ </section>
+ <section role="h3" label="SPD-AbstractPlugin">
+ <title>AbstractPlugin</title>
+ <para>
+ This is a simple parent class, which allows a common point of extension
+ for shared plugin code. Currently it simply implements the interface with
+ abstract methods.
+ </para>
+ <programlisting>
+public abstract Result access(ObjectType object, Object instance);
+public abstract Result authorise(Operation operation, ObjectType object, ObjectProperties properties);
+ </programlisting>
+ </section>
+ <section role="h3" label="SPD-AbstractProxyPlugin">
+ <title>AbstractProxyPlugin</title>
+ <para>
+ This class is designed to be extended by plugins that only wish to take part in a subset
+ of the possible security descisions. Normally, a call to the <code>authorise</code> method
+ is proxied to one of the provided methods, based on the operation, for example a <literal>CONSUME</literal>
+ access control check would be proxied to the <code>authoriseConsume</code> method with
+ the appropriate paramaters set. The default behaviour is to return <literal>ABSTAIN</literal>, meaning
+ the plugin does not handle this type of operation. If a method is overridden, it can then perform
+ whatever security checks are required and return <literal>ALLOWED</literal> or <literal>DENIED</literal>
+ as appropriate.
+ </para>
+ <programlisting>
+public Result authoriseConsume(ObjectType object, ObjectProperties properties);
+public Result authorisePublish(ObjectType object, ObjectProperties properties);
+public Result authoriseCreate(ObjectType object, ObjectProperties properties);
+public Result authoriseAccess(ObjectType object, ObjectProperties properties);
+public Result authoriseBind(ObjectType object, ObjectProperties properties);
+public Result authoriseUnbind(ObjectType object, ObjectProperties properties);
+public Result authoriseDelete(ObjectType object, ObjectProperties properties);
+public Result authorisePurge(ObjectType object, ObjectProperties properties);
+public Result authoriseExecute(ObjectType object, ObjectProperties properties);
+public Result authoriseUpdate(ObjectType object, ObjectProperties properties);
+public Result accessVirtualhost(Object instance);
+ </programlisting>
+ </section>
+ </section>
+ <section role="h2" label="SPD-Access-Control-Security-Plugin">
+ <title>Access Control Security Plugin</title>
+ <para>
+ This security plugin implements access control using the same configuration file syntax as the
+ C++ broker. The classes are all in sub-packages of the <code>org.apache.qpid.server.security.access</code>
+ package. The exposed classes consist of the plugoin itself, its OSGi activator and the configuration
+ plugin, as well as the properties file and generated code for logging. The private, internal classes,
+ consist of the ruleset implementation for managing access control list rules. The plugin also makes
+ extensive use of the enumerations provided by the broker as part of the security plugin interfaces,
+ for operations, objects and permissions.
+ </para>
+ <section role="h3" label="SPD-ACL-Enumerations">
+ <title>Enumerations</title>
+ <para>
+ These enumerations are used to define exactly what a security plugin can control.
+ </para>
+ <para>
+ The <code>ObjectProperties</code> and <code>ObjectProperties.Property</code> lalala
+ </para>
+ <para>
+ The <code>ObjectType</code>
+ </para>
+ <para>
+ The <code>Operation</code>
+ </para>
+ <para>
+ The <code>Permission</code>
+ </para>
+ </section>
+ <section role="h3" label="SPD-ACL-Configuration">
+ <title>Configuration</title>
+ <para>
+ Security plugins are configurable using the Qpid XML configuration file, under the <code>&lt;security&gt;</code>
+ element. This can be either inside the main <code>&lt;broker /&gt;</code> element, as a global plugin affecting
+ all virtual hosts, or under a <code>&lt;virtualhosts&gt;&lt;virtualhost&gt;&lt;name&gt;</code> element, where
+ the <code>&lt;name&gt;</code> element is the name of the virtual host that is to be configured. Each security
+ plugin must register the elements it expects to process using a <code>ConfigurationPlugin</code>, which is
+ documented elsewhere.
+ </para>
+ <para>
+ The plugins are checked in order, first for the virtual host, then globally, and the first <literal>ALLOWED</literal> or
+ <literal>DENIED</literal> response is used.
+ </para>
+ <para>
+ The ACL configuration file is specified via the contents of the <code>&lt;aclv2&gt;</code> element. This is simply
+ the path to the file, which is a plain text format, and is parseable by both Java and C++ brokers. The path can be
+ specified with embedded property value interpolation, for environment variables or other properties defined in the
+ configuration file.
+ </para>
+ <programlisting>
+<![CDATA[
+<security>
+ <!-- global access control configuration file -->
+ <aclv2>${QPID_HOME}/etc/global-security-config.txt</aclv2>
+</security>
+]]>
+ </programlisting>
+ <section role="h4" label="SPD-ACL-File-Format">
+ <title>File Format</title>
+ <para>
+ The file format is described below.
+ </para>
+ <itemizedlist>
+ <listitem>
+ <para>
+ Whitespace is considered to be any ASCII
+ byte with a value below <literal>0x20</literal>, and is
+ ignored when it occurs between tokens.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Continuations using the <literal>\</literal>
+ character (ASCII <literal>0x5c</literal>) are allowed
+ anywhere on a line, and
+ can consist of a blank line with a continuation
+ character as the last non-whitespace token
+ </para>
+ <programlisting>
+group group1 name1 name2 \
+ name3 name4 \
+ name5
+acl allow group1 create queue \
+ property1 = "value1" \
+ property2 \
+ = "value2"
+ </programlisting>
+ </listitem>
+ <listitem>
+ <para>
+ Comments are line-style comments, and any text after
+ an un-quoted <literal>#</literal> (ASCII <literal>0x23</literal>)
+ are ignored, including continuations. The <literal>#</literal>
+ charater may appear in a quoted string.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Quoted strings consist of any ASCII inside matching pairs of
+ <literal>'</literal> or <literal>"</literal> (ASCII <literal>0x27</literal>
+ and <literal>0x22</literal>) characters, including any
+ otherwise special characters.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Tokens are <emphasis>NOT</emphasis> case sensitive, but quoted
+ strings <emphasis>ARE</emphasis>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ The <literal>=</literal> (ASCII <literal>0x3d</literal>) character
+ is special, and is used to indicate property value assignment.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Wildcards are specified using the <literal>*</literal> (ASCII
+ <literal>0x2a</literal>) character in a property value string,
+ which may be quoted.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Empty lines and lines that contain only whitespace are ignored.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ The keyword <literal>all</literal> is reserved, and matches all individuals,
+ groups and actions. It may be used in place of a group or
+ individual name and/or an action - eg <literal>acl allow all all</literal>,
+ <literal>acl deny all all</literal> or <literal>acl deny user1 all</literal>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Rules are interpreted from the top of the file down until the
+ name match is obtained; at which point processing stops.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ The last line of the file (whether present or not) will be
+ assumed to be <literal>acl deny all all</literal>. If present in the file, any
+ lines below this one are ignored.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Names and group names may contain only <literal>a-z</literal>,
+ <literal>A-Z</literal>, <literal>0-9</literal>,
+ <literal>-</literal>, <literal>@</literal>, <literal>/</literal>
+ or <literal>_</literal>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Rules must be preceded by any configuration and group definitions they may use;
+ any name not previously defined as a group will be assumed to be
+ that of an individual user.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>CONFIG</literal> lines must have the following tokens in order:
+ </para>
+ <itemizedlist>
+ <listitem>
+ <para>The string literal <literal>config</literal></para>
+ </listitem>
+ <listitem>
+ <para>One or more property name-value pairs, in the form <literal>property = value</literal>
+ where value is the token <literal>true</literal> or <literal>false</literal></para>
+ </listitem>
+ </itemizedlist>
+ </listitem>
+ <listitem>
+ <para>
+ GROUP lines must have the following tokens in order:
+ </para>
+ <itemizedlist>
+ <listitem>
+ <para>The string literal <literal>group</literal></para>
+ </listitem>
+ <listitem>
+ <para>The name of the group, which cannot contain <literal>@</literal> or
+ <literal>/</literal> characters</para>
+ </listitem>
+ <listitem>
+ <para>A whitespace separated list of user and group names. User names are formatted
+ as <literal>username/domain@realm</literal> and group names must have been defined
+ earlier in the file</para>
+ </listitem>
+ </itemizedlist>
+ </listitem>
+ <listitem>
+ <para>
+ ACL rules must have the following tokens in order:
+ </para>
+ <itemizedlist>
+ <listitem>
+ <para>An optional rule number, which should be expressible as a positive Java integer</para>
+ </listitem>
+ <listitem>
+ <para>The string literal <literal>acl</literal></para>
+ </listitem>
+ <listitem>
+ <para>The permission, one of <literal>allow</literal>, <literal>allow-log</literal>,
+ <literal>deny</literal> or <literal>deny-log</literal></para>
+ </listitem>
+ <listitem>
+ <para>The name of a single group or individual or the keyword <literal>all</literal></para>
+ </listitem>
+ <listitem>
+ <para>The name of an operation, which should be one of <literal>consume</literal>,
+ <literal>publish</literal>, <literal>create</literal>, <literal>access</literal>,
+ <literal>bind</literal>, <literal>unbind</literal>, <literal>delete</literal>,
+ <literal>purge</literal>, <literal>update</literal>, <literal>execute</literal>
+ or the keyword <literal>all</literal></para>
+ </listitem>
+ <listitem>
+ <para>Optionally, a single object type or the keyword <literal>all</literal></para>
+ <para>Objects allowed are <literal>virtualhost</literal>, <literal>queue</literal>,
+ <literal>topic</literal> and <literal>exchange</literal></para>
+ <para>Objects allowed are <literal>virtualhost</literal>, <literal>queue</literal>,
+ <literal>topic</literal>, <literal>exchange</literal>, <literal>link</literal>,
+ <literal>route</literal>, <literal>method</literal> and <literal>object</literal></para>
+ </listitem>
+ <listitem>
+ <para>If the object is present, then optionally one or more property name-value pairs in the form
+ <literal>property=value</literal>. The property and value can be separated from the
+ <literal>=</literal> charater by any amount of whitespace, and the calue can be quoted if
+ it contains special characters or whitespace.</para>
+ </listitem>
+ <listitem>
+ <para>Property values can add the wildcard <literal>*</literal> character at the end of the string
+ to indicate that any string beginning with the characters up to the wildcard will match, or
+ if the wildcard is the only character, that any string will match</para>
+ </listitem>
+ </itemizedlist>
+ </listitem>
+ </itemizedlist>
+ <para>
+ This allows a rather looser and more readable style for ACL files,
+ while still retaining the ability to read the stricter files accepted
+ by the C++ broker. Bear in mind that the group declarations are to be
+ deprecated, in favour of an external directory service, using a plugin
+ mechanism.
+ </para>
+ <para>
+ The initial number is used to allow rulesets to be created which allow
+ individual rules to be enabled and disabled using an admin interface,
+ and an ACL file using numbered lines would be restricted to having
+ increasing numbers per rule, although gaps would be allowed to enable
+ rules to be inserted later, again using an admin interface. This
+ administrative interface would also allow saving of a modified ruleset
+ and re-loading.
+ </para>
+ </section>
+ <section role="h4" label="SPD-ACL-Broker-Access-Control">
+ <title>Broker Access Control</title>
+ <para>
+ The Java broker access control mechanism is used to protect internal
+ entities used by the broker. These are virtual hosts, queues, topics
+ and exchanges. The actual access control checks take place in the
+ methods that carry out the operations on these objects, in order to
+ ensure thatsecurity is both mechanism and protocol agnostic.
+ </para>
+ <para>
+ <emphasis>The Java broker does not support <code>LINK</code> or
+ <code>ROUTE</code> object types.</emphasis>
+ </para>
+ <para>
+ An example of the various rules that can be specified follows:
+ </para>
+ <programlisting>
+acl allow robot create exchange name="robot.*"
+acl deny kitten create queue
+acl allow guest bind exchange name=amq.topic routingkey="kitten.#"
+acl allow all create queue name="tmp.*"
+acl allow guest publish all durable="false"
+acl allow robot create queue name="robot"
+acl allow kitten consume queue durable="true"
+acl allow guest create all
+ </programlisting>
+ </section>
+ <section role="h4" label="SPD-ACL-Management-Access-Control">
+ <title>Management Access Control</title>
+ <para>
+ The management of the broker using JMX is also protected by the security
+ plugins, in two ways. If the management interface is used to perform
+ operations that would be access controlled normally, the same rules
+ would still apply and be applied. However, this only occurs when the
+ JMX connection was authenticated. If JConsole is used to connect directly
+ to a broker process started by the same user, then no extra checks are made.
+ </para>
+ <para>
+ The management operations themselves are also able to be access controlled.
+ This is done using the <code>METHOD</code> object type. A component name
+ and method name are specified as properties, and these indicate the MBean
+ type name and JMX method name respectively. If the operation is set to
+ <code>ALL</code> then reading JMX attributes, writing JMX attributes and
+ invoking JMX operations are controlled by the rule. Otherwise, the three
+ operations <code>ACCESS</code>, <code>UPDATE</code> and <code>EXECUTE</code>
+ control reading, writing and invocation respectively.
+ </para>
+ <programlisting>
+ACL ALLOW user ALL METHOD
+ACL ALLOW user ALL METHOD name="method"
+ACL ALLOW user ALL METHOD name="prefix*"
+ACL ALLOW user ALL METHOD component="MBean" name="method"
+ACL ALLOW user ACCESS METHOD component="MBean"
+ACL ALLOW user UPDATE METHOD component="MBean"
+ACL ALLOW user EXECUTE METHOD component="MBean"
+ </programlisting>
+ </section>
+ <section role="h4" label="SPD-ACL-External-Object-Access-Control">
+ <title>External Object Access Control</title>
+ <para>
+ At the moment the C++ broker has an extension point to allow access control
+ of external objects. This will be provided in the Java broker as well, using the
+ <code>ACCESS OBJECT</code> rule, with package name and class name properties.
+ The external object must be able to retrieve a reference to the virtual host
+ it is running on, and then call the <code>accessObject</code> method. This
+ must be the responsibility of the external object.
+ </para>
+ <para>
+ <emphasis>Note that this is not currently implemented in the <code>SecurityManager</code>.</emphasis>
+ </para>
+ <programlisting>
+ACL ALLOW user ACCESS OBJECT package="com.example.application" class="Extension"
+ </programlisting>
+ <programlisting>
+if (!_vhost.getSecurityManager().accessObject("com.example.application", "Extension"))
+{
+ // TODO reject access somehow - exception
+}
+ </programlisting>
+ </section>
+ </section>
+ </section>
+ <section role="h2" label="SPD-Other-Security-Plugins">
+ <title>Other Security Plugins</title>
+ <para>
+ There are two basic plugins provided internally by the broker, which can be
+ found in the <code>org.apache.qpid.server.security.access.plugins</code> package.
+ These are <code>AllowAll</code> and <code>DenyAll</code>. The <code>LegacyAccess</code>
+ plugin is not normally required, and simply ignores legacy elements of the configuration
+ file. The other two plugins are activated by the presence of an element in the
+ <code>&lt;security /&gt;</code> section of the configuration or virtual hosts XML
+ files. To deny all access by default, add the empty <code>&lt;deny-all /&gt;</code>
+ element, and to allow all access, add <code>&lt;allow-all /&gt;</code>.
+ </para>
+ </section>
+</section>
diff --git a/qpid/doc/book/src/Security.xml b/qpid/doc/book/src/Security.xml
new file mode 100644
index 0000000000..49abfbebca
--- /dev/null
+++ b/qpid/doc/book/src/Security.xml
@@ -0,0 +1,1217 @@
+<?xml version='1.0' encoding='utf-8' ?>
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
+<!--
+
+ 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.
+
+-->
+<section id="chap-Messaging_User_Guide-Security">
+ <title>Security</title>
+ <para>
+ This chapter describes how authentication, rule-based authorization, encryption, and digital signing can be accomplished using Qpid. Authentication is the process of verifying the identity of a user; in Qpid, this is done using the SASL framework. Rule-based authorization is a mechanism for specifying the actions that each user is allowed to perform; in Qpid, this is done using an Access Control List (ACL) that is part of the Qpid broker. Encryption is used to ensure that data is not transferred in a plain-text format that could be intercepted and read. Digital signatures provide proof that a given message was sent by a known sender. Encryption and signing are done using SSL (they can also be done using SASL, but SSL provides stronger encryption).
+ </para>
+ <section id="sect-Messaging_User_Guide-Security-User_Authentication">
+ <title>User Authentication</title>
+ <para>
+ AMQP uses Simple Authentication and Security Layer (SASL) to authenticate client connections to the broker. SASL is a framework that supports a variety of authentication methods. For secure applications, we suggest <command>CRAM-MD5</command>, <command>DIGEST-MD5</command>, or <command>GSSAPI</command>. The <command>ANONYMOUS</command> method is not secure. The <command>PLAIN</command> method is secure only when used together with SSL.
+ </para>
+ <para>
+ Both the Qpid broker and Qpid clients use the <ulink url="http://cyrusimap.web.cmu.edu/">Cyrus SASL library</ulink>, a full-featured authentication framework, which offers many configuration options. This section shows how to configure users for authentication with SASL, which is sufficient when using <command>SASL PLAIN</command>. If you are not using SSL, you should configure SASL to use <command>CRAM-MD5</command>, <command>DIGEST-MD5</command>, or <command>GSSAPI</command> (which provides Kerberos authentication). For information on configuring these and other options in SASL, see the Cyrus SASL documentation<!-- at <filename>/usr/share/doc/cyrus-sasl-lib-2.1.22/index.html</filename> for &RHEL5; or <filename>/usr/share/doc/cyrus-sasl-2.1.19/index.html</filename> for &RHEL4;-->.
+ </para>
+ <important>
+ <title>Important</title>
+ <para>
+ The <command>SASL PLAIN</command> method sends passwords in cleartext, and is vulnerable to man-in-the-middle attacks unless SSL (Secure Socket Layer) is also used (see <xref linkend="sect-Messaging_User_Guide-Security-Encryption_using_SSL" />).
+ </para>
+ <para>
+ If you are not using SSL, we recommend that you disable <command>PLAIN</command> authentication in the broker.
+ </para>
+
+ </important>
+ <para>
+ The Qpid broker uses the <command>auth yes|no</command> option to determine whether to use SASL authentication. Turn on authentication by setting <command>auth</command> to <command>yes</command> in <filename>/etc/qpidd.conf</filename>:
+ </para>
+
+<programlisting>
+# /etc/qpidd.conf
+#
+# Set auth to &#39;yes&#39; or &#39;no&#39;
+
+auth=yes
+</programlisting>
+ <section id="sect-Messaging_User_Guide-User_Authentication-Configuring_SASL">
+ <title>Configuring SASL</title>
+ <para>
+ On Linux systems, the SASL configuration file is generally found in <filename>/etc/sasl2/qpidd.conf</filename> <!-- for &RHEL5; and-->or <filename>/usr/lib/sasl2/qpidd.conf</filename><!-- for &RHEL4;-->.
+ </para>
+ <para>
+ The SASL database contains user names and passwords for SASL. In SASL, a user may be associated with a <firstterm>realm</firstterm>. The Qpid broker authenticates users in the <command>QPID</command> realm by default, but it can be set to a different realm using the <command>realm</command> option:
+ </para>
+
+<programlisting>
+# /etc/qpidd.conf
+#
+# Set the SASL realm using &#39;realm=&#39;
+
+auth=yes
+realm=QPID
+</programlisting>
+ <para>
+ The SASL database is installed at <filename>/var/lib/qpidd/qpidd.sasldb</filename>; initially, it has one user named <command>guest</command> in the <command>QPID</command> realm, and the password for this user is <command>guest</command>.
+ </para>
+ <note>
+ <title>Note</title>
+ <para>
+ The user database is readable only by the <systemitem class="username">qpidd</systemitem> user. When run as a daemon, Qpid always runs as the <systemitem class="username">qpidd</systemitem> user. If you start the broker from a user other than the <systemitem class="username">qpidd</systemitem> user, you will need to either reconfigure SASL or turn authentication off.
+ </para>
+
+ </note>
+ <important>
+ <title>Important</title>
+ <para>
+ The SASL database stores user names and passwords in plain text. If it is compromised so are all of the passwords that it stores. This is the reason that the <systemitem class="username">qpidd</systemitem> user is the only user that can read the database. If you modify permissions, be careful not to expose the SASL database.
+ </para>
+
+ </important>
+ <para>
+ Add new users to the database by using the <command>saslpasswd2</command> command, which specifies a realm and a user ID. A user ID takes the form <command><replaceable>user-id</replaceable>@<replaceable>domain</replaceable>.</command>.
+ </para>
+
+<screen># saslpasswd2 -f /var/lib/qpidd/qpidd.sasldb -u <replaceable>realm</replaceable> <replaceable>new_user_name</replaceable></screen>
+ <para>
+ To list the users in the SASL database, use <command>sasldblistusers2</command>:
+ </para>
+
+<screen># sasldblistusers2 -f /var/lib/qpidd/qpidd.sasldb
+</screen>
+ <para>
+ If you are using <command>PLAIN</command> authentication, users who are in the database can now connect with their user name and password. This is secure only if you are using SSL. If you are using a more secure form of authentication, please consult your SASL documentation for information on configuring the options you need.
+ </para>
+
+ </section>
+
+ <section id="sect-Messaging_User_Guide-User_Authentication-Kerberos">
+ <title>Kerberos</title>
+ <para>
+ Both the Qpid broker and Qpid users are &#39;principals&#39; of the Kerberos server, which means that they are both clients of the Kerberos authentication services.
+ </para>
+ <para>
+ To use Kerberos, both the Qpid broker and each Qpid user must be authenticated on the Kerberos server:
+ </para>
+ <procedure>
+ <step>
+ <para>
+ Install the Kerberos workstation software and Cyrus SASL GSSAPI on each machine that runs a qpidd broker or a qpidd messaging client:
+ </para>
+
+<screen>$ sudo yum install cyrus-sasl-gssapi krb5-workstation</screen>
+
+ </step>
+ <step>
+ <para>
+ Make sure that the Qpid broker is registered in the Kerberos database.
+ </para>
+ <para>
+ Traditionally, a Kerberos principal is divided into three parts: the primary, the instance, and the realm. A typical Kerberos V5 has the format <literal>primary/instance@REALM</literal>. For a Qpid broker, the primary is <literal>qpidd</literal>, the instance is the fully qualified domain name, which you can obtain using <command>hostname --fqdn</command>, and the REALM is the Kerberos domain realm. By default, this realm is <literal>QPID</literal>, but a different realm can be specified in qpid.conf, e.g.:
+<screen>realm=EXAMPLE.COM</screen>
+
+ </para>
+ <para>
+ For instance, if the fully qualified domain name is <literal>dublduck.example.com</literal> and the Kerberos domain realm is <literal>EXAMPLE.COM</literal>, then the principal name is <literal>qpidd/dublduck.example.com@EXAMPLE.COM</literal>.
+ </para>
+ <para>
+ The following script creates a principal for qpidd:
+ </para>
+
+<programlisting>
+FDQN=`hostname --fqdn`
+REALM=&#34;EXAMPLE.COM&#34;
+kadmin -r $REALM -q &#34;addprinc -randkey -clearpolicy qpidd/$FQDN&#34;
+</programlisting>
+ <para>
+ Now create a Kerberos keytab file for the Qpid broker. The Qpid broker must have read access to the keytab file. The following script creates a keytab file and allows the broker read access:
+ </para>
+
+<programlisting>
+QPIDD_GROUP=&#34;qpidd&#34;
+kadmin -r $REALM -q &#34;ktadd -k /etc/qpidd.keytab qpidd/$FQDN@$REALM&#34;
+chmod g+r /etc/qpidd.keytab
+chgrp $QPIDD_GROUP /etc/qpidd.keytab
+</programlisting>
+ <para>
+ The default location for the keytab file is <filename>/etc/krb5.keytab</filename>. If a different keytab file is used, the KRB5_KTNAME environment variable must contain the name of the file, e.g.:
+ </para>
+
+<programlisting>
+export KRB5_KTNAME=/etc/qpidd.keytab
+</programlisting>
+ <para>
+ If this is correctly configured, you can now enable kerberos support on the Qpid broker by setting the <varname>auth</varname> and <varname>realm</varname> options in <filename>/etc/qpidd.conf</filename>:
+ </para>
+
+<programlisting>
+# /etc/qpidd.conf
+auth=yes
+realm=EXAMPLE.COM
+</programlisting>
+ <para>
+ Restart the broker to activate these settings.
+ </para>
+
+ </step>
+ <step>
+ <para>
+ Make sure that each Qpid user is registered in the Kerberos database, and that Kerberos is correctly configured on the client machine. The Qpid user is the account from which a Qpid messaging client is run. If it is correctly configured, the following command should succeed:
+ </para>
+
+<screen>$ kinit user@REALM.COM</screen>
+
+ </step>
+
+ </procedure>
+
+ <para>
+ Java JMS clients require a few additional steps.
+ </para>
+ <procedure>
+ <step>
+ <para>
+ The Java JVM must be run with the following arguments:
+ </para>
+ <variablelist>
+ <varlistentry>
+ <term>-Djavax.security.auth.useSubjectCredsOnly=false</term>
+ <listitem>
+ <para>
+ Forces the SASL GASSPI client to obtain the kerberos credentials explicitly instead of obtaining from the &#34;subject&#34; that owns the current thread.
+ </para>
+
+ </listitem>
+
+ </varlistentry>
+ <varlistentry>
+ <term>-Djava.security.auth.login.config=myjas.conf</term>
+ <listitem>
+ <para>
+ Specifies the jass configuration file. Here is a sample JASS configuration file:
+ </para>
+
+<programlisting>
+com.sun.security.jgss.initiate {
+ com.sun.security.auth.module.Krb5LoginModule required useTicketCache=true;
+};
+</programlisting>
+
+ </listitem>
+
+ </varlistentry>
+ <varlistentry>
+ <term>-Dsun.security.krb5.debug=true</term>
+ <listitem>
+ <para>
+ Enables detailed debug info for troubleshooting
+ </para>
+
+ </listitem>
+
+ </varlistentry>
+
+ </variablelist>
+
+ </step>
+ <step>
+ <para>
+ The client&#39;s Connection URL must specify the following Kerberos-specific broker properties:
+ </para>
+ <itemizedlist>
+ <listitem>
+ <para>
+ <varname>sasl_mechs</varname> must be set to <literal>GSSAPI</literal>.
+ </para>
+
+ </listitem>
+ <listitem>
+ <para>
+ <varname>sasl_protocol</varname> must be set to the principal for the qpidd broker, e.g. <literal>qpidd</literal>/
+ </para>
+
+ </listitem>
+ <listitem>
+ <para>
+ <varname>sasl_server</varname> must be set to the host for the SASL server, e.g. <literal>sasl.com</literal>.
+ </para>
+
+ </listitem>
+
+ </itemizedlist>
+ <para>
+ Here is a sample connection URL for a Kerberos connection:
+ </para>
+
+<screen>amqp://guest@clientid/testpath?brokerlist=&#39;tcp://localhost:5672?sasl_mechs=&#39;GSSAPI&#39;&amp;sasl_protocol=&#39;qpidd&#39;&amp;sasl_server=&#39;&#60;server-host-name&#62;&#39;&#39;</screen>
+
+ </step>
+
+ </procedure>
+<!--
+ <para>
+ Please refer to the following documentation for more detail on using Kerberos:
+ </para>
+ <variablelist>
+ <varlistentry>
+ <term>RHEL5</term>
+ <listitem>
+ <para>
+ <ulink url="http://www.redhat.com/docs/manuals/enterprise/RHEL-5-manual/Deployment_Guide-en-US/ch-kerberos.html"> Red Hat Enterprise Linux 5: Deployment Guide </ulink>
+ </para>
+
+ </listitem>
+
+ </varlistentry>
+ <varlistentry>
+ <term>RHEL4</term>
+ <listitem>
+ <para>
+ <ulink url="http://www.redhat.com/docs/manuals/enterprise/RHEL-4-Manual/ref-guide/ch-kerberos.html"> Red Hat Enterprise Linux 4: Reference Guide </ulink>
+ </para>
+
+ </listitem>
+
+ </varlistentry>
+ <varlistentry>
+ <term>Java</term>
+ <listitem>
+ <para>
+ <ulink url="http://java.sun.com/j2se/1.5.0/docs/guide/security/jgss/tutorials/index.html"> Introduction to JAAS and Java GSS-API Tutorials </ulink>
+ </para>
+
+ </listitem>
+
+ </varlistentry>
+
+ </variablelist>
+ -->
+
+ </section>
+
+
+ </section>
+
+ <!-- ################################################### --> <section id="sect-Messaging_User_Guide-Security-Authorization">
+ <title>Authorization</title>
+ <para>
+ In Qpid, Authorization specifies which actions can be performed by each authenticated user using an Access Control List (ACL). Use the <command>--acl-file</command> command to load the access control list. The filename should have a <filename>.acl</filename> extension:
+ </para>
+
+<screen>
+$ qpidd --acl-file <replaceable>./aclfilename.acl</replaceable></screen>
+ <para>
+ Each line in an ACL file grants or denies specific rights to a user. If the last line in an ACL file is <literal>acl deny all all</literal>, the ACL uses <firstterm>deny mode</firstterm>, and only those rights that are explicitly allowed are granted:
+ </para>
+
+<programlisting>
+acl allow rajith@QPID all all
+acl deny all all
+</programlisting>
+ <para>
+ On this server, <literal>rajith@QPID</literal> can perform any action, but nobody else can. Deny mode is the default, so the previous example is equivalent to the following ACL file:
+ </para>
+
+<programlisting>
+acl allow rajith@QPID all all
+</programlisting>
+ <para>
+ In deny mode, denying rights to an action is redundant and has no effect.
+ </para>
+
+<programlisting>
+acl allow rajith@QPID all all
+acl deny jonathan@QPID all all # This rule is redundant, and has no effect
+acl deny all all
+</programlisting>
+ <para>
+ If the last line in an ACL file is <literal>acl allow all all</literal>, ACL uses <firstterm>allow mode</firstterm>, and all rights are granted except those that are explicitly denied. The following ACL file allows everyone else to perform any action, but denies <literal>jonathan@QPID</literal> all permissions.
+ </para>
+
+<programlisting>
+acl deny jonathan@QPID all all
+acl allow all all
+</programlisting>
+ <para>
+ In allow mode, allowing rights to an action is redundant and has no effect.
+ </para>
+
+<programlisting>
+acl allow rajith@QPID all all # This rule is redundant, and has no effect
+acl deny jonathan@QPID all all
+acl allow all all
+</programlisting>
+ <important>
+ <title>Important</title>
+ <para>
+ ACL processing ends when one of the following lines is encountered:
+ </para>
+
+<programlisting>
+acl allow all all
+</programlisting>
+
+<programlisting>
+acl deny all all
+</programlisting>
+ <para>
+ Any lines that occur after one of these statements will be ignored:
+ </para>
+
+<programlisting>
+acl allow all all
+acl deny jonathan@QPID all all # This line is ignored !!!
+</programlisting>
+
+ </important>
+ <para>
+ ACL syntax allows fine-grained access rights for specific actions:
+ </para>
+
+<programlisting>
+acl allow carlt@QPID create exchange name=carl.*
+acl allow fred@QPID create all
+acl allow all consume queue
+acl allow all bind exchange
+acl deny all all
+</programlisting>
+ <para>
+ An ACL file can define user groups, and assign permissions to them:
+ </para>
+
+<programlisting>
+group admin ted@QPID martin@QPID
+acl allow admin create all
+acl deny all all
+</programlisting>
+ <!-- ######## --> <section id="sect-Messaging_User_Guide-Authorization-ACL_Syntax">
+ <title>ACL Syntax</title>
+ <para>
+ ACL rules must be on a single line and follow this syntax:
+<programlisting>acl permission {&#60;group-name&#62;|&#60;user-name&#62;|&#34;all&#34;} {action|&#34;all&#34;} [object|&#34;all&#34;] [property=&#60;property-value&#62;]
+</programlisting>
+ ACL rules can also include a single object name (or the keyword <parameter>all</parameter>) and one or more property name value pairs in the form <command>property=value</command>
+ </para>
+ <para>
+ The following tables show the possible values for <command>permission</command>, <command>action</command>, <command>object</command>, and <command>property</command> in an ACL rules file.
+ </para>
+ <table id="tabl-Messaging_User_Guide-ACL_Syntax-ACL_Rules_permission">
+ <title>ACL Rules: permission</title>
+ <tgroup cols="2">
+ <tbody>
+ <row>
+ <entry>
+ <command>allow</command>
+ </entry>
+ <entry>
+ <para>
+ Allow the action <!-- ### rule => the action -->
+ </para>
+
+ </entry>
+
+ </row>
+ <row>
+ <entry>
+ <command>allow-log</command>
+ </entry>
+ <entry>
+ <para>
+ Allow the action and log the action in the event log
+ </para>
+
+ </entry>
+
+ </row>
+ <row>
+ <entry>
+ <command>deny</command>
+ </entry>
+ <entry>
+ <para>
+ Deny the action
+ </para>
+
+ </entry>
+
+ </row>
+ <row>
+ <entry>
+ <command>deny-log</command>
+ </entry>
+ <entry>
+ <para>
+ Deny the action and log the action in the event log
+ </para>
+
+ </entry>
+
+ </row>
+
+ </tbody>
+
+ </tgroup>
+
+ </table>
+ <!-- Actions --> <table id="tabl-Messaging_User_Guide-ACL_Syntax-ACL_Rulesaction">
+ <title>ACL Rules:action</title>
+ <tgroup cols="2">
+ <tbody>
+ <row>
+ <entry>
+ <command>consume</command>
+ </entry>
+ <entry>
+ <para>
+ Applied when subscriptions are created
+ </para>
+
+ </entry>
+
+ </row>
+ <row>
+ <entry>
+ <command>publish</command>
+ </entry>
+ <entry>
+ <para>
+ Applied on a per message basis on publish message transfers, this rule consumes the most resources
+ </para>
+
+ </entry>
+
+ </row>
+ <row>
+ <entry>
+ <command>create</command>
+ </entry>
+ <entry>
+ <para>
+ Applied when an object is created, such as bindings, queues, exchanges, links
+ </para>
+
+ </entry>
+
+ </row>
+ <row>
+ <entry>
+ <command>access</command>
+ </entry>
+ <entry>
+ <para>
+ Applied when an object is read or accessed
+ </para>
+
+ </entry>
+
+ </row>
+ <row>
+ <entry>
+ <command>bind</command>
+ </entry>
+ <entry>
+ <para>
+ Applied when objects are bound together
+ </para>
+
+ </entry>
+
+ </row>
+ <row>
+ <entry>
+ <command>unbind</command>
+ </entry>
+ <entry>
+ <para>
+ Applied when objects are unbound
+ </para>
+
+ </entry>
+
+ </row>
+ <row>
+ <entry>
+ <command>delete</command>
+ </entry>
+ <entry>
+ <para>
+ Applied when objects are deleted
+ </para>
+
+ </entry>
+
+ </row>
+ <row>
+ <entry>
+ <command>purge</command>
+ </entry>
+ <entry>
+ <para>
+ Similar to delete but the action is performed on more than one object
+ </para>
+
+ </entry>
+
+ </row>
+ <row>
+ <entry>
+ <command>update</command>
+ </entry>
+ <entry>
+ <para>
+ Applied when an object is updated
+ </para>
+
+ </entry>
+
+ </row>
+
+ </tbody>
+
+ </tgroup>
+
+ </table>
+ <!-- object types --> <table id="tabl-Messaging_User_Guide-ACL_Syntax-ACL_Rulesobject">
+ <title>ACL Rules:object</title>
+ <tgroup cols="2">
+ <tbody>
+ <row>
+ <entry>
+ <command>queue</command>
+ </entry>
+ <entry>
+ <para>
+ A queue
+ </para>
+
+ </entry>
+
+ </row>
+ <row>
+ <entry>
+ <command>exchange</command>
+ </entry>
+ <entry>
+ <para>
+ An exchange
+ </para>
+
+ </entry>
+
+ </row>
+ <row>
+ <entry>
+ <command>broker</command>
+ </entry>
+ <entry>
+ <para>
+ The broker
+ </para>
+
+ </entry>
+
+ </row>
+ <row>
+ <entry>
+ <command>link</command>
+ </entry>
+ <entry>
+ <para>
+ A federation or inter-broker link
+ </para>
+
+ </entry>
+
+ </row>
+ <row>
+ <entry>
+ <command>method</command>
+ </entry>
+ <entry>
+ <para>
+ Management or agent or broker method
+ </para>
+
+ </entry>
+
+ </row>
+
+ </tbody>
+
+ </tgroup>
+
+ </table>
+ <!--
+ <para>
+ Wild cards can be used on properties that are a string. The following properties are supported: --> <table id="tabl-Messaging_User_Guide-ACL_Syntax-ACL_Rulesproperty">
+ <title>ACL Rules:property</title>
+ <tgroup cols="2">
+ <tbody>
+ <row>
+ <entry>
+ <command>name</command>
+ </entry>
+ <entry>
+ <para>
+ String. Object name, such as a queue name or exchange name.
+ </para>
+
+ </entry>
+
+ </row>
+ <row>
+ <entry>
+ <command>durable</command>
+ </entry>
+ <entry>
+ <para>
+ Boolean. Indicates the object is durable
+ </para>
+
+ </entry>
+
+ </row>
+ <row>
+ <entry>
+ <command>routingkey</command>
+ </entry>
+ <entry>
+ <para>
+ Sring. Specifies routing key
+ </para>
+
+ </entry>
+
+ </row>
+ <row>
+ <entry>
+ <command>passive</command>
+ </entry>
+ <entry>
+ <para>
+ Boolean. Indicates the presence of a <parameter>passive</parameter> flag
+ </para>
+
+ </entry>
+
+ </row>
+ <row>
+ <entry>
+ <command>autodelete</command>
+ </entry>
+ <entry>
+ <para>
+ Boolean. Indicates whether or not the object gets deleted when the connection is closed
+ </para>
+
+ </entry>
+
+ </row>
+ <row>
+ <entry>
+ <command>exclusive</command>
+ </entry>
+ <entry>
+ <para>
+ Boolean. Indicates the presence of an <parameter>exclusive</parameter> flag
+ </para>
+
+ </entry>
+
+ </row>
+ <row>
+ <entry>
+ <command>type</command>
+ </entry>
+ <entry>
+ <para>
+ String. Type of object, such as topic, fanout, or xml
+ </para>
+
+ </entry>
+
+ </row>
+ <row>
+ <entry>
+ <command>alternate</command>
+ </entry>
+ <entry>
+ <para>
+ String. Name of the alternate exchange
+ </para>
+
+ </entry>
+
+ </row>
+ <row>
+ <entry>
+ <command>queuename</command>
+ </entry>
+ <entry>
+ <para>
+ String. Name of the queue (used only when the object is something other than <parameter>queue</parameter>
+ </para>
+
+ </entry>
+
+ </row>
+ <row>
+ <entry>
+ <command>schemapackage</command>
+ </entry>
+ <entry>
+ <para>
+ String. QMF schema package name
+ </para>
+
+ </entry>
+
+ </row>
+ <row>
+ <entry>
+ <command>schemaclass</command>
+ </entry>
+ <entry>
+ <para>
+ String. QMF schema class name
+ </para>
+
+ </entry>
+
+ </row>
+
+ </tbody>
+
+ </tgroup>
+
+ </table>
+
+ </section>
+
+ <section id="sect-Messaging_User_Guide-Authorization-ACL_Syntactic_Conventions">
+ <title>ACL Syntactic Conventions</title>
+ <para>
+ In ACL files, the following syntactic conventions apply:
+ <itemizedlist>
+ <listitem>
+ <para>
+ A line starting with the <command>#</command> character is considered a comment and is ignored.
+ </para>
+
+ </listitem>
+ <listitem>
+ <para>
+ Empty lines and lines that contain only whitespace are ignored
+ </para>
+
+ </listitem>
+ <listitem>
+ <para>
+ All tokens are case sensitive. <parameter>name1</parameter> is not the same as <parameter>Name1</parameter> and <parameter>create</parameter> is not the same as <parameter>CREATE</parameter>
+ </para>
+
+ </listitem>
+ <listitem>
+ <para>
+ Group lists can be extended to the following line by terminating the line with the <command>\</command> character
+ </para>
+
+ </listitem>
+ <listitem>
+ <para>
+ Additional whitespace - that is, where there is more than one whitespace character - between and after tokens is ignored. Group and ACL definitions must start with either <command>group</command> or <command>acl</command> and with no preceding whitespace.
+ </para>
+
+ </listitem>
+ <listitem>
+ <para>
+ All ACL rules are limited to a single line
+ </para>
+
+ </listitem>
+ <listitem>
+ <para>
+ Rules are interpreted from the top of the file down until the name match is obtained; at which point processing stops.
+ </para>
+
+ </listitem>
+ <listitem>
+ <para>
+ The keyword <parameter>all</parameter> matches all individuals, groups and actions
+ </para>
+
+ </listitem>
+ <listitem>
+ <para>
+ The last line of the file - whether present or not - will be assumed to be <command>acl deny all all</command>. If present in the file, all lines below it are ignored.
+ </para>
+
+ </listitem>
+ <listitem>
+ <para>
+ Names and group names may contain only <parameter>a-z</parameter>, <parameter>A-Z</parameter>, <parameter>0-9</parameter>, <parameter>-</parameter> and <parameter>_</parameter>
+ </para>
+
+ </listitem>
+ <listitem>
+ <para>
+ Rules must be preceded by any group definitions they can use. Any name not defined as a group will be assumed to be that of an individual.
+ </para>
+
+ </listitem>
+
+ </itemizedlist>
+
+ </para>
+
+ </section>
+
+ <section id="sect-Messaging_User_Guide-Authorization-Specifying_ACL_Permissions">
+ <title>Specifying ACL Permissions</title>
+ <para>
+ Now that we have seen the ACL syntax, we will provide representative examples and guidelines for ACL files.
+ </para>
+ <para>
+ Most ACL files begin by defining groups:
+ </para>
+
+<programlisting>
+group admin ted@QPID martin@QPID
+group user-consume martin@QPID ted@QPID
+group group2 kim@QPID user-consume rob@QPID
+group publisher group2 \
+tom@QPID andrew@QPID debbie@QPID
+</programlisting>
+ <para>
+ Rules in an ACL file grant or deny specific permissions to users or groups:
+ </para>
+
+<programlisting>
+acl allow carlt@QPID create exchange name=carl.*
+acl allow rob@QPID create queue
+acl allow guest@QPID bind exchange name=amq.topic routingkey=stocks.rht.#
+acl allow user-consume create queue name=tmp.*
+
+acl allow publisher publish all durable=false
+acl allow publisher create queue name=RequestQueue
+acl allow consumer consume queue durable=true
+acl allow fred@QPID create all
+acl allow bob@QPID all queue
+acl allow admin all
+acl allow all consume queue
+acl allow all bind exchange
+acl deny all all
+</programlisting>
+ <para>
+ In the previous example, the last line, <literal>acl deny all all</literal>, denies all authorizations that have not been specifically granted. This is the default, but it is useful to include it explicitly on the last line for the sake of clarity. If you want to grant all rights by default, you can specify <literal>acl allow all all</literal> in the last line.
+ </para>
+ <para>
+ Do not allow <parameter>guest</parameter> to access and log QMF management methods that could cause security breaches:
+ </para>
+
+<programlisting>
+group allUsers guest@QPID
+....
+acl deny-log allUsers create link
+acl deny-log allUsers access method name=connect
+acl deny-log allUsers access method name=echo
+acl allow all all
+</programlisting>
+
+ </section>
+
+
+ </section>
+
+ <!-- ########################### --> <section id="sect-Messaging_User_Guide-Security-Encryption_using_SSL">
+ <title>Encryption using SSL</title>
+ <para>
+ Encryption and certificate management for <command>qpidd</command> is provided by Mozilla&#39;s Network Security Services Library (NSS).
+ </para>
+ <orderedlist id="orde-Messaging_User_Guide-Encryption_using_SSL-Enabling_SSL_for_the_RHM_broker">
+ <title>Enabling SSL for the Qpid broker</title>
+ <listitem>
+ <para>
+ You will need a certificate that has been signed by a Certification Authority (CA). This certificate will also need to be trusted by your client. If you require client authentication in addition to server authentication, the client&#39;s certificate will also need to be signed by a CA and trusted by the broker.
+ </para>
+ <para>
+ In the broker, SSL is provided through the <command>ssl.so</command> module. This module is installed and loaded by default in Qpid. To enable the module, you need to specify the location of the database containing the certificate and key to use. This is done using the <command>ssl-cert-db</command> option.
+ </para>
+ <para>
+ The certificate database is created and managed by the Mozilla Network Security Services (NSS) <command>certutil</command> tool. Information on this utility can be found on the <ulink url="http://www.mozilla.org/projects/security/pki/nss/tools/certutil.html">Mozilla website</ulink>, including tutorials on setting up and testing SSL connections. The certificate database will generally be password protected. The safest way to specify the password is to place it in a protected file, use the password file when creating the database, and specify the password file with the <command>ssl-cert-password-file</command> option when starting the broker.
+ </para>
+ <para>
+ The following script shows how to create a certificate database using certutil:
+ </para>
+ <!-- TODO: improve description -->
+<programlisting>
+mkdir ${CERT_DIR}
+certutil -N -d ${CERT_DIR} -f ${CERT_PW_FILE}
+certutil -S -d ${CERT_DIR} -n ${NICKNAME} -s &#34;CN=${NICKNAME}&#34; -t &#34;CT,,&#34; -x -f ${CERT_PW_FILE} -z /usr/bin/certutil
+</programlisting>
+ <para>
+ When starting the broker, set <command>ssl-cert-password-file</command> to the value of <command>${CERT_PW_FILE}</command>, set <command>ssl-cert-db</command> to the value of <command>${CERT_DIR}</command>, and set <command>ssl-cert-name</command> to the value of <command>${NICKNAME}</command>.
+ </para>
+
+ </listitem>
+ <!-- SSL options --> <listitem>
+ <para>
+ The following SSL options can be used when starting the broker:
+ <variablelist>
+ <varlistentry>
+ <term><command>--ssl-use-export-policy</command></term>
+ <listitem>
+ <para>
+ Use NSS export policy
+ </para>
+
+ </listitem>
+
+ </varlistentry>
+ <varlistentry>
+ <term><command>--ssl-cert-password-file <replaceable>PATH</replaceable></command></term>
+ <listitem>
+ <para>
+ Required. Plain-text file containing password to use for accessing certificate database.
+ </para>
+
+ </listitem>
+
+ </varlistentry>
+ <varlistentry>
+ <term><command>--ssl-cert-db <replaceable>PATH</replaceable></command></term>
+ <listitem>
+ <para>
+ Required. Path to directory containing certificate database.
+ </para>
+
+ </listitem>
+
+ </varlistentry>
+ <varlistentry>
+ <term><command>--ssl-cert-name <replaceable>NAME</replaceable></command></term>
+ <listitem>
+ <para>
+ Name of the certificate to use. Default is <literal>localhost.localdomain</literal>.
+ </para>
+
+ </listitem>
+
+ </varlistentry>
+ <varlistentry>
+ <term><command>--ssl-port <replaceable>NUMBER</replaceable></command></term>
+ <listitem>
+ <para>
+ Port on which to listen for SSL connections. If no port is specified, port 5671 is used.
+ </para>
+
+ </listitem>
+
+ </varlistentry>
+ <varlistentry>
+ <term><command>--ssl-require-client-authentication</command></term>
+ <listitem>
+ <para>
+ Require SSL client authentication (i.e. verification of a client certificate) during the SSL handshake. This occurs before SASL authentication, and is independent of SASL.
+ </para>
+ <para>
+ This option enables the <literal>EXTERNAL</literal> SASL mechanism for SSL connections. If the client chooses the <literal>EXTERNAL</literal> mechanism, the client&#39;s identity is taken from the validated SSL certificate, using the <literal>CN</literal>literal&#62;, and appending any <literal>DC</literal>literal&#62;s to create the domain. For instance, if the certificate contains the properties <literal>CN=bob</literal>, <literal>DC=acme</literal>, <literal>DC=com</literal>, the client&#39;s identity is <literal>bob@acme.com</literal>.
+ </para>
+ <para>
+ If the client chooses a different SASL mechanism, the identity take from the client certificate will be replaced by that negotiated during the SASL handshake.
+ </para>
+
+ </listitem>
+
+ </varlistentry>
+ <varlistentry>
+ <term><command>--ssl-sasl-no-dict</command></term>
+ <listitem>
+ <para>
+ Do not accept SASL mechanisms that can be compromised by dictionary attacks. This prevents a weaker mechanism being selected instead of <literal>EXTERNAL</literal>, which is not vulnerable to dictionary attacks.
+ </para>
+
+ </listitem>
+
+ </varlistentry>
+
+ </variablelist>
+ Also relevant is the <command>--require-encryption</command> broker option. This will cause <command>qpidd</command> to only accept encrypted connections.
+ </para>
+
+ </listitem>
+
+ </orderedlist>
+ <!-- --> <variablelist id="vari-Messaging_User_Guide-Encryption_using_SSL-Enabling_SSL_in_Clients">
+ <title>Enabling SSL in Clients</title>
+ <varlistentry>
+ <term>C++ clients:</term>
+ <listitem>
+ <para>
+ <orderedlist>
+ <listitem>
+ <para>
+ In C++ clients, SSL is implemented in the <command>sslconnector.so</command> module. This module is installed and loaded by default in Qpid.
+ </para>
+ <para>
+ The following options can be specified for C++ clients using environment variables:
+ </para>
+ <table frame="all" id="tabl-Messaging_User_Guide-Enabling_SSL_in_Clients-SSL_Client_Environment_Variables_for_C_clients">
+ <title>SSL Client Environment Variables for C++ clients</title>
+ <tgroup align="left" cols="2" colsep="1" rowsep="1">
+ <colspec colname="c1"></colspec>
+ <colspec colname="c2"></colspec>
+ <thead>
+ <row>
+ <entry align="center" nameend="c2" namest="c1">
+ SSL Client Options for C++ clients
+ </entry>
+
+ </row>
+
+ </thead>
+ <tbody>
+ <row>
+ <entry>
+ <command>QPID_SSL_USE_EXPORT_POLICY</command>
+ </entry>
+ <entry>
+ Use NSS export policy
+ </entry>
+
+ </row>
+ <row>
+ <entry>
+ <command>QPID_SSL_CERT_PASSWORD_FILE <replaceable>PATH</replaceable></command>
+ </entry>
+ <entry>
+ File containing password to use for accessing certificate database
+ </entry>
+
+ </row>
+ <row>
+ <entry>
+ <command>QPID_SSL_CERT_DB <replaceable>PATH</replaceable></command>
+ </entry>
+ <entry>
+ Path to directory containing certificate database
+ </entry>
+
+ </row>
+ <row>
+ <entry>
+ <command>QPID_SSL_CERT_NAME <replaceable>NAME</replaceable></command>
+ </entry>
+ <entry>
+ Name of the certificate to use. When SSL client authentication is enabled, a certificate name should normally be provided.
+ </entry>
+
+ </row>
+
+ </tbody>
+
+ </tgroup>
+
+ </table>
+ <!-- ######## -->
+ </listitem>
+ <listitem>
+ <para>
+ When using SSL connections, clients must specify the location of the certificate database, a directory that contains the client&#39;s certificate and the public key of the Certificate Authority. This can be done by setting the environment variable <command>QPID_SSL_CERT_DB</command> to the full pathname of the directory. If a connection uses SSL client authentication, the client&#39;s password is also needed&mdash;the password should be placed in a protected file, and the <command>QPID_SSL_CERT_PASSWORD_FILE</command> variable should be set to the location of the file containing this password.
+ </para>
+
+ </listitem>
+ <listitem>
+ <para>
+ To open an SSL enabled connection in the Qpid Messaging API, set the <parameter>protocol</parameter> connection option to <parameter>ssl</parameter>.
+ </para>
+
+ </listitem>
+
+ </orderedlist>
+
+ </para>
+
+ </listitem>
+
+ </varlistentry>
+ <varlistentry>
+ <term>Java clients:</term>
+ <listitem>
+ <para>
+ <orderedlist>
+ <listitem>
+ <para>
+ For both server and client authentication, import the trusted CA to your trust store and keystore and generate keys for them. Create a certificate request using the generated keys and then create a certificate using the request. You can then import the signed certificate into your keystore. Pass the following arguments to the Java JVM when starting your client:
+<programlisting>
+-Djavax.net.ssl.keyStore=/home/bob/ssl_test/keystore.jks
+-Djavax.net.ssl.keyStorePassword=password
+-Djavax.net.ssl.trustStore=/home/bob/ssl_test/certstore.jks
+-Djavax.net.ssl.trustStorePassword=password
+</programlisting>
+
+ </para>
+
+ </listitem>
+ <listitem>
+ <para>
+ For server side authentication only, import the trusted CA to your trust store and pass the following arguments to the Java JVM when starting your client:
+<programlisting>
+-Djavax.net.ssl.trustStore=/home/bob/ssl_test/certstore.jks
+-Djavax.net.ssl.trustStorePassword=password
+</programlisting>
+
+ </para>
+
+ </listitem>
+ <listitem>
+ <para>
+ Java clients must use the SSL option in the connection URL to enable SSL encryption, e.g.
+ </para>
+
+<programlisting>amqp://username:password@clientid/test?brokerlist=&#39;tcp://localhost:5672?ssl=&#39;true&#39;&#39;
+</programlisting>
+
+ </listitem>
+ <listitem>
+ <para>
+ If you need to debug problems in an SSL connection, enable Java&#39;s SSL debugging by passing the argument <literal>-Djavax.net.debug=ssl</literal> to the Java JVM when starting your client.
+ </para>
+
+ </listitem>
+
+ </orderedlist>
+
+ </para>
+
+ </listitem>
+
+ </varlistentry>
+
+ </variablelist>
+
+ </section>
+
+
+</section>
+
diff --git a/qpid/doc/book/src/Starting-a-cluster.xml b/qpid/doc/book/src/Starting-a-cluster.xml
new file mode 100644
index 0000000000..036e571649
--- /dev/null
+++ b/qpid/doc/book/src/Starting-a-cluster.xml
@@ -0,0 +1,561 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+
+ 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.
+
+-->
+
+<section id="chap-Messaging_User_Guide-High_Availability_Messaging_Clusters">
+ <title>High Availability Messaging Clusters</title>
+ <para>
+ High Availability Messaging Clusters provide fault tolerance by ensuring that every broker in a <firstterm>cluster</firstterm> has the same queues, exchanges, messages, and bindings, and allowing a client to <firstterm>fail over</firstterm> to a new broker and continue without any loss of messages if the current broker fails or becomes unavailable. Because all brokers are automatically kept in a consistent state, clients can connect to and use any broker in a cluster. Any number of messaging brokers can be run as one <firstterm>cluster</firstterm>, and brokers can be added to or removed from a cluster while it is in use.
+ </para>
+ <para>
+ High Availability Messaging Clusters are implemented using using the <ulink url="http://www.openais.org/">OpenAIS Cluster Framework</ulink>.
+ </para>
+ <para>
+ An OpenAIS daemon runs on every machine in the cluster, and these daemons communicate using multicast on a particular address. Every qpidd process in a cluster joins a named group that is automatically synchronized using OpenAIS Closed Process Groups (CPG) — the qpidd processes multicast events to the named group, and CPG ensures that each qpidd process receives all the events in the same sequence. All members get an identical sequence of events, so they can all update their state consistently.
+ </para>
+ <para>
+ Two messaging brokers are in the same cluster if
+ <orderedlist>
+ <listitem>
+ <para>
+ They run on hosts in the same OpenAIS cluster; that is, OpenAIS is configured with the same mcastaddr, mcastport and bindnetaddr, and
+ </para>
+
+ </listitem>
+ <listitem>
+ <para>
+ They use the same cluster name.
+ </para>
+
+ </listitem>
+
+ </orderedlist>
+
+ </para>
+ <para>
+ High Availability Clustering has a cost: in order to allow each broker in a cluster to continue the work of any other broker, a cluster must replicate state for all brokers in the cluster. Because of this, the brokers in a cluster should normally be on a LAN; there should be fast and reliable connections between brokers. Even on a LAN, using multiple brokers in a cluster is somewhat slower than using a single broker without clustering. This may be counter-intuitive for people who are used to clustering in the context of High Performance Computing or High Throughput Computing, where clustering increases performance or throughput.
+ </para>
+
+ <para>
+ High Availability Messaging Clusters should be used together with Red Hat Clustering Services (RHCS); without RHCS, clusters are vulnerable to the &#34;split-brain&#34; condition, in which a network failure splits the cluster into two sub-clusters that cannot communicate with each other. See the documentation on the <command>--cluster-cman</command> option for details on running using RHCS with High Availability Messaging Clusters. See the <ulink url="http://sources.redhat.com/cluster/wiki">CMAN Wiki</ulink> for more detail on CMAN and split-brain conditions. Use the <command>--cluster-cman</command> option to enable RHCS when starting the broker.
+ </para>
+ <section id="sect-Messaging_User_Guide-High_Availability_Messaging_Clusters-Starting_a_Broker_in_a_Cluster">
+ <title>Starting a Broker in a Cluster</title>
+ <para>
+ Clustering is implemented using the <filename>cluster.so</filename> module, which is loaded by default when you start a broker. To run brokers in a cluster, make sure they all use the same OpenAIS mcastaddr, mcastport, and bindnetaddr. All brokers in a cluster must also have the same cluster name — specify the cluster name in <filename>qpidd.conf</filename>:
+ </para>
+
+<screen>cluster-name=&#34;local_test_cluster&#34;
+</screen>
+ <para>
+ On RHEL6, you must create the file <filename>/etc/corosync/uidgid.d/qpidd</filename> to tell Corosync the name of the user running the broker.By default, the user is qpidd:
+ </para>
+
+<programlisting>
+uidgid {
+ uid: qpidd
+ gid: qpidd
+}
+</programlisting>
+ <para>
+ On RHEL5, the primary group for the process running qpidd must be the ais group. If you are running qpidd as a service, it is run as the <command>qpidd</command> user, which is already in the ais group. If you are running the broker from the command line, you must ensure that the primary group for the user running qpidd is ais. You can set the primary group using <command>newgrp</command>:
+ </para>
+
+<screen>$ newgrp ais
+</screen>
+ <para>
+ You can then run the broker from the command line, specifying the cluster name as an option.
+ </para>
+
+<screen>[jonathan@localhost]$ qpidd --cluster-name=&#34;local_test_cluster&#34;
+</screen>
+ <para>
+ All brokers in a cluster must have identical configuration, with a few exceptions noted below. They must load the same set of plug-ins, and have matching configuration files and command line arguments. The should also have identical ACL files and SASL databases if these are used. If one broker uses persistence, all must use persistence — a mix of transient and persistent brokers is not allowed. Differences in configuration can cause brokers to exit the cluster. For instance, if different ACL settings allow a client to access a queue on broker A but not on broker B, then publishing to the queue will succeed on A and fail on B, so B will exit the cluster to prevent inconsistency.
+ </para>
+ <para>
+ The following settings can differ for brokers on a given cluster:
+ </para>
+ <itemizedlist>
+ <listitem>
+ <para>
+ logging options
+ </para>
+
+ </listitem>
+ <listitem>
+ <para>
+ cluster-url — if set, it will be different for each broker.
+ </para>
+
+ </listitem>
+ <listitem>
+ <para>
+ port — brokers can listen on different ports.
+ </para>
+
+ </listitem>
+
+ </itemizedlist>
+ <para>
+ The qpid log contains entries that record significant clustering events, e.g. when a broker becomes a member of a cluster, the membership of a cluster is changed, or an old journal is moved out of the way. For instance, the following message states that a broker has been added to a cluster as the first node:
+ </para>
+
+<screen>
+2009-07-09 18:13:41 info 127.0.0.1:1410(READY) member update: 127.0.0.1:1410(member)
+2009-07-09 18:13:41 notice 127.0.0.1:1410(READY) first in cluster
+</screen>
+ <note>
+ <para>
+ If you are using SELinux, the qpidd process and OpenAIS must have the same SELinux context, or else SELinux must be set to permissive mode. If both qpidd and OpenAIS are run as services, they have the same SELinux context. If both OpenAIS and qpidd are run as user processes, they have the same SELinux context. If one is run as a service, and the other is run as a user process, they have different SELinux contexts.
+ </para>
+
+ </note>
+ <para>
+ The following options are available for clustering:
+ </para>
+ <table frame="all" id="tabl-Messaging_User_Guide-Starting_a_Broker_in_a_Cluster-Options_for_High_Availability_Messaging_Cluster">
+ <title>Options for High Availability Messaging Cluster</title>
+ <tgroup align="left" cols="2" colsep="1" rowsep="1">
+ <colspec colname="c1" colwidth="1*"></colspec>
+ <colspec colname="c2" colwidth="4*"></colspec>
+ <thead>
+ <row>
+ <entry align="center" nameend="c2" namest="c1">
+ Options for High Availability Messaging Cluster
+ </entry>
+
+ </row>
+
+ </thead>
+ <tbody>
+ <row>
+ <entry>
+ <command>--cluster-name <replaceable>NAME</replaceable></command>
+ </entry>
+ <entry>
+ Name of the Messaging Cluster to join. A Messaging Cluster consists of all brokers started with the same cluster-name and openais configuration.
+ </entry>
+
+ </row>
+ <row>
+ <entry>
+ <command>--cluster-size <replaceable>N</replaceable></command>
+ </entry>
+ <entry>
+ Wait for at least N initial members before completing cluster initialization and serving clients. Use this option in a persistent cluster so all brokers in a persistent cluster can exchange the status of their persistent store and do consistency checks before serving clients.
+ </entry>
+
+ </row>
+ <row>
+ <entry>
+ <command>--cluster-url <replaceable>URL</replaceable></command>
+ </entry>
+ <entry>
+ An AMQP URL containing the local address that the broker advertizes to clients for fail-over connections. This is different for each host. By default, all local addresses for the broker are advertized. You only need to set this if
+ <orderedlist>
+ <listitem>
+ <para>
+ Your host has more than one active network interface, and
+ </para>
+
+ </listitem>
+ <listitem>
+ <para>
+ You want to restrict client fail-over to a specific interface or interfaces.
+ </para>
+
+ </listitem>
+
+ </orderedlist>
+ <para>Each broker in the cluster is specified using the following form:</para>
+
+<programlisting>url = [&#34;amqp:&#34;][ user [&#34;/&#34; password] &#34;@&#34; ] protocol_addr
+ (&#34;,&#34; protocol_addr)*
+protocol_addr = tcp_addr / rmda_addr / ssl_addr / ...
+tcp_addr = [&#34;tcp:&#34;] host [&#34;:&#34; port]
+rdma_addr = &#34;rdma:&#34; host [&#34;:&#34; port]
+ssl_addr = &#34;ssl:&#34; host [&#34;:&#34; port]</programlisting>
+
+ <para>In most cases, only one address is advertized, but more than one address can be specified in if the machine running the broker has more than one network interface card, and you want to allow clients to connect using multiple network interfaces. Use a comma delimiter (&#34;,&#34;) to separate brokers in the URL. Examples:</para>
+ <itemizedlist>
+ <listitem>
+ <para>
+ <command>amqp:tcp:192.168.1.103:5672</command> advertizes a single address to the broker for failover.
+ </para>
+
+ </listitem>
+ <listitem>
+ <para>
+ <command>amqp:tcp:192.168.1.103:5672,tcp:192.168.1.105:5672</command> advertizes two different addresses to the broker for failover, on two different network interfaces.
+ </para>
+
+ </listitem>
+
+ </itemizedlist>
+
+ </entry>
+
+ </row>
+ <row>
+ <entry>
+ <command>--cluster-cman</command>
+ </entry>
+ <entry>
+ <para>
+ CMAN protects against the &#34;split-brain&#34; condition, in which a network failure splits the cluster into two sub-clusters that cannot communicate with each other. When &#34;split-brain&#34; occurs, each of the sub-clusters can access shared resources without knowledge of the other sub-cluster, resulting in corrupted cluster integrity.
+ </para>
+ <para>
+ To avoid &#34;split-brain&#34;, CMAN uses the notion of a &#34;quorum&#34;. If more than half the cluster nodes are active, the cluster has quorum and can act. If half (or fewer) nodes are active, the cluster does not have quorum, and all cluster activity is stopped. There are other ways to define the quorum for particular use cases (e.g. a cluster of only 2 members), see the <ulink url="http://sources.redhat.com/cluster/wiki">CMAN Wiki</ulink>
+for more detail.
+ </para>
+ <para>
+ When enabled, the broker will wait until it belongs to a quorate cluster before accepting client connections. It continually monitors the quorum status and shuts down immediately if the node it runs on loses touch with the quorum.
+ </para>
+
+ </entry>
+
+ </row>
+ <row>
+ <entry>
+ --cluster-username
+ </entry>
+ <entry>
+ SASL username for connections between brokers.
+ </entry>
+
+ </row>
+ <row>
+ <entry>
+ --cluster-password
+ </entry>
+ <entry>
+ SASL password for connections between brokers.
+ </entry>
+
+ </row>
+ <row>
+ <entry>
+ --cluster-mechanism
+ </entry>
+ <entry>
+ SASL authentication mechanism for connections between brokers
+ </entry>
+
+ </row>
+
+ </tbody>
+
+ </tgroup>
+
+ </table>
+ <para>
+ If a broker is unable to establish a connection to another broker in the cluster, the log will contain SASL errors, e.g:
+ </para>
+
+<screen>2009-aug-04 10:17:37 info SASL: Authentication failed: SASL(-13): user not found: Password verification failed
+</screen>
+ <para>
+ You can set the SASL user name and password used to connect to other brokers using the <command>cluster-username</command> and <command>cluster-password</command> properties when you start the broker. In most environment, it is easiest to create an account with the same user name and password on each broker in the cluster, and use these as the <command>cluster-username</command> and <command>cluster-password</command>. You can also set the SASL mode using <command>cluster-mechanism</command>. Remember that any mechanism you enable for broker-to-broker communication can also be used by a client, so do not enable <command>cluster-mechanism=ANONYMOUS</command> in a secure environment.
+ </para>
+ <para>
+ Once the cluster is running, run <command>qpid-cluster</command> to make sure that the brokers are running as one cluster. See the following section for details.
+ </para>
+ <para>
+ If the cluster is correctly configured, queues and messages are replicated to all brokers in the cluster, so an easy way to test the cluster is to run a program that routes messages to a queue on one broker, then connect to a different broker in the same cluster and read the messages to make sure they have been replicated. The <command>drain</command> and <command>spout</command> programs can be used for this test.
+ </para>
+
+ </section>
+
+ <section id="sect-Messaging_User_Guide-High_Availability_Messaging_Clusters-qpid_cluster">
+ <title>qpid-cluster</title>
+ <para>
+ <command>qpid-cluster</command> is a command-line utility that allows you to view information on a cluster and its brokers, disconnect a client connection, shut down a broker in a cluster, or shut down the entire cluster. You can see the options using the <command>--help</command> option:
+ </para>
+
+<screen>$ ./qpid-cluster --help
+</screen>
+
+<screen>Usage: qpid-cluster [OPTIONS] [broker-addr]
+
+ broker-addr is in the form: [username/password@] hostname | ip-address [:&#60;port&#62;]
+ ex: localhost, 10.1.1.7:10000, broker-host:10000, guest/guest@localhost
+
+Options:
+ -C [--all-connections] View client connections to all cluster members
+ -c [--connections] ID View client connections to specified member
+ -d [--del-connection] HOST:PORT
+ Disconnect a client connection
+ -s [--stop] ID Stop one member of the cluster by its ID
+ -k [--all-stop] Shut down the whole cluster
+ -f [--force] Suppress the &#39;are-you-sure?&#39; prompt
+ -n [--numeric] Don&#39;t resolve names
+</screen>
+ <para>
+ Let&#39;s connect to a cluster and display basic information about the cluser and its brokers. When you connect to the cluster using <command>qpid-tool</command>, you can use the host and port for any broker in the cluster. For instance, if a broker in the cluster is running on <filename>localhost</filename> on port 6664, you can start <command>qpid-tool</command> like this:
+ </para>
+
+<screen>
+$ qpid-cluster localhost:6664
+</screen>
+ <para>
+ Here is the output:
+ </para>
+
+<screen>
+ Cluster Name: local_test_cluster
+Cluster Status: ACTIVE
+ Cluster Size: 3
+ Members: ID=127.0.0.1:13143 URL=amqp:tcp:192.168.1.101:6664,tcp:192.168.122.1:6664,tcp:10.16.10.62:6664
+ : ID=127.0.0.1:13167 URL=amqp:tcp:192.168.1.101:6665,tcp:192.168.122.1:6665,tcp:10.16.10.62:6665
+ : ID=127.0.0.1:13192 URL=amqp:tcp:192.168.1.101:6666,tcp:192.168.122.1:6666,tcp:10.16.10.62:6666
+</screen>
+ <para>
+ The ID for each broker in cluster is given on the left. For instance, the ID for the first broker in the cluster is <command>127.0.0.1:13143</command>. The URL in the output is the broker&#39;s advertized address. Let&#39;s use the ID to shut the broker down using the <command>--stop</command> command:
+ </para>
+
+<screen>$ ./qpid-cluster localhost:6664 --stop 127.0.0.1:13143
+</screen>
+
+ </section>
+
+ <section id="sect-Messaging_User_Guide-High_Availability_Messaging_Clusters-Failover_in_Clients">
+ <title>Failover in Clients</title>
+ <para>
+ If a client is connected to a broker, the connection fails if the broker crashes or is killed. If heartbeat is enabled for the connection, a connection also fails if the broker hangs, the machine the broker is running on fails, or the network connection to the broker is lost — the connection fails no later than twice the heartbeat interval.
+ </para>
+ <para>
+ When a client&#39;s connection to a broker fails, any sent messages that have been acknowledged to the sender will have been replicated to all brokers in the cluster, any received messages that have not yet been acknowledged by the receiving client requeued to all brokers, and the client API notifies the application of the failure by throwing an exception.
+ </para>
+ <para>
+ Clients can be configured to automatically reconnect to another broker when it receives such an exception. Any messages that have been sent by the client, but not yet acknowledged as delivered, are resent. Any messages that have been read by the client, but not acknowledged, are delivered to the client.
+ </para>
+ <para>
+ TCP is slow to detect connection failures. A client can configure a connection to use a heartbeat to detect connection failure, and can specify a time interval for the heartbeat. If heartbeats are in use, failures will be detected no later than twice the heartbeat interval. The Java JMS client enables hearbeat by default. See the sections on Failover in Java JMS Clients and Failover in C++ Clients for the code to enable heartbeat.
+ </para>
+ <section id="sect-Messaging_User_Guide-Failover_in_Clients-Failover_in_Java_JMS_Clients">
+ <title>Failover in Java JMS Clients</title>
+ <para>
+ In Java JMS clients, client failover is handled automatically if it is enabled in the connection. Any messages that have been sent by the client, but not yet acknowledged as delivered, are resent. Any messages that have been read by the client, but not acknowledged, are sent to the client.
+ </para>
+ <para>
+ You can configure a connection to use failover using the <command>failover</command> property:
+ </para>
+
+<screen>
+connectionfactory.qpidConnectionfactory = amqp://guest:guest@clientid/test?brokerlist=&#39;tcp://localhost:5672&#39;&amp;failover=&#39;failover_exchange&#39;
+</screen>
+ <para>
+ This property can take three values:
+ </para>
+ <variablelist id="vari-Messaging_User_Guide-Failover_in_Java_JMS_Clients-Failover_Modes">
+ <title>Failover Modes</title>
+ <varlistentry>
+ <term>failover_exchange</term>
+ <listitem>
+ <para>
+ If the connection fails, fail over to any other broker in the cluster.
+ </para>
+
+ </listitem>
+
+ </varlistentry>
+ <varlistentry>
+ <term>roundrobin</term>
+ <listitem>
+ <para>
+ If the connection fails, fail over to one of the brokers specified in the <command>brokerlist</command>.
+ </para>
+
+ </listitem>
+
+ </varlistentry>
+ <varlistentry>
+ <term>singlebroker</term>
+ <listitem>
+ <para>
+ Failover is not supported; the connection is to a single broker only.
+ </para>
+
+ </listitem>
+
+ </varlistentry>
+
+ </variablelist>
+ <para>
+ In a Connection URL, heartbeat is set using the <command>idle_timeout</command> property, which is an integer corresponding to the heartbeat period in seconds. For instance, the following line from a JNDI properties file sets the heartbeat time out to 3 seconds:
+ </para>
+
+<screen>
+connectionfactory.qpidConnectionfactory = amqp://guest:guest@clientid/test?brokerlist=&#39;tcp://localhost:5672&#39;,idle_timeout=3
+</screen>
+
+ </section>
+
+ <section id="sect-Messaging_User_Guide-Failover_in_Clients-Failover_and_the_Qpid_Messaging_API">
+ <title>Failover and the Qpid Messaging API</title>
+ <para>
+ The Qpid Messaging API also supports automatic reconnection in the event a connection fails. . Senders can also be configured to replay any in-doubt messages (i.e. messages whice were sent but not acknowleged by the broker. See &#34;Connection Options&#34; and &#34;Sender Capacity and Replay&#34; in <citetitle>Programming in Apache Qpid</citetitle> for details.
+ </para>
+ <para>
+ In C++ and python clients, heartbeats are disabled by default. You can enable them by specifying a heartbeat interval (in seconds) for the connection via the &#39;heartbeat&#39; option.
+ </para>
+ <para>
+ See &#34;Cluster Failover&#34; in <citetitle>Programming in Apache Qpid</citetitle> for details on how to keep the client aware of cluster membership.
+ </para>
+
+ </section>
+
+
+ </section>
+
+ <section id="sect-Messaging_User_Guide-High_Availability_Messaging_Clusters-Error_handling_in_Clusters">
+ <title>Error handling in Clusters</title>
+ <para>
+ If a broker crashes or is killed, or a broker machine failure, broker connection failure, or a broker hang is detected, the other brokers in the cluster are notified that it is no longer a member of the cluster. If a new broker is joined to the cluster, it synchronizes with an active broker to obtain the current cluster state; if this synchronization fails, the new broker exit the cluster and aborts.
+ </para>
+ <para>
+ If a broker becomes extremely busy and stops responding, it stops accepting incoming work. All other brokers continue processing, and the non-responsive node caches all AIS traffic. When it resumes, the broker completes processes all cached AIS events, then accepts further incoming work. <!-- If a broker is non-responsive for too long, it is assumed to be hanging, and treated as described in the previous paragraph. -->
+ </para>
+ <para>
+ Broker hangs are only detected if the watchdog plugin is loaded and the <command>--watchdog-interval</command> option is set. The watchdog plug-in kills the qpidd broker process if it becomes stuck for longer than the watchdog interval. In some cases, e.g. certain phases of error resolution, it is possible for a stuck process to hang other cluster members that are waiting for it to send a message. Using the watchdog, the stuck process is terminated and removed from the cluster, allowing other members to continue and clients of the stuck process to fail over to other members.
+ </para>
+ <para>
+ Redundancy can also be achieved directly in the AIS network by specifying more than one network interface in the AIS configuration file. This causes Totem to use a redundant ring protocol, which makes failure of a single network transparent.
+ </para>
+ <para>
+ Redundancy can be achieved at the operating system level by using NIC bonding, which combines multiple network ports into a single group, effectively aggregating the bandwidth of multiple interfaces into a single connection. This provides both network load balancing and fault tolerance.
+ </para>
+ <para>
+ If any broker encounters an error, the brokers compare notes to see if they all received the same error. If not, the broker removes itself from the cluster and shuts itself down to ensure that all brokers in the cluster have consistent state. For instance, a broker may run out of disk space; if this happens, the broker shuts itself down. Examining the broker&#39;s log can help determine the error and suggest ways to prevent it from occuring in the future.
+ </para>
+ <!-- "Bad case" for cluster matrix - things we will fix, or things users may encounter long term? -->
+ </section>
+
+ <section id="sect-Messaging_User_Guide-High_Availability_Messaging_Clusters-Persistence_in_High_Availability_Message_Clusters">
+ <title>Persistence in High Availability Message Clusters</title>
+ <para>
+ Persistence and clustering are two different ways to provide reliability. Most systems that use a cluster do not enable persistence, but you can do so if you want to ensure that messages are not lost even if the last broker in a cluster fails. A cluster must have all transient or all persistent members, mixed clusters are not allowed. Each broker in a persistent cluster has it&#39;s own independent replica of the cluster&#39;s state it its store.
+ </para>
+ <section id="sect-Messaging_User_Guide-Persistence_in_High_Availability_Message_Clusters-Clean_and_Dirty_Stores">
+ <title>Clean and Dirty Stores</title>
+ <para>
+ When a broker is an active member of a cluster, its store is marked &#34;dirty&#34; because it may be out of date compared to other brokers in the cluster. If a broker leaves a running cluster because it is stopped, it crashes or the host crashes, its store continues to be marked &#34;dirty&#34;.
+ </para>
+ <para>
+ If the cluster is reduced to a single broker, its store is marked &#34;clean&#34; since it is the only broker making updates. If the cluster is shut down with the command <literal>qpid-cluster -k</literal> then all the stores are marked clean.
+ </para>
+ <para>
+ When a cluster is initially formed, brokers with clean stores read from their stores. Brokers with dirty stores, or brokers that join after the cluster is running, discard their old stores and initialize a new store with an update from one of the running brokers. The <command>--truncate</command> option can be used to force a broker to discard all existing stores even if they are clean. (A dirty store is discarded regardless.)
+ </para>
+ <para>
+ Discarded stores are copied to a back up directory. The active store is in &#60;data-dir&#62;/rhm. Back-up stores are in &#60;data-dir&#62;/_cluster.bak.&#60;nnnn&#62;/rhm, where &#60;nnnn&#62; is a 4 digit number. A higher number means a more recent backup.
+ </para>
+
+ </section>
+
+ <section id="sect-Messaging_User_Guide-Persistence_in_High_Availability_Message_Clusters-Starting_a_persistent_cluster">
+ <title>Starting a persistent cluster</title>
+ <para>
+ When starting a persistent cluster broker, set the cluster-size option to the number of brokers in the cluster. This allows the brokers to wait until the entire cluster is running so that they can synchronize their stored state.
+ </para>
+ <para>
+ The cluster can start if:
+ </para>
+ <para>
+ <itemizedlist>
+ <listitem>
+ <para>
+ all members have empty stores, or
+ </para>
+
+ </listitem>
+ <listitem>
+ <para>
+ at least one member has a clean store
+ </para>
+
+ </listitem>
+
+ </itemizedlist>
+
+ </para>
+ <para>
+ All members of the new cluster will be initialized with the state from a clean store.
+ </para>
+
+ </section>
+
+ <section id="sect-Messaging_User_Guide-Persistence_in_High_Availability_Message_Clusters-Stopping_a_persistent_cluster">
+ <title>Stopping a persistent cluster</title>
+ <para>
+ To cleanly shut down a persistent cluster use the command <command>qpid-cluster -k</command>. This causes all brokers to synchronize their state and mark their stores as &#34;clean&#34; so they can be used when the cluster restarts.
+ </para>
+
+ </section>
+
+ <section id="sect-Messaging_User_Guide-Persistence_in_High_Availability_Message_Clusters-Starting_a_persistent_cluster_with_no_clean_store">
+ <title>Starting a persistent cluster with no clean store</title>
+ <para>
+ If the cluster has previously had a total failure and there are no clean stores then the brokers will fail to start with the log message <literal>Cannot recover, no clean store.</literal> If this happens you can start the cluster by marking one of the stores &#34;clean&#34; as follows:
+ </para>
+ <procedure>
+ <step>
+ <para>
+ Move the latest store backup into place in the brokers data-directory. The backups end in a 4 digit number, the latest backup is the highest number.
+ </para>
+
+<screen>
+ cd &#60;data-dir&#62;
+ mv rhm rhm.bak
+ cp -a _cluster.bak.&#60;nnnn&#62;/rhm .
+</screen>
+
+ </step>
+ <step>
+ <para>
+ Mark the store as clean:
+<screen>qpid-cluster-store -c &#60;data-dir&#62;</screen>
+
+ </para>
+
+ </step>
+
+ </procedure>
+
+ <para>
+ Now you can start the cluster, all members will be initialized from the store you marked as clean.
+ </para>
+
+ </section>
+
+ <section id="sect-Messaging_User_Guide-Persistence_in_High_Availability_Message_Clusters-Isolated_failures_in_a_persistent_cluster">
+ <title>Isolated failures in a persistent cluster</title>
+ <para>
+ A broker in a persistent cluster may encounter errors that other brokers in the cluster do not; if this happens, the broker shuts itself down to avoid making the cluster state inconsistent. For example a disk failure on one node will result in that node shutting down. Running out of storage capacity can also cause a node to shut down because because the brokers may not run out of storage at exactly the same point, even if they have similar storage configuration. To avoid unnecessary broker shutdowns, make sure the queue policy size of each durable queue is less than the capacity of the journal for the queue.
+ </para>
+
+ </section>
+
+
+ </section>
+
+
+</section>
diff --git a/qpid/doc/book/src/System-Properties.xml b/qpid/doc/book/src/System-Properties.xml
new file mode 100644
index 0000000000..d61673f234
--- /dev/null
+++ b/qpid/doc/book/src/System-Properties.xml
@@ -0,0 +1,417 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+
+ 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.
+
+-->
+
+<section>
+
+ <title>
+ System Properties
+ </title>
+
+ <section role="h2" id="SystemProperties-ExplanationofSystempropertiesusedinQpid">
+
+ <title> Explanation of System properties used in Qpid </title>
+
+ <para>
+ This page documents the various System Properties that are
+ currently used in the Qpid Java code base.
+ </para>
+
+<!-- ######################################################### -->
+
+ <section role="h3" id="SystemProperties-ClientProperties">
+ <title> Client Properties </title>
+
+ <variablelist>
+ <varlistentry>
+ <term>STRICT_AMQP</term>
+ <listitem>
+ <variablelist>
+ <varlistentry>
+ <term>Type</term>
+ <listitem><para>Boolean</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Default</term>
+ <listitem><para>FALSE</para></listitem>
+ </varlistentry>
+ </variablelist>
+ <para> This forces the client to only send AMQP compliant
+ frames. This will disable a number of JMS features.</para>
+
+ <itemizedlist>
+ <title> Features disabled by STRICT_AMQP</title>
+ <listitem><para>Queue Browser
+ </para></listitem>
+ <listitem><para>Message Selectors
+ </para></listitem>
+ <listitem><para>Durable Subscriptions
+ </para></listitem>
+ <listitem><para>Session Recover may result in duplicate message delivery
+ </para></listitem>
+ <listitem><para>Destination validation, so no InvalidDestinationException
+ will be thrown
+ </para></listitem>
+ </itemizedlist>
+ <para>
+ This is associated with property <xref linkend="SystemProperties-STRICTAMQPFATAL"/>
+ </para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry id="SystemProperties-STRICTAMQPFATAL">
+ <term>STRICT_AMQP_FATAL</term>
+ <listitem>
+ <variablelist>
+ <varlistentry>
+ <term>Type</term>
+ <listitem><para>Boolean</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Default</term>
+ <listitem><para>FALSE</para></listitem>
+ </varlistentry>
+ </variablelist>
+ <para>
+ This will cause any attempt to utilise an enhanced feature to
+ throw and UnsupportedOperationException. When set to false then
+ the exception will not occur but the feature will be disabled.
+ </para>
+ <para>
+ e.g.
+ The Queue Browser will always show no messages.
+ Any message selector will be removed.
+ </para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>IMMEDIATE_PREFETCH</term>
+ <listitem>
+ <variablelist>
+ <varlistentry>
+ <term>Type</term>
+ <listitem><para>Boolean</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Default</term>
+ <listitem><para>FALSE</para></listitem>
+ </varlistentry>
+ </variablelist>
+ <para>
+ The default with AMQP is to start prefetching messages. However,
+ with certain 3rd party Java tools, such as Mule this can cause a
+ problem. Mule will create a consumer but never consume from it so
+ any any prefetched messages will be stuck until that session is
+ closed. This property is used to re-instate the default AMQP
+ behaviour. The default Qpid behaviour is to prevent prefetch
+ occurring, by starting the connection Flow Controlled, until a
+ request for a message is made on the consumer either via a
+ receive() or setting a message listener.</para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term>amqj.default_syncwrite_timeout</term>
+ <listitem>
+ <variablelist>
+ <varlistentry>
+ <term>Type</term>
+ <listitem><para>long</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Default</term>
+ <listitem><para>30000</para></listitem>
+ </varlistentry>
+ </variablelist>
+ <para> The number length of time in millisecond to wait
+ for a synchronous write to complete.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>amq.dynamicsaslregistrar.properties</term>
+ <listitem>
+ <variablelist>
+ <varlistentry>
+ <term>Type</term>
+ <listitem><para>String</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Default</term>
+ <listitem><para>org/apache/qpid/client/security/DynamicSaslRegistrar.properties</para></listitem>
+ </varlistentry>
+ </variablelist>
+ <para>The name of the SASL configuration properties file.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>amqj.heartbeat.timeoutFactor</term>
+ <listitem>
+ <variablelist>
+ <varlistentry>
+ <term>Type</term>
+ <listitem><para>float</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Default</term>
+ <listitem><para>2.0</para></listitem>
+ </varlistentry>
+ </variablelist>
+ <para>
+ The factor used to get the timeout from the delay between
+ heartbeats
+ </para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>amqj.tcpNoDelay</term>
+ <listitem>
+ <variablelist>
+ <varlistentry>
+ <term>Type</term>
+ <listitem><para>Boolean</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Default</term>
+ <listitem><para>TRUE</para></listitem>
+ </varlistentry>
+ </variablelist>
+ <para> Disable Nagle's algorithm on the TCP connection.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>amqj.sendBufferSize</term>
+ <listitem>
+ <variablelist>
+ <varlistentry>
+ <term>integer</term>
+ <listitem><para>Boolean</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Default</term>
+ <listitem><para>32768</para></listitem>
+ </varlistentry>
+ </variablelist>
+ <para>This is the default buffer sized created by Mina.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>amqj.receiveBufferSize</term>
+ <listitem>
+ <variablelist>
+ <varlistentry>
+ <term>Type</term>
+ <listitem><para>integer</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Default</term>
+ <listitem><para>32768</para></listitem>
+ </varlistentry>
+ </variablelist>
+ <para>This is the default buffer sized created by Mina.
+ </para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>amqj.protocolprovider.class</term>
+ <listitem>
+ <variablelist>
+ <varlistentry>
+ <term>Type</term>
+ <listitem><para>String</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Default</term>
+ <listitem><para>org.apache.qpid.server.protocol.AMQPFastProtocolHandler</para></listitem>
+ </varlistentry>
+ </variablelist>
+ <para> This specifies the default IoHandlerAdapter that
+ represents the InVM broker. The IoHandlerAdapter must have
+ a constructor that takes a single Integer that represents
+ the InVM port number.
+ </para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>amqj.protocol.logging.level</term>
+ <listitem>
+ <variablelist>
+ <varlistentry>
+ <term>Type</term>
+ <listitem><para>Boolean</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Default</term>
+ <listitem><para>null</para></listitem>
+ </varlistentry>
+ </variablelist>
+ <para>If set this will turn on protocol logging on the
+ client. </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>jboss.host</term>
+ <listitem>
+ <para>
+ Used by the JBossConnectionFactoryInitialiser to specify the host
+ to connect to perform JNDI lookups.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>jboss.port</term>
+ <listitem>
+ <para>
+ Used by the JBossConnectionFactoryInitialiser to specify the port
+ to connect to perform JNDI lookups.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>amqj.MaximumStateWait</term>
+ <listitem>
+ <variablelist>
+ <varlistentry>
+ <term>Default</term>
+ <listitem><para>30000</para></listitem>
+ </varlistentry>
+ </variablelist>
+ <para>
+ Used to set the maximum time the State Manager should wait before
+ timing out a frame wait.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </section>
+<!-- ######################################################### -->
+
+ <section role="h3" id="SystemProperties-ManagementProperties">
+
+ <title>
+ Management Properties
+ </title>
+
+ <variablelist>
+ <varlistentry>
+ <term>security</term>
+ <listitem>
+ <variablelist>
+ <varlistentry>
+ <term>Default</term>
+ <listitem><para>null</para></listitem>
+ </varlistentry>
+ </variablelist>
+ <para>
+ String representing the Security level to be used to on
+ the connection to the broker. The null default results
+ in no security or PLAIN. When used with jmxconnector
+ 'javax.management.remote.jmxmp.JMXMPConnector' a
+ security value of 'CRAM-MD5' will result in all
+ communication to the broker being encrypted.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>jmxconnector</term>
+ <listitem>
+ <variablelist>
+ <varlistentry>
+ <term>Default</term>
+ <listitem><para>null</para></listitem>
+ </varlistentry>
+ </variablelist>
+ <para>
+ String representing the JMXConnector class used to
+ perform the connection to the broker. The null default
+ results in the standard JMX connector. Utilising
+ 'javax.management.remote.jmxmp.JMXMPConnector' and
+ security 'CRAM-MD5' will result in all communication to
+ the broker being encrypted.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>timeout</term>
+ <listitem>
+ <variablelist>
+ <varlistentry>
+ <term>Default</term>
+ <listitem><para>5000</para></listitem>
+ </varlistentry>
+ </variablelist>
+ <para>
+ Long value representing the milli seconds before
+ connection to the broker should timeout.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+
+ </section>
+
+
+<!-- ######################################################### -->
+
+
+ <section role="h3" id="SystemProperties-PropertiesusedinExamples">
+
+ <title> Properties used in Examples </title>
+
+ <variablelist>
+ <varlistentry>
+ <term>archivepath</term>
+ <listitem>
+ <para>
+ Used in <filename>FileMessageDispatcher</filename>. This
+ properties specifies the directory to move payload
+ file(s) to archive location as no error</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+</section>
+</section>
+</section>
diff --git a/qpid/doc/book/src/Use-Priority-Queues.xml b/qpid/doc/book/src/Use-Priority-Queues.xml
new file mode 100644
index 0000000000..eeac3de06d
--- /dev/null
+++ b/qpid/doc/book/src/Use-Priority-Queues.xml
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+
+ 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.
+
+-->
+
+<section><title>
+ Use Priority Queues
+ </title>
+
+
+ <section role="h2" id="UsePriorityQueues-GeneralInformation"><title>
+ General
+ Information
+ </title>
+ <para>
+ The Qpid M3 release introduces priority queues into the Java
+ Messaging Broker, supporting JMS clients who wish to make use of
+ priorities in their messaging implementation.
+ </para><para>
+ There are some key points around the use of priority queues in
+ Qpid, discussed in the sections below.
+ </para>
+<!--h2--></section>
+ <section role="h2" id="UsePriorityQueues-DefiningPriorityQueues"><title>
+ Defining
+ Priority Queues
+ </title>
+ <para>
+ You must define a priority queue specifically before you start to
+ use it. You cannot subsequently change a queue to/from a priority
+ queue (without deleting it and re-creating).
+ </para><para>
+ You define a queue as a priority queue in the virtualhost
+ configuration file, which the broker loads at startup. When
+ defining the queue, add a &lt;priority&gt;true&lt;/priority&gt;
+ element. This will ensure that the queue has 10 distinct
+ priorities, which is the number supported by JMS.
+ </para><para>
+ If you require fewer priorities, it is possible to specify a
+ &lt;priorities&gt;int&lt;/priorities&gt; element (where int is a
+ valid integer value between 2 and 10 inclusive) which will give
+ the queue that number of distinct priorities. When messages are
+ sent to that queue, their effective priority will be calculated
+ by partitioning the priority space. If the number of effective
+ priorities is 2, then messages with priority 0-4 are treated the
+ same as "lower priority" and messages with priority 5-9 are
+ treated equivalently as "higher priority".
+ </para>
+ <programlisting>
+&lt;queue&gt;
+ &lt;name&gt;test&lt;/name&gt;
+ &lt;test&gt;
+ &lt;exchange&gt;amq.direct&lt;/exchange&gt;
+ &lt;priority&gt;true&lt;/priority&gt;
+ &lt;/test&gt;
+&lt;/queue&gt;
+</programlisting>
+<!--h2--></section>
+
+ <section role="h2" id="UsePriorityQueues-Clientconfiguration-2Fmessagingmodelforpriorityqueues"><title>
+ Client configuration/messaging model for priority queues
+ </title>
+ <para>
+ There are some other configuration &amp; paradigm changes which
+ are required in order that priority queues work as expected.
+ </para>
+ <section role="h3" id="UsePriorityQueues-Setlowprefetch"><title>
+ Set low pre-fetch
+ </title>
+ <para>
+ Qpid clients receive buffered messages in batches, sized
+ according to the pre-fetch value. The current default is 5000.
+ </para><para>
+ However, if you use the default value you will probably
+ <emphasis>not</emphasis> see desirable behaviour with messages of different
+ priority. This is because a message arriving after the pre-fetch
+ buffer has filled will not leap frog messages of lower priority.
+ It will be delivered at the front of the next batch of buffered
+ messages (if that is appropriate), but this is most likely NOT
+ what you need.
+ </para><para>
+ So, you need to set the prefetch values for your client
+ (consumer) to make this sensible. To do this set the java system
+ property max_prefetch on the client environment (using -D) before
+ creating your consumer.
+ </para><para>
+ Setting the Qpid pre-fetch to 1 for your client means that
+ message priority will be honoured by the Qpid broker as it
+ dispatches messages to your client. A default for all client
+ connections can be set via a system property:
+ </para>
+ <programlisting>
+-Dmax_prefetch=1
+</programlisting>
+ <para>
+ The prefetch can be also be adjusted on a per connection basis by
+ adding a 'maxprefetch' value to the <xref linkend="Connection-URL-Format"/>
+ </para>
+ <programlisting>
+amqp://guest:guest@client1/development?maxprefetch='1'&amp;brokerlist='tcp://localhost:5672'
+</programlisting>
+ <para>
+ There is a slight performance cost here if using the receive()
+ method and you could test with a slightly higher pre-fetch (up to
+ 10) if the trade-off between throughput and prioritisation is
+ weighted towards the former for your application. (If you're
+ using OnMessage() then this is not a concern.)
+ </para>
+<!--h3--></section>
+ <section role="h3" id="UsePriorityQueues-Singleconsumerpersession"><title>
+ Single
+ consumer per session
+ </title>
+ <para>
+ If you are using the receive() method to consume messages then
+ you should also only use one consumer per session with priority
+ queues. If you're using OnMessage() then this is not a concern.
+ </para>
+<!--h3--></section>
+<!--h2--></section>
+</section>
diff --git a/qpid/doc/book/src/Using-Broker-Federation.xml b/qpid/doc/book/src/Using-Broker-Federation.xml
new file mode 100644
index 0000000000..f5fedf814c
--- /dev/null
+++ b/qpid/doc/book/src/Using-Broker-Federation.xml
@@ -0,0 +1,661 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+
+ 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.
+
+-->
+
+<section id="chap-Messaging_User_Guide-Broker_Federation">
+ <title>Broker Federation</title>
+ <para>
+ <firstterm>Broker Federation</firstterm> allows messaging networks to be defined by creating <firstterm>message routes</firstterm>, in which messages in one broker (the <firstterm>source broker</firstterm>) are automatically routed to another broker (the <firstterm>destination broker</firstterm>). These routes may be defined between exchanges in the two brokers (the <firstterm>source exchange</firstterm> and the <firstterm>destination exchange</firstterm>), or from a queue in the source broker (the <firstterm>source queue</firstterm>) to an exchange in the destination broker. Message routes are unidirectional; when bidirectional flow is needed, one route is created in each direction. Routes can be durable or transient. A durable route survives broker restarts, restoring a route as soon as both the source broker and the destination are available. If the connection to a destination is lost, messages associated with a durable route continue to accumulate on the source, so they can be retrieved when the connection is reestablished.
+ </para>
+ <para>
+ Broker Federation can be used to build large messaging networks, with many brokers, one route at a time. If network connectivity permits, an entire distributed messaging network can be configured from a single location. The rules used for routing can be changed dynamically as servers change, responsibilities change, at different times of day, or to reflect other changing conditions.
+ </para>
+ <para>
+ Broker Federation is useful in a wide variety of scenarios. Some of these have to do with functional organization; for instance, brokers may be organized by geography, service type, or priority. Here are some use cases for federation:
+ <itemizedlist>
+ <listitem>
+ <para>
+ Geography: Customer requests may be routed to a processing location close to the customer.
+ </para>
+
+ </listitem>
+ <listitem>
+ <para>
+ Service Type: High value customers may be routed to more responsive servers.
+ </para>
+
+ </listitem>
+ <listitem>
+ <para>
+ Load balancing: Routing among brokers may be changed dynamically to account for changes in actual or anticipated load.
+ </para>
+
+ </listitem>
+ <listitem>
+ <para>
+ High Availability: Routing may be changed to a new broker if an existing broker becomes unavailable.
+ </para>
+
+ </listitem>
+ <listitem>
+ <para>
+ WAN Connectivity: Federated routes may connect disparate locations across a wide area network, while clients connect to brokers on their own local area network. Each broker can provide persistent queues that can hold messages even if there are gaps in WAN connectivity.
+ </para>
+
+ </listitem>
+ <listitem>
+ <para>
+ Functional Organization: The flow of messages among software subsystems can be configured to mirror the logical structure of a distributed application.
+ </para>
+
+ </listitem>
+ <listitem>
+ <para>
+ Replicated Exchanges: High-function exchanges like the XML exchange can be replicated to scale performance.
+ </para>
+
+ </listitem>
+ <listitem>
+ <para>
+ Interdepartmental Workflow: The flow of messages among brokers can be configured to mirror interdepartmental workflow at an organization.
+ </para>
+
+ </listitem>
+
+ </itemizedlist>
+
+ </para>
+ <section id="sect-Messaging_User_Guide-Broker_Federation-Message_Routes">
+ <title>Message Routes</title>
+ <para>
+ Broker Federation is done by creating message routes. The destination for a route is always an exchange on the destination broker. By default, a message route is created by configuring the destination broker, which then contacts the source broker to subscribe to the source queue. This is called a <firstterm>pull route</firstterm>. It is also possible to create a route by configuring the source broker, which then contacts the destination broker in order to send messages. This is called a <firstterm>push route</firstterm>, and is particularly useful when the destination broker may not be available at the time the messaging route is configured, or when a large number of routes are created with the same destination exchange.
+ </para>
+ <para>
+ The source for a route can be either an exchange or a queue on the source broker. If a route is between two exchanges, the routing criteria can be given explicitly, or the bindings of the destination exchange can be used to determine the routing criteria. To support this functionality, there are three kinds of message routes: queue routes, exchange routes, and dynamic exchange routes.
+ </para>
+ <section id="sect-Messaging_User_Guide-Message_Routes-Queue_Routes">
+ <title>Queue Routes</title>
+ <para>
+ <firstterm>Queue Routes</firstterm> route all messages from a source queue to a destination exchange. If message acknowledgement is enabled, messages are removed from the queue when they have been received by the destination exchange; if message acknowledgement is off, messages are removed from the queue when sent.
+ </para>
+
+ </section>
+
+ <section id="sect-Messaging_User_Guide-Message_Routes-Exchange_Routes">
+ <title>Exchange Routes</title>
+ <para>
+ <firstterm>Exchange routes</firstterm> route messages from a source exchange to a destination exchange, using a binding key (which is optional for a fanout exchange).
+ </para>
+ <para>
+ Internally, creating an exchange route creates a private queue (auto-delete, exclusive) on the source broker to hold messages that are to be routed to the destination broker, binds this private queue to the source broker exchange, and subscribes the destination broker to the queue.
+ </para>
+
+ </section>
+
+ <section id="sect-Messaging_User_Guide-Message_Routes-Dynamic_Exchange_Routes">
+ <title>Dynamic Exchange Routes</title>
+ <para>
+ Dynamic exchange routes allow a client to create bindings to an exchange on one broker, and receive messages that satisfy the conditions of these bindings not only from the exchange to which the client created the binding, but also from other exchanges that are connected to it using dynamic exchange routes. If the client modifies the bindings for a given exchange, they are also modified for dynamic exchange routes associated with that exchange.
+ </para>
+ <para>
+ <firstterm>Dynamic exchange routes</firstterm> apply all the bindings of a destination exchange to a source exchange, so that any message that would match one of these bindings is routed to the destination exchange. If bindings are added or removed from the destination exchange, these changes are reflected in the dynamic exchange route -- when the destination broker creates a binding with a given binding key, this is reflected in the route, and when the destination broker drops a binding with a binding key, the route no longer incurs the overhead of transferring messages that match the binding key among brokers. If two exchanges have dynamic exchange routes to each other, then all bindings in each exchange are reflected in the dynamic exchange route of the other. In a dynamic exchange route, the source and destination exchanges must have the same exchange type, and they must have the same name; for instance, if the source exchange is a direct exchange, the destination exchange must also be a direct exchange, and the names must match.
+ </para>
+ <para>
+ Internally, dynamic exchange routes are implemented in the same way as exchange routes, except that the bindings used to implement dynamic exchange routes are modified if the bindings in the destination exchange change.
+ </para>
+ <para>
+ A dynamic exchange route is always a pull route. It can never be a push route.
+ </para>
+
+ </section>
+
+
+ </section>
+
+ <section id="sect-Messaging_User_Guide-Broker_Federation-Federation_Topologies">
+ <title>Federation Topologies</title>
+ <para>
+ A federated network is generally a tree, star, or line, using bidirectional links (implemented as a pair of unidirectional links) between any two brokers. A ring topology is also possible, if only unidirectional links are used.
+ </para>
+ <para>
+ Every message transfer takes time. For better performance, you should minimize the number of brokers between the message origin and final destination. In most cases, tree or star topologies do this best.
+ </para>
+ <para>
+ For any pair of nodes A,B in a federated network, there should be only one path from A to B. If there is more than one path, message loops can cause duplicate message transmission and flood the federated network. The topologies discussed above do not have message loops. A ring topology with bidirectional links is one example of a topology that does cause this problem, because a given broker can receive the same message from two different brokers. Mesh topologies can also cause this problem.
+ </para>
+
+ </section>
+
+ <section id="sect-Messaging_User_Guide-Broker_Federation-Federation_among_High_Availability_Message_Clusters">
+ <title>Federation among High Availability Message Clusters</title>
+ <para>
+ Federation is generally used together with High Availability Message Clusters, using clusters to provide high availability on each LAN, and federation to route messages among the clusters. Because message state is replicated within a cluster, it makes little sense to define message routes between brokers in the same cluster.
+ </para>
+ <para>
+ To create a message route between two clusters, simply create a route between any one broker in the first cluster and any one broker in the second cluster. Each broker in a given cluster can use message routes defined for another broker in the same cluster. If the broker for which a message route is defined should fail, another broker in the same cluster can restore the message route.
+ </para>
+
+ </section>
+
+ <section id="sect-Messaging_User_Guide-Broker_Federation-The_qpid_route_Utility">
+ <title>The qpid-route Utility</title>
+ <para>
+ <command>qpid-route</command> is a command line utility used to configure federated networks of brokers and to view the status and topology of networks. It can be used to configure routes among any brokers that <command>qpid-route</command> can connect to.
+ </para>
+ <para>
+ The syntax of <command>qpid-route</command> is as follows:
+ </para>
+
+<screen>
+qpid-route [OPTIONS] dynamic add &#60;dest-broker&#62; &#60;src-broker&#62; &#60;exchange&#62;
+qpid-route [OPTIONS] dynamic del &#60;dest-broker&#62; &#60;src-broker&#62; &#60;exchange&#62;
+
+qpid-route [OPTIONS] route add &#60;dest-broker&#62; &#60;src-broker&#62; &#60;exchange&#62; &#60;routing-key&#62;
+qpid-route [OPTIONS] route del &#60;dest-broker&#62; &#60;src-broker&#62; &#60;exchange&#62; &#60;routing-key&#62;
+
+qpid-route [OPTIONS] queue add &#60;dest-broker&#62; &#60;src-broker&#62; &#60;dest-exchange&#62; &#60;src-queue&#62;
+qpid-route [OPTIONS] queue del &#60;dest-broker&#62; &#60;src-broker&#62; &#60;dest-exchange&#62; &#60;src-queue&#62;
+
+qpid-route [OPTIONS] list [&#60;broker&#62;]
+qpid-route [OPTIONS] flush [&#60;broker&#62;]
+qpid-route [OPTIONS] map [&#60;broker&#62;]
+
+<!-- qpid-route [OPTIONS] add connection &lt;dest-broker&gt; &lt;src-broker&gt;
+qpid-route [OPTIONS] del connection &lt;dest-broker&gt; &lt;src-broker&gt; -->
+qpid-route [OPTIONS] list connections [&#60;broker&#62;]
+</screen>
+ <para>
+ The syntax for <command>broker</command>, <command>dest-broker</command>, and <command>src-broker</command> is as follows:
+ </para>
+
+<screen>
+[username/password@] hostname | ip-address [:&#60;port&#62;]
+</screen>
+ <para>
+ The following are all valid examples of the above syntax: <command>localhost</command>, <command>10.1.1.7:10000</command>, <command>broker-host:10000</command>, <command>guest/guest@localhost</command>.
+ </para>
+ <para>
+ These are the options for <command>qpid-route</command>:
+ </para>
+ <table frame="all" id="tabl-Messaging_User_Guide-The_qpid_route_Utility-qpid_route_options">
+ <title><command>qpid-route</command> options</title>
+ <tgroup align="left" cols="2" colsep="1" rowsep="1">
+ <colspec colname="c1"></colspec>
+ <colspec colname="c2"></colspec>
+ <!-- <thead>
+ <row>
+ <entry align="center" nameend="c2" namest="c1">
+ Options for using <command>qpid-route</command> to Manage Federation
+ </entry>
+ </row>
+ </thead>
+ --> <tbody>
+ <row>
+ <entry>
+ <command>-v</command>
+ </entry>
+ <entry>
+ Verbose output.
+ </entry>
+
+ </row>
+ <row>
+ <entry>
+ <command>-q</command>
+ </entry>
+ <entry>
+ Quiet output, will not print duplicate warnings.
+ </entry>
+
+ </row>
+ <row>
+ <entry>
+ <command>-d</command>
+ </entry>
+ <entry>
+ Make the route durable.
+ </entry>
+
+ </row>
+ <!--
+ <row>
+ <entry>
+ <command>-e</command>
+ </entry>
+ <entry>
+ Delete link after deleting the last route on the link.
+ </entry>
+ </row> --> <row>
+ <entry>
+ <command> --timeout N</command>
+ </entry>
+ <entry>
+ Maximum time to wait when qpid-route connects to a broker, in seconds. Default is 10 seconds.
+ </entry>
+
+ </row>
+ <row>
+ <entry>
+ <command>--ack N</command>
+ </entry>
+ <entry>
+ Acknowledge transfers of routed messages in batches of N. Default is 0 (no acknowledgements). Setting to 1 or greater enables acknowledgements; when using acknowledgements, values of N greater than 1 can significnantly improve performance, especially if there is significant network latency between the two brokers.
+ </entry>
+
+ </row>
+ <row>
+ <entry>
+ <command>-s [ --src-local ]</command>
+ </entry>
+ <entry>
+ Configure the route in the source broker (create a push route).
+ </entry>
+
+ </row>
+ <row>
+ <entry>
+ <command>-t &#60;transport&#62; [ --transport &#60;transport&#62;]</command>
+ </entry>
+ <entry>
+ Transport protocol to be used for the route.
+ <itemizedlist>
+ <listitem>
+ <para>
+ tcp (default)
+ </para>
+
+ </listitem>
+ <listitem>
+ <para>
+ ssl
+ </para>
+
+ </listitem>
+ <listitem>
+ <para>
+ rdma
+ </para>
+
+ </listitem>
+
+ </itemizedlist>
+
+ </entry>
+
+ </row>
+
+ </tbody>
+
+ </tgroup>
+
+ </table>
+ <section id="sect-Messaging_User_Guide-The_qpid_route_Utility-Creating_and_Deleting_Queue_Routes">
+ <title>Creating and Deleting Queue Routes</title>
+ <para>
+ The syntax for creating and deleting queue routes is as follows:
+ </para>
+
+<screen>
+qpid-route [OPTIONS] queue add &#60;dest-broker&#62; &#60;src-broker&#62; &#60;dest-exchange&#62; &#60;src-queue&#62;
+qpid-route [OPTIONS] queue del &#60;dest-broker&#62; &#60;src-broker&#62; &#60;dest-exchange&#62; &#60;src-queue&#62;
+</screen>
+ <para>
+ For instance, the following creates a queue route that routes all messages from the queue named <command>public</command> on the source broker <command>localhost:10002</command> to the <command>amq.fanout</command> exchange on the destination broker <command>localhost:10001</command>:
+ </para>
+
+<screen>
+$ qpid-route queue add localhost:10001 localhost:10002 amq.fanout public
+</screen>
+ <para>
+ If the <command>-d</command> option is specified, this queue route is persistent, and will be restored if one or both of the brokers is restarted:
+ </para>
+
+<screen>
+$ qpid-route -d queue add localhost:10001 localhost:10002 amq.fanout public
+</screen>
+ <para>
+ The <command>del</command> command takes the same arguments as the <command>add</command> command. The following command deletes the queue route described above:
+ </para>
+
+<screen>
+$ qpid-route queue del localhost:10001 localhost:10002 amq.fanout public
+</screen>
+
+ </section>
+
+ <section id="sect-Messaging_User_Guide-The_qpid_route_Utility-Creating_and_Deleting_Exchange_Routes">
+ <title>Creating and Deleting Exchange Routes</title>
+ <para>
+ The syntax for creating and deleting exchange routes is as follows:
+ </para>
+
+<screen>
+qpid-route [OPTIONS] route add &#60;dest-broker&#62; &#60;src-broker&#62; &#60;exchange&#62; &#60;routing-key&#62;
+qpid-route [OPTIONS] route del &#60;dest-broker&#62; &#60;src-broker&#62; &#60;exchange&#62; &#60;routing-key&#62;
+qpid-route [OPTIONS] flush [&#60;broker&#62;]
+</screen>
+ <para>
+ For instance, the following creates an exchange route that routes messages that match the binding key <command>global.#</command> from the <command>amq.topic</command> exchange on the source broker <command>localhost:10002</command> to the <command>amq.topic</command> exchange on the destination broker <command>localhost:10001</command>:
+ </para>
+
+<screen>
+$ qpid-route route add localhost:10001 localhost:10002 amq.topic global.#
+</screen>
+ <para>
+ In many applications, messages published to the destination exchange should also be routed to the source exchange. This is accomplished by creating a second exchange route, reversing the roles of the two exchanges:
+ </para>
+
+<screen>
+$ qpid-route route add localhost:10002 localhost:10001 amq.topic global.#
+</screen>
+ <para>
+ If the <command>-d</command> option is specified, the exchange route is persistent, and will be restored if one or both of the brokers is restarted:
+ </para>
+
+<screen>
+$ qpid-route -d route add localhost:10001 localhost:10002 amq.fanout public
+</screen>
+ <para>
+ The <command>del</command> command takes the same arguments as the <command>add</command> command. The following command deletes the first exchange route described above:
+ </para>
+
+<screen>
+$ qpid-route route del localhost:10001 localhost:10002 amq.topic global.#
+</screen>
+
+ </section>
+
+ <section id="sect-Messaging_User_Guide-The_qpid_route_Utility-Deleting_all_routes_for_a_broker">
+ <title>Deleting all routes for a broker</title>
+ <para>
+ Use the <command>flush</command> command to delete all routes for a given broker:
+ </para>
+
+<screen>
+qpid-route [OPTIONS] flush [&#60;broker&#62;]
+</screen>
+ <para>
+ For instance, the following command deletes all routes for the broker <command>localhost:10001</command>:
+ </para>
+
+<screen>
+$ qpid-route flush localhost:10001
+</screen>
+
+ </section>
+
+ <section id="sect-Messaging_User_Guide-The_qpid_route_Utility-Creating_and_Deleting_Dynamic_Exchange_Routes">
+ <title>Creating and Deleting Dynamic Exchange Routes</title>
+ <para>
+ The syntax for creating and deleting dynamic exchange routes is as follows:
+ </para>
+
+<screen>
+qpid-route [OPTIONS] dynamic add &#60;dest-broker&#62; &#60;src-broker&#62; &#60;exchange&#62;
+qpid-route [OPTIONS] dynamic del &#60;dest-broker&#62; &#60;src-broker&#62; &#60;exchange&#62;
+</screen>
+ <para>
+ In the following examples, we will route messages from a topic exchange. We will create a new topic exchange and federate it so that we are not affected by other all clients that use the built-in <command>amq.topic</command> exchange. The following commands create a new topic exchange on each of two brokers:
+ </para>
+
+<screen>
+$ qpid-config -a localhost:10003 add exchange topic fed.topic
+$ qpid-config -a localhost:10004 add exchange topic fed.topic
+</screen>
+ <para>
+ Now let&#39;s create a dynamic exchange route that routes messages from the <command>fed.topic</command> exchange on the source broker <command>localhost:10004</command> to the <command>fed.topic</command> exchange on the destination broker <command>localhost:10003</command> if they match any binding on the destination broker&#39;s <command>fed.topic</command> exchange:
+ </para>
+
+<screen>
+$ qpid-route dynamic add localhost:10003 localhost:10004 fed.topic
+</screen>
+ <para>
+ Internally, this creates a private autodelete queue on the source broker, and binds that queue to the <command>fed.topic</command> exchange on the source broker, using each binding associated with the <command>fed.topic</command> exchange on the destination broker.
+ </para>
+ <para>
+ In many applications, messages published to the destination exchange should also be routed to the source exchange. This is accomplished by creating a second dynamic exchange route, reversing the roles of the two exchanges:
+ </para>
+
+<screen>
+$ qpid-route dynamic add localhost:10004 localhost:10003 fed.topic
+</screen>
+ <para>
+ If the <command>-d</command> option is specified, the exchange route is persistent, and will be restored if one or both of the brokers is restarted:
+ </para>
+
+<screen>
+$ qpid-route -d dynamic add localhost:10004 localhost:10003 fed.topic
+</screen>
+ <para>
+ When an exchange route is durable, the private queue used to store messages for the route on the source exchange is also durable. If the connection between the brokers is lost, messages for the destination exchange continue to accumulate until it can be restored.
+ </para>
+ <para>
+ The <command>del</command> command takes the same arguments as the <command>add</command> command. The following command deletes the first exchange route described above:
+ </para>
+
+<screen>
+$ qpid-route dynamic del localhost:10004 localhost:10003 fed.topic
+</screen>
+ <para>
+ Internally, this deletes the bindings on the source exchange for the the private queues associated with the message route.
+ </para>
+
+ </section>
+
+ <section id="sect-Messaging_User_Guide-The_qpid_route_Utility-Viewing_Routes">
+ <title>Viewing Routes</title>
+ <para>
+ The <command>route list</command> command shows the routes associated with an individual broker. For instance, suppose we have created the following two routes:
+ </para>
+
+<screen>
+$ qpid-route dynamic add localhost:10003 localhost:10004 fed.topic
+$ qpid-route dynamic add localhost:10004 localhost:10003 fed.topic
+</screen>
+ <para>
+ We can now use <command>route list</command> to show all routes for the broker <command>localhost:10003</command>:
+ </para>
+
+<screen>
+$ qpid-route route list localhost:10003
+localhost:10003 localhost:10004 fed.topic &#60;dynamic&#62;
+</screen>
+ <para>
+ Note that this shows only one of the two routes we created, the route for which <command>localhost:10003</command> is a destination. If we want to see the route for which <command>localhost:10004</command> is a destination, we need to do another route list:
+ </para>
+
+<screen>
+$ qpid-route route list localhost:10004
+localhost:10004 localhost:10003 fed.topic &#60;dynamic&#62;
+</screen>
+ <para>
+ The <command>route map</command> command shows all routes associated with a broker, and recursively displays all routes for brokers involved in federation relationships with the given broker. For instance, here is the output for the two brokers configured above:
+ </para>
+
+<screen>
+$ qpid-route route map localhost:10003
+
+Finding Linked Brokers:
+ localhost:10003... Ok
+ localhost:10004... Ok
+
+Dynamic Routes:
+
+ Exchange fed.topic:
+ localhost:10004 &#60;=&#62; localhost:10003
+
+Static Routes:
+ none found
+</screen>
+ <para>
+ Note that the two dynamic exchange links are displayed as though they were one bidirectional link. The <command>route map</command> command is particularly helpful for larger, more complex networks. Let&#39;s configure a somewhat more complex network with 16 dynamic exchange routes:
+ </para>
+
+<screen>
+qpid-route dynamic add localhost:10001 localhost:10002 fed.topic
+qpid-route dynamic add localhost:10002 localhost:10001 fed.topic
+
+qpid-route dynamic add localhost:10003 localhost:10002 fed.topic
+qpid-route dynamic add localhost:10002 localhost:10003 fed.topic
+
+qpid-route dynamic add localhost:10004 localhost:10002 fed.topic
+qpid-route dynamic add localhost:10002 localhost:10004 fed.topic
+
+qpid-route dynamic add localhost:10002 localhost:10005 fed.topic
+qpid-route dynamic add localhost:10005 localhost:10002 fed.topic
+
+qpid-route dynamic add localhost:10005 localhost:10006 fed.topic
+qpid-route dynamic add localhost:10006 localhost:10005 fed.topic
+
+qpid-route dynamic add localhost:10006 localhost:10007 fed.topic
+qpid-route dynamic add localhost:10007 localhost:10006 fed.topic
+
+qpid-route dynamic add localhost:10006 localhost:10008 fed.topic
+qpid-route dynamic add localhost:10008 localhost:10006 fed.topic
+</screen>
+ <para>
+ Now we can use <command>route map</command> starting with any one broker, and see the entire network:
+ </para>
+
+<screen>
+$ ./qpid-route route map localhost:10001
+
+Finding Linked Brokers:
+ localhost:10001... Ok
+ localhost:10002... Ok
+ localhost:10003... Ok
+ localhost:10004... Ok
+ localhost:10005... Ok
+ localhost:10006... Ok
+ localhost:10007... Ok
+ localhost:10008... Ok
+
+Dynamic Routes:
+
+ Exchange fed.topic:
+ localhost:10002 &#60;=&#62; localhost:10001
+ localhost:10003 &#60;=&#62; localhost:10002
+ localhost:10004 &#60;=&#62; localhost:10002
+ localhost:10005 &#60;=&#62; localhost:10002
+ localhost:10006 &#60;=&#62; localhost:10005
+ localhost:10007 &#60;=&#62; localhost:10006
+ localhost:10008 &#60;=&#62; localhost:10006
+
+Static Routes:
+ none found
+</screen>
+
+ </section>
+
+ <section id="sect-Messaging_User_Guide-The_qpid_route_Utility-Resilient_Connections">
+ <title>Resilient Connections</title>
+ <para>
+ When a broker route is created, or when a durable broker route is restored after broker restart, a connection is created between the source broker and the destination broker. The connections used between brokers are called <firstterm>resilient connections</firstterm>; if the connection fails due to a communication error, it attempts to reconnect. The retry interval begins at 2 seconds and, as more attempts are made, grows to 64 seconds, and continues to retry every 64 seconds thereafter. If the connection fails due to an authentication problem, it will not continue to retry.
+ </para>
+ <para>
+ The command <command>list connections</command> can be used to show the resilient connections for a broker:
+ </para>
+
+<screen>
+$ qpid-route list connections localhost:10001
+
+Host Port Transport Durable State Last Error
+=============================================================================
+localhost 10002 tcp N Operational
+localhost 10003 tcp N Operational
+localhost 10009 tcp N Waiting Connection refused
+</screen>
+ <para>
+ In the above output, <command>Last Error</command> contains the string representation of the last connection error received for the connection. <command>State</command> represents the state of the connection, and may be one of the following values:
+ </para>
+ <table id="tabl-Messaging_User_Guide-Resilient_Connections-State_values_in_qpid_route_list_connections">
+ <title>State values in <command>$ qpid-route list connections</command></title>
+ <tgroup align="left" cols="2" colsep="1" rowsep="1">
+ <tbody>
+ <row>
+ <entry>
+ Waiting
+ </entry>
+ <entry>
+ Waiting before attempting to reconnect.
+ </entry>
+
+ </row>
+ <row>
+ <entry>
+ Connecting
+ </entry>
+ <entry>
+ Attempting to establish the connection.
+ </entry>
+
+ </row>
+ <row>
+ <entry>
+ Operational
+ </entry>
+ <entry>
+ The connection has been established and can be used.
+ </entry>
+
+ </row>
+ <row>
+ <entry>
+ Failed
+ </entry>
+ <entry>
+ The connection failed and will not retry (usually because authentication failed).
+ </entry>
+
+ </row>
+ <row>
+ <entry>
+ Closed
+ </entry>
+ <entry>
+ The connection has been closed and will soon be deleted.
+ </entry>
+
+ </row>
+ <row>
+ <entry>
+ Passive
+ </entry>
+ <entry>
+ If a cluster is federated to another cluster, only one of the nodes has an actual connection to remote node. Other nodes in the cluster have a passive connection.
+ </entry>
+
+ </row>
+
+ </tbody>
+
+ </tgroup>
+
+ </table>
+
+ </section>
+
+
+ </section>
+
+
+</section>
+
diff --git a/qpid/doc/book/src/Using-Qpid-with-other-JNDI-Providers.xml b/qpid/doc/book/src/Using-Qpid-with-other-JNDI-Providers.xml
new file mode 100644
index 0000000000..2bd7d761ef
--- /dev/null
+++ b/qpid/doc/book/src/Using-Qpid-with-other-JNDI-Providers.xml
@@ -0,0 +1,215 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+
+ 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.
+
+-->
+
+<chapter>
+
+ <title>
+ Using Qpid with other JNDI Providers
+ </title>
+
+ <section role="h2" id="UsingQpidwithotherJNDIProviders-HowtouseaJNDIProvider">
+
+ <title> How to use a JNDI Provider </title>
+
+ <para>
+ Qpid will work with any JNDI provider capable of storing Java
+ objects. We have a task to add our own initial context factory,
+ but until that's available ....
+ </para>
+
+ <para>
+ First you must select a JNDI provider to use. If you aren't
+ already using an application server (i.e. Tomcat ?) which
+ provides JNDI support you could consider using either:
+ </para>
+
+ <itemizedlist>
+ <listitem><para>Apache's <xref linkend="qpid_index"/>
+ which provides an LDAP JNDI implementation
+ </para></listitem>
+ </itemizedlist>
+
+ <itemizedlist>
+ <listitem>
+ <para>OR the SUN JNDI SPI for the FileSystem which can be
+ downloaded from <xref linkend="qpid_index"/>
+ </para>
+ <itemizedlist>
+ <listitem><para>Click : Download JNDI 1.2.1 &amp; More button
+ </para></listitem>
+ <listitem><para>Download: File System Service Provider, 1.2 Beta 3
+ </para></listitem>
+ <listitem><para>and then add the two jars in the lib dir to your class path.
+ </para></listitem>
+ </itemizedlist>
+ </listitem>
+ </itemizedlist>
+
+
+ <para>
+ There are two steps to using JNDI objects.
+ </para>
+
+ <itemizedlist>
+ <listitem><para>Bind : Which stores a reference to a JMS
+ Object in the provider.</para></listitem>
+ <listitem><para>Lookup : Which tries to retrieve the
+ reference and create the JMS Object. </para></listitem>
+ </itemizedlist>
+
+ <para>
+ There are two objects that would normally be stored in JNDI.
+ </para>
+
+ <itemizedlist>
+ <listitem><para>A ConnectionFactory
+ </para></listitem>
+ <listitem><para>A Destination (Queue or Topic)
+ </para></listitem>
+ </itemizedlist>
+
+
+ <section role="h3" id="UsingQpidwithotherJNDIProviders-Binding">
+ <title>
+ Binding
+ </title>
+
+ <para>
+ Then you need to setup the values that the JNDI provider will
+ used to bind your references, something like this:
+ </para>
+
+ <example>
+ <title>Setup JNDI</title>
+
+
+ <programlisting>
+Hashtable env = new Hashtable(11);
+ env.put(Context.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.fscontext.RefFSContextFactory");
+ env.put(Context.PROVIDER_URL,LOCAL_FILE_PATH_FOR_STORING_BINDS_PATH_MUST_EXIST);
+</programlisting>
+</example>
+
+ <para>
+ These values are then used to create a context to bind your
+ references.
+ </para>
+
+<example>
+ <title>Perform Binding of ConnectionFactory</title>
+
+
+ <programlisting>
+try
+{
+ Context ctx = new InitialContext(env);
+
+ // Create the object to be bound in this case a ConnectionFactory
+ ConnectionFactory factory = null;
+
+ try
+ {
+ factory = new AMQConnectionFactory(CONNECTION_URL);
+ try
+ {
+ ctx.bind(binding, factory);
+ }
+ catch (NamingException e)
+ {
+ //Handle problems with binding. Such as the binding already exists.
+ }
+ }
+ catch (URLSyntaxException amqe)
+ {
+ //Handle any exception with creating ConnnectionFactory
+ }
+}
+catch (NamingException e)
+{
+ //Handle problem creating the Context.
+}
+</programlisting>
+</example>
+
+ <para>
+ To bind a queue instead simply create a AMQQueue object and use
+ that in the binding call.
+ </para>
+
+<example>
+<title> Bind a AMQQueue</title>
+ <programlisting>
+AMQQueue queue = new AMQQueue(QUEUE_URL);
+ctx.bind(binding, queue);
+</programlisting>
+</example>
+ </section>
+
+ <section role="h3" id="UsingQpidwithotherJNDIProviders-Lookup">
+ <title>
+ Lookup
+ </title>
+ <para>
+ You can then get a queue connection factory from the JNDI
+ context.
+ </para>
+
+
+<example>
+<title> Perform Binding of ConnectionFactory</title>
+
+
+ <programlisting>
+ConnectionFactory factory;
+try
+{
+ factory= (ConnectionFactory)ctx.lookup(binding);
+}
+catch (NamingException e)
+{
+ //Handle problems with lookup. Such as binding does not exist.
+}
+</programlisting>
+</example>
+
+ <para>
+ Note that you need not cast the bound object back to an
+ AMQConnectionFactory so all your current JMS apps that
+ use JNDI can start using Qpid straight away.
+ </para>
+
+ <!--h2-->
+ </section>
+
+ <section role="h2" id="UsingQpidwithotherJNDIProviders-HowtocreateaTopicConnectionFactoryandQueueConnectionFactory"><title>
+ How to create a TopicConnectionFactory and
+ QueueConnectionFactory
+ </title>
+ <para>
+ AMQConnectionFactory implements TopicConnectionFactory and
+ QueueConnectionFactory as well as the ConnectionFactory.
+ </para>
+<!--h3-->
+ </section>
+<!--h2-->
+ </section>
+</chapter>
diff --git a/qpid/doc/book/src/WCF.xml b/qpid/doc/book/src/WCF.xml
new file mode 100644
index 0000000000..aaf54463db
--- /dev/null
+++ b/qpid/doc/book/src/WCF.xml
@@ -0,0 +1,137 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+
+ 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.
+
+-->
+
+<section>
+ <title>
+ WCF
+ </title>
+ <section role="h1" id="WCF-Introduction">
+ <title>
+ Introduction
+ </title>
+
+ <para>
+ WCF (<emphasis>Windows Communication Foundation)</emphasis> unifies the .Net
+ communication capabilities into a single, common, general Web
+ service oriented framework. A good WCF tutorial can be found
+ <ulink url="http://www.netfxharmonics.com/2008/11/Understanding-WCF-Services-in-Silverlight-2#WCFSilverlightIntroduction">here</ulink>.
+ </para>
+ <para>
+ WCF separates how service logic is written from how services
+ communicate with clients. Bindings are used to specify the
+ transport, encoding, and protocol details required for clients
+ and services to communicate with each other. Qpid provide a WCF
+ binding: org.apache.qpid.wcf.model.QpidBinding. WCF Services that
+ use the Qpid binding communicate through queues that are
+ dynamically created on a Qpid broker.
+ </para>
+ <!--h1-->
+ </section>
+ <section role="h1" id="WCF-HowtouseQpidbinding">
+ <title>
+ How to use Qpid binding
+ </title>
+
+ <para>
+ WCF services are implemented using:
+ </para>
+ <itemizedlist>
+ <listitem>
+ <para>A service contract with one or more operation contracts.
+ </para>
+ </listitem>
+ <listitem>
+ <para>A service implementation for those contracts.
+ </para>
+ </listitem>
+ <listitem>
+ <para>A configuration file to provide that implementation with an
+ endpoint and a binding for that specific contract.
+ </para>
+ </listitem>
+ </itemizedlist>
+ <para>
+ The following configuration file can be used to configure a Hello
+ Service:
+ </para>
+ <programlisting>
+&lt;configuration&gt;
+ &lt;system.serviceModel&gt;
+ &lt;services&gt;
+ &lt;!-- the service class --&gt;
+ &lt;service name="org.apache.qpid.wcf.demo.HelloService"&gt;
+ &lt;host&gt;
+ &lt;baseAddresses&gt;
+ &lt;!-- Use SOAP over AMQP --&gt;
+ &lt;add baseAddress="soap.amqp:///" /&gt;
+ &lt;/baseAddresses&gt;
+ &lt;/host&gt;
+
+ &lt;endpoint
+ address="Hello"
+ &lt;!-- We use a Qpid Binding, see below def --&gt;
+ binding="customBinding"
+ bindingConfiguration="QpidBinding"
+ &lt;!-- The service contract --&gt;
+ contract="org.apache.qpid.wcf.demo.IHelloContract"/&gt;
+ &lt;/service&gt;
+ &lt;/services&gt;
+
+ &lt;bindings&gt;
+ &lt;customBinding&gt;
+ &lt;!-- cf def of the qpid binding --&gt;
+ &lt;binding name="QpidBinding"&gt;
+ &lt;textMessageEncoding /&gt;
+ &lt;!-- specify the host and port number of the broker --&gt;
+ &lt;QpidTransport
+ host="192.168.1.14"
+ port="5673" /&gt;
+ &lt;/binding&gt;
+ &lt;/customBinding&gt;
+ &lt;/bindings&gt;
+
+ &lt;extensions&gt;
+ &lt;bindingElementExtensions&gt;
+ &lt;!-- use Qpid binding element: org.apache.qpid.wcf.model.QpidTransportElement --&gt;
+ &lt;add
+ name="QpidTransport"
+ type="org.apache.qpid.wcf.model.QpidTransportElement, qpidWCFModel"/&gt;
+ &lt;/bindingElementExtensions&gt;
+ &lt;/extensions&gt;
+
+ &lt;/system.serviceModel&gt;
+&lt;/configuration&gt;
+ </programlisting>
+ <para>
+ Endpoints and bindings can also be set within the service code:
+ </para>
+ <programlisting>
+/* set HostName, portNumber and MyService accordingly */
+Binding binding = new QpidBinding("HostName", portNumber);
+ServiceHost service = new ServiceHost(typeof(MyService), new Uri("soap.amqp:///"));
+service.AddServiceEndpoint(typeof(IBooking), binding, "MyService");
+service.Open();
+....
+ </programlisting>
+ <!--h1-->
+ </section>
+</section>
diff --git a/qpid/doc/book/src/amqp-advanced-message-queueing-protocol.html b/qpid/doc/book/src/amqp-advanced-message-queueing-protocol.html
new file mode 100644
index 0000000000..9d46429d03
--- /dev/null
+++ b/qpid/doc/book/src/amqp-advanced-message-queueing-protocol.html
@@ -0,0 +1,237 @@
+<!--
+
+ 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.
+
+-->
+
+
+<!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="resources/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 - AMQP (Advanced Message Queueing Protocol)</TITLE>
+ <META http-equiv="Content-Type" content="text/html;charset=UTF-8"></HEAD>
+ <BODY onload="init()">
+ <TABLE border="0" cellpadding="2" cellspacing="0" width="100%">
+ <TR class="topBar">
+ <TD align="left" valign="middle" class="topBarDiv" align="left" nowrap="">
+ &nbsp;<A href="index.html" title="Apache Qpid">Apache Qpid</A>&nbsp;&gt;&nbsp;<A href="index.html" title="Index">Index</A>&nbsp;&gt;&nbsp;<A href="" title="AMQP (Advanced Message Queueing Protocol)">AMQP (Advanced Message Queueing Protocol)</A>
+ </TD>
+ <TD align="right" valign="middle" nowrap="">
+ <FORM name="search" action="http://www.google.com/search" method="get">
+ <INPUT type="hidden" name="ie" value="UTF-8">
+ <INPUT type="hidden" name="oe" value="UTF-8">
+ <INPUT type="hidden" name="domains" value="">
+ <INPUT type="hidden" name="sitesearch" value="">
+ <INPUT type="text" name="q" maxlength="255" value="">
+ <INPUT type="submit" name="btnG" value="Google Search">
+ </FORM>
+ </TD>
+ </TR>
+ </TABLE>
+
+ <DIV id="PageContent">
+ <DIV class="pageheader" style="padding: 6px 0px 0px 0px;">
+<DIV>
+<TABLE border="0" width="90%">
+<TR>
+<TD align="left">
+<A href="http://qpid.apache.org/">
+<IMG src="http://qpid.apache.org/images/qpid-logo.png" height="69" width="225" border="0"></A>
+</TD>
+<TD>
+</TD>
+<TD align="right"> <A href="http://www.apache.org/">
+ <IMG src="http://qpid.apache.org/images/asf-logo.png" height="69" width="225" border="0"></A></TD>
+</TR>
+</TABLE>
+</DIV>
+
+ </DIV>
+
+<!--
+
+
+ <div class="pagesubheading" style="margin: 0px 10px 0px 10px;">
+ Added by <a href="/confluence/display/~jonathan.robie@redhat.com">Jonathan Robie</a>, last edited by <a href="/confluence/display/~jonathan.robie@redhat.com">Jonathan Robie</a> on Feb 18, 2009
+ &nbsp;(<a class="noprint" href="/confluence/pages/diffpages.action?pageId=110693&originalId=110695">view change</a>)
+
+ </div>
+-->
+
+ <DIV class="left">
+
+
+
+
+ <DIV class="panel" style="background-color: E0E0FF;border-color: #202080;border-style: solid;border-width: 1px;"><DIV class="panelContent" style="background-color: E0E0FF;">
+<H3><A name="Navigation-ApacheQpid"></A>Apache Qpid</H3>
+<P> <A href="index.html" title="Index">Home</A><BR>
+ <A href="download.html" title="Download">Download</A><BR>
+ <A href="getting-started.html" title="Getting Started">Getting Started</A> <BR>
+ <A href="documentation.html" title="Documentation">Documentation</A><BR>
+ <A href="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="faq.html" title="FAQ">FAQ/How to</A></P>
+
+<H3><A name="Navigation-Resources"></A>Resources</H3>
+<P> <A href="getting-involved.html" title="Getting Involved">Getting Involved</A><BR>
+ <A href="qpid-integrations.html" title="Qpid Integrations">Qpid Integrated with..</A><BR>
+ <A href="source-repository.html" title="Source Repository">Source Repository</A><BR>
+ <A href="building.html" title="Building">Building Qpid</A><BR>
+ <A href="developer-pages.html" title="Developer Pages">Developer Pages</A><BR>
+ <A href="qpid-management-framework.html" title="Qpid Management Framework">QMF</A></P>
+
+<H3><A name="Navigation-AboutQpid"></A>About Qpid</H3>
+<P> <A href="people.html" title="People">People</A><BR>
+ <A href="license.html" title="License">License</A><BR>
+ <A href="project-status.html" title="Project Status">Project Status</A><BR>
+ <A href="acknowledgments.html" title="Acknowledgments">Acknowledgments</A></P>
+
+<H3><A name="Navigation-AboutAMQP"></A>About AMQP</H3>
+<P> <A href="" title="AMQP (Advanced Message Queueing Protocol)">What is AMQP ?</A><BR>
+ <A href="" title="AMQP (Advanced Message Queueing Protocol)">AMQP Specification Download</A></P>
+
+<P><IMG src="navigation.data/AMQP_logo_71px-small.jpg" align="absmiddle" border="0"></P>
+</DIV></DIV>
+ </DIV>
+
+ <DIV class="pagecontent">
+ <DIV class="wiki-content">
+ <H2><A name="AMQP%28AdvancedMessageQueueingProtocol%29-WhatisAMQP%3F"></A>What is AMQP?</H2>
+
+<P>AMQP <A href="http://www.amqp.org/" rel="nofollow">Advanced Message Queuing Protocol</A> is an open standard designed to support reliable, high-performance messaging over the Internet. AMQP can be used for any distributed or business application, and supports common messaging paradigms like point-to-point, fanout, publish-subscribe, and request-response.</P>
+
+<P>Apache Qpid implements AMQP, including transaction management, queuing, clustering, federation, security, management and multi-platform support.</P>
+
+
+<P>Apache Qpid implements the latest AMQP specification, providing transaction management, queuing, distribution, security, management, clustering, federation and heterogeneous multi-platform support and a lot more. </P>
+
+<P>Apache Qpid is highly optimized, and <A href="amqp-compatibility.html" title="AMQP compatibility">aims to be 100% AMQP Compliant</A>.</P>
+
+<H2><A name="AMQP%28AdvancedMessageQueueingProtocol%29-DownloadtheAMQPSpecifications"></A>Download the AMQP Specifications</H2>
+
+<H3><A name="AMQP%28AdvancedMessageQueueingProtocol%29-AMQPversion010"></A>AMQP version 0-10</H3>
+
+
+<UL>
+ <LI><A href="https://jira.amqp.org/confluence/download/attachments/720900/amqp.0-10.pdf?version=1" rel="nofollow">AMQP 0-10 Specification (PDF) </A></LI>
+ <LI><A href="https://jira.amqp.org/confluence/download/attachments/720900/amqp.0-10.xml?version=1" rel="nofollow">AMQP 0-10 Protocol Definition XML </A></LI>
+ <LI><A href="https://jira.amqp.org/confluence/download/attachments/720900/amqp.0-10.dfd?version=1" rel="nofollow">AMQP 0-10 Protocol Definition DTD </A></LI>
+</UL>
+
+
+<H3><A name="AMQP%28AdvancedMessageQueueingProtocol%29-AMQPversion091"></A>AMQP version 0-9-1</H3>
+
+<UL>
+ <LI><A href="https://jira.amqp.org/confluence/download/attachments/720900/amqp0-9-1.pdf?version=1" rel="nofollow">AMQP 0-9-1 Specification (PDF) </A></LI>
+ <LI><A href="https://jira.amqp.org/confluence/download/attachments/720900/amqp0-9-1.xml?version=1" rel="nofollow">AMQP 0-9-1 Protocol Documentation (PDF) </A></LI>
+ <LI><A href="https://jira.amqp.org/confluence/download/attachments/720900/amqp0-9-1.dtd?version=1" rel="nofollow">AMQP 0-9-1 Protocol Definitions (XML) </A></LI>
+</UL>
+
+
+<H3><A name="AMQP%28AdvancedMessageQueueingProtocol%29-AMQPversion09"></A>AMQP version 0-9</H3>
+
+<UL>
+ <LI><A href="https://jira.amqp.org/confluence/download/attachments/720900/amqp0-9.pdf?version=1" rel="nofollow">AMQP 0-9 Specification (PDF) </A></LI>
+ <LI><A href="https://jira.amqp.org/confluence/download/attachments/720900/amqp0-9.xml?version=1" rel="nofollow">AMQP 0-9 Protocol Documentation (PDF) </A></LI>
+ <LI><A href="https://jira.amqp.org/confluence/download/attachments/720900/amqp0-9.dtd?version=1" rel="nofollow">AMQP 0-9 Protocol Definitions (XML) </A></LI>
+</UL>
+
+
+<H3><A name="AMQP%28AdvancedMessageQueueingProtocol%29-AMQPversion08"></A>AMQP version 0-8</H3>
+
+<UL>
+ <LI><A href="https://jira.amqp.org/confluence/download/attachments/720900/amqp0-8.pdf?version=1" rel="nofollow">AMQP 0-8 Specification (PDF) </A></LI>
+ <LI><A href="https://jira.amqp.org/confluence/download/attachments/720900/amqp0-8.dtd?version=1" rel="nofollow">AMQP 0-8 Protocol Documentation (PDF) </A></LI>
+ <LI><A href="https://jira.amqp.org/confluence/download/attachments/720900/amqp0-8.xml?version=1" rel="nofollow">AMQP 0-8 Protocol Definitions (XML) </A></LI>
+</UL>
+
+ </DIV>
+
+<!--
+ -->
+
+ </DIV>
+
+ <DIV class="footer">
+ Apache Qpid, Enterprise AMQP Messaging
+ &nbsp;
+ &copy; 2004-2008 The Apache Software Foundation.
+ &nbsp;
+ (<A href="http://cwiki.apache.org/confluence/pages/editpage.action?pageId=110693">edit this page</A>)
+ </DIV>
+ </BODY>
+</HTML>
diff --git a/qpid/doc/book/src/images/jmx_console/3113098.png b/qpid/doc/book/src/images/jmx_console/3113098.png
new file mode 100644
index 0000000000..7de85030c6
--- /dev/null
+++ b/qpid/doc/book/src/images/jmx_console/3113098.png
Binary files differ
diff --git a/qpid/doc/book/src/images/jmx_console/3113099.png b/qpid/doc/book/src/images/jmx_console/3113099.png
new file mode 100644
index 0000000000..fb6fc65d73
--- /dev/null
+++ b/qpid/doc/book/src/images/jmx_console/3113099.png
Binary files differ
diff --git a/qpid/doc/book/src/images/jmx_console/3113100.png b/qpid/doc/book/src/images/jmx_console/3113100.png
new file mode 100644
index 0000000000..a7d727b854
--- /dev/null
+++ b/qpid/doc/book/src/images/jmx_console/3113100.png
Binary files differ
diff --git a/qpid/doc/book/src/images/jmx_console/3113101.png b/qpid/doc/book/src/images/jmx_console/3113101.png
new file mode 100644
index 0000000000..30731277c2
--- /dev/null
+++ b/qpid/doc/book/src/images/jmx_console/3113101.png
Binary files differ
diff --git a/qpid/doc/book/src/images/jmx_console/3113102.png b/qpid/doc/book/src/images/jmx_console/3113102.png
new file mode 100644
index 0000000000..f150a21b10
--- /dev/null
+++ b/qpid/doc/book/src/images/jmx_console/3113102.png
Binary files differ
diff --git a/qpid/doc/book/src/images/jmx_console/3113103.png b/qpid/doc/book/src/images/jmx_console/3113103.png
new file mode 100644
index 0000000000..a91efb4306
--- /dev/null
+++ b/qpid/doc/book/src/images/jmx_console/3113103.png
Binary files differ
diff --git a/qpid/doc/book/src/images/jmx_console/3113104.png b/qpid/doc/book/src/images/jmx_console/3113104.png
new file mode 100644
index 0000000000..c5ef12d8b1
--- /dev/null
+++ b/qpid/doc/book/src/images/jmx_console/3113104.png
Binary files differ
diff --git a/qpid/doc/book/src/images/jmx_console/3113105.png b/qpid/doc/book/src/images/jmx_console/3113105.png
new file mode 100644
index 0000000000..b155f9d9a1
--- /dev/null
+++ b/qpid/doc/book/src/images/jmx_console/3113105.png
Binary files differ
diff --git a/qpid/doc/book/src/images/jmx_console/3113106.png b/qpid/doc/book/src/images/jmx_console/3113106.png
new file mode 100644
index 0000000000..22bcdd084e
--- /dev/null
+++ b/qpid/doc/book/src/images/jmx_console/3113106.png
Binary files differ
diff --git a/qpid/doc/book/src/images/jmx_console/3113107.png b/qpid/doc/book/src/images/jmx_console/3113107.png
new file mode 100644
index 0000000000..cf5dd97e89
--- /dev/null
+++ b/qpid/doc/book/src/images/jmx_console/3113107.png
Binary files differ
diff --git a/qpid/doc/book/src/images/jmx_console/3113108.png b/qpid/doc/book/src/images/jmx_console/3113108.png
new file mode 100644
index 0000000000..c0e5eafde2
--- /dev/null
+++ b/qpid/doc/book/src/images/jmx_console/3113108.png
Binary files differ
diff --git a/qpid/doc/book/src/images/jmx_console/3113109.png b/qpid/doc/book/src/images/jmx_console/3113109.png
new file mode 100644
index 0000000000..139d81d849
--- /dev/null
+++ b/qpid/doc/book/src/images/jmx_console/3113109.png
Binary files differ
diff --git a/qpid/doc/book/src/images/jmx_console/3113110.png b/qpid/doc/book/src/images/jmx_console/3113110.png
new file mode 100644
index 0000000000..2207f15cd7
--- /dev/null
+++ b/qpid/doc/book/src/images/jmx_console/3113110.png
Binary files differ
diff --git a/qpid/doc/book/src/images/jmx_console/3113111.png b/qpid/doc/book/src/images/jmx_console/3113111.png
new file mode 100644
index 0000000000..5737f41caf
--- /dev/null
+++ b/qpid/doc/book/src/images/jmx_console/3113111.png
Binary files differ
diff --git a/qpid/doc/book/src/images/jmx_console/3113112.png b/qpid/doc/book/src/images/jmx_console/3113112.png
new file mode 100644
index 0000000000..d9ee094ab4
--- /dev/null
+++ b/qpid/doc/book/src/images/jmx_console/3113112.png
Binary files differ
diff --git a/qpid/doc/book/src/images/jmx_console/3113113.png b/qpid/doc/book/src/images/jmx_console/3113113.png
new file mode 100644
index 0000000000..e80812f83c
--- /dev/null
+++ b/qpid/doc/book/src/images/jmx_console/3113113.png
Binary files differ
diff --git a/qpid/doc/book/src/images/jmx_console/3113114.png b/qpid/doc/book/src/images/jmx_console/3113114.png
new file mode 100644
index 0000000000..b237181150
--- /dev/null
+++ b/qpid/doc/book/src/images/jmx_console/3113114.png
Binary files differ
diff --git a/qpid/doc/book/src/images/jmx_console/3113115.png b/qpid/doc/book/src/images/jmx_console/3113115.png
new file mode 100644
index 0000000000..84ad42b567
--- /dev/null
+++ b/qpid/doc/book/src/images/jmx_console/3113115.png
Binary files differ
diff --git a/qpid/doc/book/src/images/jmx_console/3113116.png b/qpid/doc/book/src/images/jmx_console/3113116.png
new file mode 100644
index 0000000000..18b979792f
--- /dev/null
+++ b/qpid/doc/book/src/images/jmx_console/3113116.png
Binary files differ
diff --git a/qpid/doc/book/src/images/jmx_console/3113117.png b/qpid/doc/book/src/images/jmx_console/3113117.png
new file mode 100644
index 0000000000..3b33ef67ac
--- /dev/null
+++ b/qpid/doc/book/src/images/jmx_console/3113117.png
Binary files differ
diff --git a/qpid/doc/book/src/images/jmx_console/3113118.png b/qpid/doc/book/src/images/jmx_console/3113118.png
new file mode 100644
index 0000000000..60451f88cf
--- /dev/null
+++ b/qpid/doc/book/src/images/jmx_console/3113118.png
Binary files differ
diff --git a/qpid/doc/book/src/images/jmx_console/3113119.png b/qpid/doc/book/src/images/jmx_console/3113119.png
new file mode 100644
index 0000000000..16ded074bd
--- /dev/null
+++ b/qpid/doc/book/src/images/jmx_console/3113119.png
Binary files differ
diff --git a/qpid/doc/book/src/images/qpid-logo.png b/qpid/doc/book/src/images/qpid-logo.png
new file mode 100644
index 0000000000..5f4ccc3081
--- /dev/null
+++ b/qpid/doc/book/src/images/qpid-logo.png
Binary files differ
diff --git a/qpid/doc/book/src/java/broker/configuration/Topic-Configuration.xml b/qpid/doc/book/src/java/broker/configuration/Topic-Configuration.xml
new file mode 100644
index 0000000000..1f73bbd7a4
--- /dev/null
+++ b/qpid/doc/book/src/java/broker/configuration/Topic-Configuration.xml
@@ -0,0 +1,107 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+
+ 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.
+
+-->
+
+<section>
+ <title>Topic Configuration on Java Broker</title>
+
+ <para>New in 0.8 is the ability to define configuration for topics. Currently this is limited to
+ configuration for slow consumer detection. This configuration is based on the work
+ designed on the <ulink
+ url="http://cwiki.apache.org/confluence/display/qpid/Topic+Configuration+Design">design
+ wiki</ulink>.</para>
+
+ <section id="Topic Identification">
+ <title>Topic Identification</title>
+ <para>A configuration section has two entries that can be used to identify how the
+ configuration will be applied: 'name' and 'subscriptionName'.
+
+ <programlisting>
+ &lt;topic&gt;
+ &lt;name&gt;stocks.us&lt;/name&gt;
+ </programlisting>
+ <programlisting>
+ &lt;topic&gt;
+ &lt;subscriptionName&gt;clientid:mysubscription&lt;/subscriptionName&gt;
+ </programlisting>
+
+ It is also possible to combine these two identifiers to specify a unique subscription to
+ a given topic.
+
+ <programlisting>
+ &lt;topic&gt;
+ &lt;name&gt;stocks.us&lt;/name&gt;
+ &lt;subscriptionName&gt;clientid:mysubscription&lt;/subscriptionName&gt;
+ </programlisting>
+ </para>
+ </section>
+
+ <section>
+ <title>Configuration Items</title>
+ <para> Currently only one element of the designed configuration is processed, that of the
+ slow consumer detection. This is setup as below using the 'slow-consumer-detection'
+ element. There are two required types of tag, first the trigger, which is one of
+ 'depth', 'messageAge' or 'messageCount' and secondly the 'policy'. </para>
+ <programlisting>
+ &lt;slow-consumer-detection&gt;
+ &lt;!-- The maximum depth before which the policy will be applied--&gt;
+ &lt;depth&gt;4235264&lt;/depth&gt;
+
+ &lt;!-- The maximum message age before which the policy will be applied--&gt;
+ &lt;messageAge&gt;600000&lt;/messageAge&gt;
+
+ &lt;!-- The maximum number of message before which the policy will be applied--&gt;
+ &lt;messageCount&gt;50&lt;/messageCount&gt;
+
+ &lt;!-- Policy Selection --&gt;
+ &lt;policy name="TopicDelete"/&gt;
+ &lt;/slow-consumer-detection&gt;
+ </programlisting>
+
+ <para> The trigger is used to determine when the policy should be applied. Currently we have
+ a simple policy 'topicdelete', this will disconnect consumers of topics where their
+ consumption rate falls sufficiently to hit one of the trigger values. </para>
+ </section>
+
+
+ <section id="Limitiations">
+ <title>Limitiations</title>
+ <para> As of 0.8 the topic configuration is limited to straight string matching. This means
+ that given the following two topic configuring sections for 'stocks.us' and 'stocks.*' a
+ subscription for 'stocks.uk' will not match the expected 'stocks.*'. Nor will any
+ additional configuration listed in 'stocks.*' affect any 'stocks.us' subscriptions. </para>
+ <programlisting>
+ &lt;topics&gt;
+ &lt;topic&gt;
+ &lt;name&gt;stocks.us&lt;/name&gt;
+ ...
+ &lt;/topic&gt;
+ &lt;topic&gt;
+ &lt;name&gt;stocks.*&lt;/name&gt;
+ ...
+ &lt;/topic&gt;
+ &lt;/topics&gt;
+ </programlisting>
+ <para> A subscription for 'stocks.us' will only receive configuration settings that are
+ defined in the 'stocks.us' section. </para>
+ </section>
+
+</section>
diff --git a/qpid/doc/book/src/producer-flow-control.xml b/qpid/doc/book/src/producer-flow-control.xml
new file mode 100644
index 0000000000..fd44f51e81
--- /dev/null
+++ b/qpid/doc/book/src/producer-flow-control.xml
@@ -0,0 +1,351 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+
+ 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.
+
+-->
+
+<section id="producer-flow-control">
+ <title>
+ Producer Flow Control
+ </title>
+
+ <section role="h2" id="producerflowcontrol-Overview">
+ <title>
+ Overview
+ </title>
+ <para>
+ As of release 0.10, the C++ broker supports the use of flow control to
+ throttle back message producers that are at risk of overflowing a
+ destination queue.
+ </para>
+
+ <para>
+ Each queue in the C++ broker has two threshold values associated with it:
+ </para>
+
+ <para>
+ Flow Stop Threshold: this is the level of queue resource
+ utilization above which flow control will be enabled. Once this
+ threshold is crossed, the queue is considered in danger of overflow.
+ </para>
+
+ <para>
+ Flow Resume Threshold - this is the level of queue resource utilization
+ below which flow control will be disabled. Once this threshold is
+ crossed, the queue is no longer considered in danger of overflow.
+ </para>
+
+ <para>
+ In the above description, queue resource utilization may be
+ defined as the total count of messages currently enqueued, or the total
+ sum of all message content in bytes.
+ </para>
+
+ <para>
+ The value for a queue's Flow Stop Threshold must be greater than or
+ equal to the value of the queue's Flow Resume Threshold.
+ </para>
+
+ <section role="h3" id="producerflowcontrol-QueueThresholdsExample">
+ <title>
+ Example
+ </title>
+
+ <para>
+ Let's consider a queue with a maximum limit set on the total number of
+ messages that may be enqueued to that queue. Assume this maximum
+ message limit is 1000 messages. Assume also that the user configures a
+ Flow Stop Threshold of 900 messages, and a Flow Resume Threshold of 500
+ messages. Then the following holds:
+ </para>
+
+ <para>
+ The queue's initial flow control state is "OFF".
+ </para>
+
+ <para>
+ While the total number of enqueued messages is less than or equal to
+ 900, the queue's flow control state remains "OFF".
+ </para>
+
+ <para>
+ When the total number of enqueued messages is greater than 900, the
+ queue's flow control state transitions to "ON".
+ </para>
+
+ <para>
+ When the queue's flow control state is "ON", it remains "ON" until the
+ total number of enqueued messages is less than 500. At that point, the queue's
+ flow control state transitions to "OFF".
+ </para>
+
+ <para>
+ A similar example using total enqueued content bytes as the threshold
+ units are permitted.
+ </para>
+ </section>
+
+ <para>
+ Thresholds may be set using both total message counts and total byte
+ counts. In this case, the following rules apply:
+ </para>
+
+ <para>
+ 1) Flow control is "ON" when either stop threshold value is crossed.
+ </para>
+ <para>
+ 2) Flow control remains "ON" until both resume thresholds are satisfied.
+ </para>
+
+ <section role="h3" id="producerflowcontro-MultiThresholdExample">
+ <title>
+ Example
+ </title>
+
+ <para>
+ Let's consider a queue with a maximum size limit of 10K bytes, and 5000
+ messages. A user may assign a Flow Stop Threshold based on a total
+ message count of 4000 messages. They may also assigne a Flow Stop
+ Threshold of 8K bytes. The queue's flow control state transitions to
+ "ON" if either threshold is crossed: (total-msgs greater-than 4000 OR total-bytes
+ greater-than 8K).
+ </para>
+
+ <para>
+ Assume the user has assigned Flow Resume threshold's of 3000 messages and
+ 6K bytes. Then the queue's flow control will remain active until both
+ thresholds are satified: (total-msg less-than 3000 AND total-bytes less-than 6K).
+ </para>
+ </section>
+
+ <para>
+ The Broker enforces flow control by delaying the completion of the
+ Message.Transfer command that causes a message to be delivered to a queue
+ with active flow control. The completion of the Message.Transfer command
+ is held off until flow control state transitions to "OFF" for all queues
+ that are a destination for that command.
+ </para>
+
+ <para>
+ A message producing client is permitted to have a finite number of
+ commands pending completion. When the total number of these outstanding
+ commands reaches the limit, the client must not issue further commands
+ until one or more of the outstanding commands have completed. This
+ window of outstanding commands is considered the sender's "capacity".
+ This allows any given producer to have a "capacity's" worth of messages
+ blocked due to flow control before the sender must stop sending further
+ messages.
+ </para>
+
+ <para>
+ This capacity window must be considered when determining a suitable
+ flow stop threshold for a given queue, as a producer may send its
+ capacity worth of messages _after_ a queue has reached the flow stop
+ threshold. Therefore, a flow stop threshould should be set such that
+ the queue can accomodate more messages without overflowing.
+ </para>
+
+ <para>
+ For example, assume two clients, C1 and C2, are producing messages to
+ one particular destination queue. Assume client C1 has a configured
+ capacity of 50 messages, and client C2's capacity is 15 messages. In
+ this example, assume C1 and C2 are the only clients queuing messages to
+ a given queue. If this queue has a Flow Stop Threshold of 100
+ messages, then, worst-case, the queue may receive up to 165 messages
+ before clients C1 and C2 are blocked from sending further messages.
+ This is due to the fact that the queue will enable flow control on
+ receipt of its 101'st message - preventing the completion of the
+ Message.Transfer command that carried the 101'st message. However, C1
+ and C2 are allowed to have a total of 65 (50 for C1 and 15 for C2)
+ messages pending completion of Message.Transfer before they will stop
+ producing messages. Thus, up to 65 messages may be enqueued beyond the
+ flow stop threshold before the producers will be blocked.
+ </para>
+ </section>
+
+ <section role="h2" id="producerflowcontrol-UserInterface">
+ <title>
+ User Interface
+ </title>
+
+ <para>
+ By default, the C++ broker assigns a queue's flow stop and flow resume
+ thresholds when the queue is created. The C++ broker also allows the
+ user to manually specify the flow control thresholds on a per queue
+ basis.
+ </para>
+
+ <para>
+ However, queues that have been configured with a Limit Policy of type
+ RING or RING-STRICT do NOT have queue flow thresholds enabled by
+ default. The nature of a RING queue defines its behavior when its
+ capacity is reach: replace the oldest message.
+ </para>
+
+ <para>
+ The flow control state of a queue can be determined by the "flowState"
+ boolean in the queue's QMF management object. The queue's management
+ object also contains a counter that increments each time flow control
+ becomes active for the queue.
+ </para>
+
+ <para>
+ The broker applies a threshold ratio to compute a queue's default flow
+ control configuration. These thresholds are expressed as a percentage
+ of a queue's maximum capacity. There is one value for determining the
+ stop threshold, and another for determining the resume threshold. The
+ user may configure these percentages using the following broker
+ configuration options:
+ </para>
+
+ <programlisting>
+ --default-flow-stop-threshold ("Queue capacity level at which flow control is activated.")
+ --default-flow-resume-threshold ("Queue capacity level at which flow control is de-activated.")
+ </programlisting>
+
+ <para>
+ For example:
+ </para>
+
+ <programlisting>
+ qpidd --default-flow-stop-threshold=90 --default-flow-resume-threshold=75
+ </programlisting>
+
+ <para>
+ Sets the default flow stop threshold to 90% of a queue's maximum
+ capacity and the flow resume threshold to 75% of the maximum capacity.
+ If a queue is created with a default-queue-limit of 10000 bytes, then
+ the default flow stop threshold would be 90% of 10000 = 9000 bytes and
+ the flow resume threshold would be 75% of 10000 = 7500. The same
+ computation is performed should a queue be created with a maximum size
+ expressed as a message count instead of a byte count.
+ </para>
+
+ <para>
+ If not overridden by the user, the value of the
+ default-flow-stop-threshold is 80% and the value of the
+ default-flow-resume-threshold is 70%.
+ </para>
+
+ <para>
+ The user may disable default queue flow control broker-wide by
+ specifying the value 0 for both of these configuration options. Note
+ that flow control may still be applied manually on a per-queue basis in
+ this case.
+ </para>
+
+ <para>
+ The user may manually set the flow thresholds when creating a queue.
+ The following options may be provided when adding a queue using the
+ <command>qpid-config</command> command line tool:
+ </para>
+
+ <programlisting>
+ --flow-stop-size=<replaceable>N</replaceable> Sets the queue's flow stop threshold to <replaceable>N</replaceable> total bytes.
+ --flow-resume-size=<replaceable>N</replaceable> Sets the queue's flow resume threshold to <replaceable>N</replaceable> total bytes.
+ --flow-stop-count=<replaceable>N</replaceable> Sets the queue's flow stop threshold to <replaceable>N</replaceable> total messages.
+ --flow-resume-count=<replaceable>N</replaceable> Sets the queue's flow resume threshold to <replaceable>N</replaceable> total messages.
+ </programlisting>
+
+ <para>
+ Flow thresholds may also be specified in the
+ <command>queue.declare</command> method, via the
+ <command>arguments</command> parameter map. The following keys can be
+ provided in the arguments map for setting flow thresholds:
+ </para>
+
+ <table>
+ <title>Queue Declare Method Flow Control Arguments</title>
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Key</entry>
+ <entry>Value</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>qpid.flow_stop_size</entry>
+ <entry>integer - queue's flow stop threshold value in bytes</entry>
+ </row>
+ <row>
+ <entry>qpid.flow_resume_size</entry>
+ <entry>integer - queue's flow resume threshold value in bytes</entry>
+ </row>
+ <row>
+ <entry>qpid.flow_stop_count</entry>
+ <entry>integer - queue's flow stop threshold value as a message count</entry>
+ </row>
+ <row>
+ <entry>qpid.flow_resume_count</entry>
+ <entry>integer - queue's flow resume threshold value as a message count</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ The user may disable flow control on a per queue basis by setting
+ the flow-stop-size and flow-stop-count to zero for the queue.
+ </para>
+
+ <para>
+ The current state of flow control for a given queue can be
+ determined by the "flowStopped" statistic. This statistic is
+ available in the queue's QMF management object. The value of
+ flowStopped is True when the queue's capacity has exceeded the
+ flow stop threshold. The value of flowStopped is False when the
+ queue is no longer blocking due to flow control.
+ </para>
+
+ <para>
+ A queue will also track the number of times flow control has been
+ activated. The "flowStoppedCount" statistic is incremented each time
+ the queue's capacity exceeds a flow stop threshold. This statistic can
+ be used to monitor the activity of flow control for any given queue
+ over time.
+ </para>
+
+ <table>
+ <title>Flow Control Statistics available in Queue's QMF Class</title>
+ <tgroup cols="3">
+ <thead>
+ <row>
+ <entry>Statistic Name</entry>
+ <entry>Type</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>flowStopped</entry>
+ <entry>Boolean</entry>
+ <entry>If true, producers are blocked by flow control.</entry>
+ </row>
+ <row>
+ <entry>flowStoppedCount</entry>
+ <entry>count32</entry>
+ <entry>Number of times flow control was activated for this queue</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </section>
+ <!--h2-->
+ </section>
diff --git a/qpid/doc/book/src/queue-state-replication.xml b/qpid/doc/book/src/queue-state-replication.xml
new file mode 100644
index 0000000000..3ffac805eb
--- /dev/null
+++ b/qpid/doc/book/src/queue-state-replication.xml
@@ -0,0 +1,333 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+
+ 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.
+
+-->
+
+<section id="queue-state-replication">
+ <title>
+ Queue State Replication
+ </title>
+
+ <section role="h2" id="queuestatereplication-AsynchronousReplicationofQueueState">
+ <title>
+ Asynchronous
+ Replication of Queue State
+ </title>
+
+ <section role="h3" id="queuestatereplication-Overview">
+ <title>
+ Overview
+ </title>
+ <para>
+ There is support in qpidd for selective asynchronous replication
+ of queue state. This is achieved by:
+ </para>
+ <para>
+ (a) enabling event generation for the queues in question
+ </para>
+ <para>
+ (b) loading a plugin on the 'source' broker to encode those
+ events as messages on a replication queue (this plugin is
+ called
+ replicating_listener.so)
+ </para>
+ <para>
+ (c) loading a custom exchange plugin on the 'backup' broker (this
+ plugin is called replication_exchange.so)
+ </para>
+ <para>
+ (d) creating an instance of the replication exchange type on the
+ backup broker
+ </para>
+ <para>
+ (e) establishing a federation bridge between the replication
+ queue on the source broker and the replication exchange on the
+ backup broker
+ </para>
+ <para>
+ The bridge established between the source and backup brokers for
+ replication (step (e) above) should have acknowledgements turned
+ on (this may be done through the --ack N option to qpid-route).
+ This ensures that replication events are not lost if the bridge
+ fails.
+ </para>
+ <para>
+ The replication protocol will also eliminate duplicates to ensure
+ reliably replicated state. Note though that only one bridge per
+ replication exchange is supported. If clients try to publish to
+ the replication exchange or if more than a the single required
+ bridge from the replication queue on the source broker is
+ created, replication will be corrupted. (Access control may be
+ used to restrict access and help prevent this).
+ </para>
+ <para>
+ The replicating event listener plugin (step (b) above) has the
+ following options:
+ </para>
+ <programlisting>
+Queue Replication Options:
+ --replication-queue QUEUE Queue on which events for
+ other queues are recorded
+ --replication-listener-name NAME (replicator) name by which to register the
+ replicating event listener
+ --create-replication-queue if set, the replication will
+ be created if it does not
+ exist
+ </programlisting>
+ <para>
+ The name of the queue is required. It can either point to a
+ durable queue whose definition has been previously recorded, or
+ the --create-replication-queue option can be specified in which
+ case the queue will be created a simple non-durable queue if it
+ does not already exist.
+ </para>
+ <!--h3-->
+ </section>
+
+ <section role="h3" id="queuestatereplication-UsewithClustering">
+ <title>
+ Use with
+ Clustering
+ </title>
+ <para>
+ The source and/or backup brokers may also be clustered brokers.
+ In this case the federated bridge will be re-established between
+ replicas should either of the originally connected nodes fail.
+ There are however the following limitations at present:
+ </para>
+ <itemizedlist>
+ <listitem>
+ <para>The backup site does not process membership updates after it
+ establishes the first connection. In order for newly added
+ members on a source cluster to be eligible as failover targets,
+ the bridge must be recreated after those members have been added
+ to the source cluster.
+ </para>
+ </listitem>
+ </itemizedlist>
+ <itemizedlist>
+ <listitem>
+ <para>New members added to a backup cluster will not receive
+ information about currently established bridges. Therefore in
+ order to allow the bridge to be re-established from these members
+ in the event of failure of older nodes, the bridge must be
+ recreated after the new members have joined.
+ </para>
+ </listitem>
+ </itemizedlist>
+ <itemizedlist>
+ <listitem>
+ <para>Only a single URL can be passed to create the initial link
+ from backup site to the primary site. this means that at the time
+ of creating the initial connection the initial node in the
+ primary site to which the connection is made needs to be running.
+ Once connected the backup site will receive a membership update
+ of all the nodes in the primary site, and if the initial
+ connection node in the primary fails, the link will be
+ re-established on the next node that was started (time) on the
+ primary site.
+ </para>
+ </listitem>
+ </itemizedlist>
+ <para>
+ Due to the acknowledged transfer of events over the bridge (see
+ note above) manual recreation of the bridge and automatic
+ re-establishment of te bridge after connection failure (including
+ failover where either or both ends are clustered brokers) will
+ not result in event loss.
+ </para>
+ <!--h3-->
+ </section>
+
+ <section role="h3" id="queuestatereplication-OperationsonBackupQueues">
+ <title>
+ Operations
+ on Backup Queues
+ </title>
+ <para>
+ When replicating the state of a queue to a backup broker it is
+ important to recognise that any other operations performed
+ directly on the backup queue may break the replication.
+ </para>
+ <para>
+ If the backup queue is to be an active (i.e. accessed by clients
+ while replication is on) only enqueues should be selected
+ for
+ replication. In this mode, any message enqueued on the source
+ brokers copy of the queue will also be enqueued on the backup
+ brokers copy. However not attempt will be made to remove messages
+ from the backup queue in response to removal of messages from the
+ source queue.
+ </para>
+ <!--h3-->
+ </section>
+
+ <section role="h3" id="queuestatereplication-SelectingQueuesforReplication">
+ <title>
+ Selecting
+ Queues for Replication
+ </title>
+ <para>
+ Queues are selected for replication by specifying the types of
+ events they should generate (it is from these events that the
+ replicating plugin constructs messages which are then pulled and
+ processed by the backup site). This is done through options
+ passed to the initial queue-declare command that creates the
+ queue and may be done either through qpid-config or similar
+ tools, or by the application.
+ </para>
+ <para>
+ With qpid-config, the --generate-queue-events options is used:
+ </para>
+ <programlisting>
+ --generate-queue-events N
+ If set to 1, every enqueue will generate an event that can be processed by
+ registered listeners (e.g. for replication). If set to 2, events will be
+ generated for enqueues and dequeues
+ </programlisting>
+ <para>
+ From an application, the arguments field of the queue-declare
+ AMQP command is used to convey this information. An entry should
+ be added to the map with key 'qpid.queue_event_generation' and an
+ integer value of 1 (to replicate only enqueue events) or 2 (to
+ replicate both enqueue and dequeue events).
+ </para>
+ <para>
+ Applications written using the c++ client API may fine the
+ qpid::client::QueueOptions class convenient. This has a
+ enableQueueEvents() method on it that can be used to set the
+ option (the instance of QueueOptions is then passed as the value
+ of the arguments field in the queue-declare command. The boolean
+ option to that method should be set to true if only enequeue
+ events should be replicated; by default it is false meaning that
+ both enqueues and dequeues will be replicated. E.g.
+ </para>
+ <programlisting>
+ QueueOptions options;
+ options.enableQueueEvents(false);
+ session.queueDeclare(arg::queue="my-queue", arg::arguments=options);
+ </programlisting>
+ <!--h3-->
+ </section>
+
+ <section role="h3" id="queuestatereplication-Example">
+ <title>
+ Example
+ </title>
+ <para>
+ Lets assume we will run the primary broker on host1 and the
+ backup on host2, have installed qpidd on both and have the
+ replicating_listener and replication_exchange plugins in qpidd's
+ module directory(*1).
+ </para>
+ <para>
+ On host1 we start the source broker and specifcy that a queue
+ called 'replication' should be used for storing the events until
+ consumed by the backup. We also request that this queue be
+ created (as transient) if not already specified:
+ </para>
+ <programlisting>
+ qpidd --replication-queue replication-queue --create-replication-queue true --log-enable info+
+ </programlisting>
+ <para>
+ On host2 we start up the backup broker ensuring that the
+ replication exchange module is loaded:
+ </para>
+ <programlisting>
+ qpidd
+ </programlisting>
+ <para>
+ We can then create the instance of that replication exchange that
+ we will use to process the events:
+ </para>
+ <programlisting>
+ qpid-config -a host2 add exchange replication replication-exchange
+ </programlisting>
+ <para>
+ If this fails with the message "Exchange type not implemented:
+ replication", it means the replication exchange module was
+ not
+ loaded. Check that the module is installed on your system and if
+ necessary provide the full path to the library.
+ </para>
+ <para>
+ We then connect the replication queue on the source broker with
+ the replication exchange on the backup broker using the
+ qpid-route command:
+ </para>
+ <programlisting>
+ qpid-route --ack 50 queue add host2 host1 replication-exchange replication-queue
+</programlisting>
+ <para>
+ The example above configures the bridge to acknowledge messages
+ in batches of 50.
+ </para>
+ <para>
+ Now create two queues (on both source and backup brokers), one
+ replicating both enqueues and dequeues (queue-a) and the
+ other
+ replicating only dequeues (queue-b):
+ </para>
+ <programlisting>
+ qpid-config -a host1 add queue queue-a --generate-queue-events 2
+ qpid-config -a host1 add queue queue-b --generate-queue-events 1
+
+ qpid-config -a host2 add queue queue-a
+ qpid-config -a host2 add queue queue-b
+ </programlisting>
+ <para>
+ We are now ready to use the queues and see the replication.
+ </para>
+ <para>
+ Any message enqueued on queue-a will be replicated to the backup
+ broker. When the message is acknowledged by a client connected to
+ host1 (and thus dequeued), that message will be removed from the
+ copy of the queue on host2. The state of queue-a on host2 will
+ thus mirror that of the equivalent queue on host1, albeit with a
+ small lag. (Note
+ however that we must not have clients connected to host2 publish
+ to-or consume from- queue-a or the state will fail to replicate
+ correctly due to conflicts).
+ </para>
+ <para>
+ Any message enqueued on queue-b on host1 will also be enqueued on
+ the equivalent queue on host2. However the acknowledgement and
+ consequent dequeuing of messages from queue-b on host1 will have
+ no effect on the state of queue-b on host2.
+ </para>
+ <para>
+ (*1) If not the paths in the above may need to be modified. E.g.
+ if using modules built from a qpid svn checkout, the following
+ would be added to the command line used to start qpidd on host1:
+ </para>
+ <programlisting>
+ --load-module &lt;path-to-qpid-dir&gt;/src/.libs/replicating_listener.so
+ </programlisting>
+ <para>
+ and the following for the equivalent command line on host2:
+ </para>
+ <programlisting>
+ --load-module &lt;path-to-qpid-dir&gt;/src/.libs/replication_exchange.so
+ </programlisting>
+ <!--h3-->
+ </section>
+ <!--h2-->
+ </section>
+</section>
diff --git a/qpid/doc/book/src/schemas.xml b/qpid/doc/book/src/schemas.xml
new file mode 100644
index 0000000000..d0bec81aed
--- /dev/null
+++ b/qpid/doc/book/src/schemas.xml
@@ -0,0 +1,101 @@
+<?xml version="1.0"?>
+<!--
+
+ 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.
+
+-->
+
+<locatingRules xmlns="http://thaiopensource.com/ns/locating-rules/1.0">
+ <uri resource="foo.xml" typeId="DocBook"/>
+ <uri resource="foo.xml" typeId="DocBook"/>
+ <uri resource="Programming-In-Apache-Qpid.xml" typeId="DocBook"/>
+ <uri resource="queue-state-replication.xml" typeId="DocBook"/>
+ <uri resource="AMQP-Messaging-Broker-Java-Book.xml" typeId="DocBook"/>
+ <uri resource="High-Level-API.xml" typeId="DocBook"/>
+ <uri resource="High-Level-API.xml" typeId="DocBook"/>
+ <uri resource="Java-JMS-Selector-Syntax.xml" typeId="DocBook"/>
+ <uri resource="ACL.xml" typeId="DocBook"/>
+ <uri resource="Add-New-Users.xml" typeId="DocBook"/>
+ <uri resource="AMQP-C++-Messaging-Client.xml" typeId="DocBook"/>
+ <uri resource="AMQP-Compatibility.xml" typeId="DocBook"/>
+ <uri resource="AMQP-Java-JMS-Messaging-Client.xml" typeId="DocBook"/>
+ <uri resource="AMQP-Messaging-Broker-CPP.xml" typeId="DocBook"/>
+ <uri resource="AMQP-Messaging-Broker-Java.xml" typeId="DocBook"/>
+ <uri resource="AMQP-.NET-Messaging-Client.xml" typeId="DocBook"/>
+ <uri resource="AMQP-Python-Messaging-Client.xml" typeId="DocBook"/>
+ <uri resource="AMQP-Ruby-Messaging-Client.xml" typeId="DocBook"/>
+ <uri resource="AMQP.xml" typeId="DocBook"/>
+ <uri resource="Binding-URL-Format.xml" typeId="DocBook"/>
+ <uri resource="Book-Info.xml" typeId="DocBook"/>
+ <uri resource="Book.xml" typeId="DocBook"/>
+ <uri resource="Broker-CPP.xml" typeId="DocBook"/>
+ <uri resource="Broker-Java.xml" typeId="DocBook"/>
+ <uri resource="Cheat-Sheet-for-configuring-Exchange-Options.xml" typeId="DocBook"/>
+ <uri resource="Cheat-Sheet-for-configuring-Queue-Options.xml" typeId="DocBook"/>
+ <uri resource="Clients.xml" typeId="DocBook"/>
+ <uri resource="Configure-ACLs.xml" typeId="DocBook"/>
+ <uri resource="Configure-Java-Qpid-to-use-a-SSL-connection.xml" typeId="DocBook"/>
+ <uri resource="Configure-Log4j-CompositeRolling-Appender.xml" typeId="DocBook"/>
+ <uri resource="Configure-the-Broker-via-config.xml.xml" typeId="DocBook"/>
+ <uri resource="Configure-the-Virtual-Hosts-via-virtualhosts.xml.xml" typeId="DocBook"/>
+ <uri resource="Configuring-Management-Users.xml" typeId="DocBook"/>
+ <uri resource="Configuring-Qpid-JMX-Management-Console.xml" typeId="DocBook"/>
+ <uri resource="Connection-URL-Format.xml" typeId="DocBook"/>
+ <uri resource="Debug-using-log4j.xml" typeId="DocBook"/>
+ <uri resource="Download.xml" typeId="DocBook"/>
+ <uri resource="Excel-AddIn.xml" typeId="DocBook"/>
+ <uri resource="FAQ.xml" typeId="DocBook"/>
+ <uri resource="foo.xml" typeId="DocBook"/>
+ <uri resource="f.xml" typeId="DocBook"/>
+ <uri resource="Getting-Started.xml" typeId="DocBook"/>
+ <uri resource="How-to-Tune-M3-Java-Broker-Performance.xml" typeId="DocBook"/>
+ <uri resource="How-to-Use-JNDI.xml" typeId="DocBook"/>
+ <uri resource="Introduction.xml" typeId="DocBook"/>
+ <uri resource="Java-Broker-Feature-Guide.xml" typeId="DocBook"/>
+ <uri resource="Java-Environment-Variables.xml" typeId="DocBook"/>
+ <uri resource="LVQ.xml" typeId="DocBook"/>
+ <uri resource="Management-Console-Security.xml" typeId="DocBook"/>
+ <uri resource="Management-Design-notes.xml" typeId="DocBook"/>
+ <uri resource="Managing-CPP-Broker.xml" typeId="DocBook"/>
+ <uri resource="MessageStore-Tool.xml" typeId="DocBook"/>
+ <uri resource="NET-User-Guide.xml" typeId="DocBook"/>
+ <uri resource="PythonBrokerTest.xml" typeId="DocBook"/>
+ <uri resource="QMan-Qpid-Management-bridge.xml" typeId="DocBook"/>
+ <uri resource="QMF-Python-Console-Tutorial.xml" typeId="DocBook"/>
+ <uri resource="Qpid-ACLs.xml" typeId="DocBook"/>
+ <uri resource="Qpid-Interoperability-Documentation.xml" typeId="DocBook"/>
+ <uri resource="Qpid-Java-Broker-Management-CLI.xml" typeId="DocBook"/>
+ <uri resource="Qpid-Java-Build-How-To.xml" typeId="DocBook"/>
+ <uri resource="Qpid-Java-FAQ.xml" typeId="DocBook"/>
+ <uri resource="Qpid-JMX-Management-Console-FAQ.xml" typeId="DocBook"/>
+ <uri resource="Qpid-JMX-Management-Console-User-Guide.xml" typeId="DocBook"/>
+ <uri resource="Qpid-JMX-Management-Console.xml" typeId="DocBook"/>
+ <uri resource="Qpid-Management-Features.xml" typeId="DocBook"/>
+ <uri resource="Qpid-Management-Framework.xml" typeId="DocBook"/>
+ <uri resource="Qpid-Troubleshooting-Guide.xml" typeId="DocBook"/>
+ <uri resource="queue-state-replication.xml" typeId="DocBook"/>
+ <uri resource="Running-CPP-Broker.xml" typeId="DocBook"/>
+ <uri resource="SASL-Compatibility.xml" typeId="DocBook"/>
+ <uri resource="SSL.xml" typeId="DocBook"/>
+ <uri resource="Starting-a-cluster.xml" typeId="DocBook"/>
+ <uri resource="System-Properties.xml" typeId="DocBook"/>
+ <uri resource="Use-Priority-Queues.xml" typeId="DocBook"/>
+ <uri resource="Using-Broker-Federation.xml" typeId="DocBook"/>
+ <uri resource="Using-Qpid-with-other-JNDI-Providers.xml" typeId="DocBook"/>
+ <uri resource="WCF.xml" typeId="DocBook"/>
+</locatingRules>