You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by rg...@apache.org on 2016/11/15 10:41:20 UTC

svn commit: r1769772 [1/2] - in /qpid/java/branches/remove-queue-runner: ./ broker-core/src/main/java/org/apache/qpid/server/model/ broker-core/src/main/java/org/apache/qpid/server/queue/ broker-plugins/management-http/src/main/java/resources/ broker-p...

Author: rgodfrey
Date: Tue Nov 15 10:41:20 2016
New Revision: 1769772

URL: http://svn.apache.org/viewvc?rev=1769772&view=rev
Log:
Merged from trunk up to r1769382

Added:
    qpid/java/branches/remove-queue-runner/broker-plugins/management-http/src/main/java/resources/js/qpid/common/HexDumpWidget.js
      - copied unchanged from r1769382, qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/common/HexDumpWidget.js
    qpid/java/branches/remove-queue-runner/doc/java-broker/src/docbkx/management/channels/Java-Broker-Management-Channel-REST-Query-API.xml
      - copied unchanged from r1769382, qpid/java/trunk/doc/java-broker/src/docbkx/management/channels/Java-Broker-Management-Channel-REST-Query-API.xml
Modified:
    qpid/java/branches/remove-queue-runner/   (props changed)
    qpid/java/branches/remove-queue-runner/broker-core/src/main/java/org/apache/qpid/server/model/Queue.java
    qpid/java/branches/remove-queue-runner/broker-core/src/main/java/org/apache/qpid/server/queue/AbstractQueue.java
    qpid/java/branches/remove-queue-runner/broker-core/src/main/java/org/apache/qpid/server/queue/MessageContentJsonConverter.java
    qpid/java/branches/remove-queue-runner/broker-plugins/management-http/src/main/java/resources/css/common.css
    qpid/java/branches/remove-queue-runner/broker-plugins/management-http/src/main/java/resources/dashboard/AddWidgetDialogContent.html
    qpid/java/branches/remove-queue-runner/broker-plugins/management-http/src/main/java/resources/js/qpid/common/util.js
    qpid/java/branches/remove-queue-runner/broker-plugins/management-http/src/main/java/resources/js/qpid/management/DashboardTab.js
    qpid/java/branches/remove-queue-runner/broker-plugins/management-http/src/main/java/resources/js/qpid/management/QueryTab.js
    qpid/java/branches/remove-queue-runner/broker-plugins/management-http/src/main/java/resources/js/qpid/management/dashboard/DashboardWidget.js
    qpid/java/branches/remove-queue-runner/broker-plugins/management-http/src/main/java/resources/js/qpid/management/query/DropDownSelect.js
    qpid/java/branches/remove-queue-runner/broker-plugins/management-http/src/main/java/resources/js/qpid/management/query/WhereExpression.js
    qpid/java/branches/remove-queue-runner/broker-plugins/management-http/src/main/java/resources/js/qpid/management/showMessage.js
    qpid/java/branches/remove-queue-runner/broker-plugins/management-http/src/main/java/resources/showMessage.html
    qpid/java/branches/remove-queue-runner/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer_0_10.java
    qpid/java/branches/remove-queue-runner/common/src/main/java/org/apache/qpid/transport/codec/AbstractDecoder.java
    qpid/java/branches/remove-queue-runner/common/src/main/java/org/apache/qpid/transport/codec/AbstractEncoder.java
    qpid/java/branches/remove-queue-runner/doc/java-broker/src/docbkx/management/channels/Java-Broker-Management-Channel-REST-API.xml
    qpid/java/branches/remove-queue-runner/doc/java-broker/src/docbkx/management/managing/Java-Broker-Management-Managing-Truststores.xml
    qpid/java/branches/remove-queue-runner/doc/java-broker/src/docbkx/runtime/Java-Broker-Runtime-Memory.xml
    qpid/java/branches/remove-queue-runner/doc/jms-client-0-8/src/docbkx/JMS-Client-Appendix-Exceptions.xml
    qpid/java/branches/remove-queue-runner/doc/jms-client-0-8/src/docbkx/JMS-Client-Message-Encryption.xml
    qpid/java/branches/remove-queue-runner/systests/src/test/java/org/apache/qpid/systest/rest/MessagesRestTest.java
    qpid/java/branches/remove-queue-runner/test-profiles/apache-ci.test.overridden.properties

Propchange: qpid/java/branches/remove-queue-runner/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Tue Nov 15 10:41:20 2016
@@ -9,5 +9,5 @@
 /qpid/branches/java-broker-vhost-refactor/java:1493674-1494547
 /qpid/branches/java-network-refactor/qpid/java:805429-821809
 /qpid/branches/qpid-2935/qpid/java:1061302-1072333
-/qpid/java/trunk:1767741-1768048
+/qpid/java/trunk:1767741-1769382
 /qpid/trunk/qpid:796646-796653

Modified: qpid/java/branches/remove-queue-runner/broker-core/src/main/java/org/apache/qpid/server/model/Queue.java
URL: http://svn.apache.org/viewvc/qpid/java/branches/remove-queue-runner/broker-core/src/main/java/org/apache/qpid/server/model/Queue.java?rev=1769772&r1=1769771&r2=1769772&view=diff
==============================================================================
--- qpid/java/branches/remove-queue-runner/broker-core/src/main/java/org/apache/qpid/server/model/Queue.java (original)
+++ qpid/java/branches/remove-queue-runner/broker-core/src/main/java/org/apache/qpid/server/model/Queue.java Tue Nov 15 10:41:20 2016
@@ -322,14 +322,13 @@ public interface Queue<X extends Queue<X
     @ManagedOperation(description = "removes all messages from this queue", changesConfiguredObjectState = false)
     long clearQueue();
 
-    @ManagedOperation(nonModifying = true, secure = true, changesConfiguredObjectState = false)
+    @ManagedOperation(nonModifying = true, secure = true, changesConfiguredObjectState = false,
+                      description = "Gets the message content")
     Content getMessageContent(@Param(name = "messageId") long messageId,
                               @Param(name = "limit", defaultValue = "-1",
                                       description = "Number of bytes to return") long limit,
                               @Param(name = "returnJson", defaultValue = "false",
-                                      description = "If true, converts message content into json format"
-                                                    + " if message mime-type is either amqp/map or amqp/list"
-                                                    + " or jms/map-message. Default is false.") boolean returnJson,
+                                      description = "If true, converts message content into JSON format.") boolean returnJson,
                               @Param(name = "decompressBeforeLimiting", defaultValue = "false",
                                       description = "If true, the operation will attempt to decompress the message"
                                                     + "(should it be compressed) before applying any limit. If"

Modified: qpid/java/branches/remove-queue-runner/broker-core/src/main/java/org/apache/qpid/server/queue/AbstractQueue.java
URL: http://svn.apache.org/viewvc/qpid/java/branches/remove-queue-runner/broker-core/src/main/java/org/apache/qpid/server/queue/AbstractQueue.java?rev=1769772&r1=1769771&r2=1769772&view=diff
==============================================================================
--- qpid/java/branches/remove-queue-runner/broker-core/src/main/java/org/apache/qpid/server/queue/AbstractQueue.java (original)
+++ qpid/java/branches/remove-queue-runner/broker-core/src/main/java/org/apache/qpid/server/queue/AbstractQueue.java Tue Nov 15 10:41:20 2016
@@ -3275,10 +3275,7 @@ public abstract class AbstractQueue<X ex
                                          final long limit,
                                          final boolean decompressBeforeLimiting)
     {
-        String mimeType = messageReference.getMessage().getMessageHeader().getMimeType();
-        if (returnJson && ("amqp/list".equalsIgnoreCase(mimeType)
-                           || "amqp/map".equalsIgnoreCase(mimeType)
-                           || "jms/map-message".equalsIgnoreCase(mimeType)))
+        if (returnJson)
         {
             ServerMessage message = messageReference.getMessage();
             if (message instanceof InternalMessage)
@@ -3295,9 +3292,17 @@ public abstract class AbstractQueue<X ex
                                                   (InternalMessage) messageConverter.convert(message, getVirtualHost()),
                                                   limit);
                 }
+                else
+                {
+                    throw new IllegalArgumentException(String.format("Unable to convert message %d on queue '%s' to JSON",
+                                                                     message.getMessageNumber(), getName()));
+                }
             }
         }
-        return new MessageContent(messageReference, limit, decompressBeforeLimiting);
+        else
+        {
+            return new MessageContent(messageReference, limit, decompressBeforeLimiting);
+        }
     }
 
     @Override
@@ -3338,6 +3343,7 @@ public abstract class AbstractQueue<X ex
                 if (_messageNumber == message.getMessageNumber())
                 {
                     _messageInfo = new MessageInfoImpl(entry, _includeHeaders);
+                    return true;
                 }
             }
             return false;

Modified: qpid/java/branches/remove-queue-runner/broker-core/src/main/java/org/apache/qpid/server/queue/MessageContentJsonConverter.java
URL: http://svn.apache.org/viewvc/qpid/java/branches/remove-queue-runner/broker-core/src/main/java/org/apache/qpid/server/queue/MessageContentJsonConverter.java?rev=1769772&r1=1769771&r2=1769772&view=diff
==============================================================================
--- qpid/java/branches/remove-queue-runner/broker-core/src/main/java/org/apache/qpid/server/queue/MessageContentJsonConverter.java (original)
+++ qpid/java/branches/remove-queue-runner/broker-core/src/main/java/org/apache/qpid/server/queue/MessageContentJsonConverter.java Tue Nov 15 10:41:20 2016
@@ -30,7 +30,14 @@ import java.util.List;
 import java.util.Map;
 import java.util.UUID;
 
+import com.fasterxml.jackson.core.JsonGenerator;
 import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.SerializerProvider;
+import com.fasterxml.jackson.databind.module.SimpleModule;
+import com.fasterxml.jackson.databind.ser.std.StdArraySerializers;
+import com.fasterxml.jackson.databind.ser.std.StdSerializer;
+import com.google.common.primitives.Bytes;
+import com.google.common.primitives.Ints;
 
 class MessageContentJsonConverter
 {
@@ -46,6 +53,9 @@ class MessageContentJsonConverter
     {
         _messageBody = messageBody;
         _objectMapper = new ObjectMapper();
+        SimpleModule module = new SimpleModule();
+        module.addSerializer(new NoneBase64ByteArraySerializer());
+        _objectMapper.registerModule(module);
         _remaining = limit;
     }
 
@@ -180,4 +190,20 @@ class MessageContentJsonConverter
         return copyCollection(copy);
     }
 
+    private static class NoneBase64ByteArraySerializer extends StdSerializer<byte[]>
+    {
+        final StdArraySerializers.IntArraySerializer _underlying = new StdArraySerializers.IntArraySerializer();
+
+        public NoneBase64ByteArraySerializer()
+        {
+            super(byte[].class);
+        }
+
+        @Override
+        public void serialize(final byte[] value, final JsonGenerator jgen, final SerializerProvider provider)
+                throws IOException
+        {
+            _underlying.serialize(Ints.toArray(Bytes.asList(value)), jgen, provider);
+        }
+    }
 }

Modified: qpid/java/branches/remove-queue-runner/broker-plugins/management-http/src/main/java/resources/css/common.css
URL: http://svn.apache.org/viewvc/qpid/java/branches/remove-queue-runner/broker-plugins/management-http/src/main/java/resources/css/common.css?rev=1769772&r1=1769771&r2=1769772&view=diff
==============================================================================
--- qpid/java/branches/remove-queue-runner/broker-plugins/management-http/src/main/java/resources/css/common.css (original)
+++ qpid/java/branches/remove-queue-runner/broker-plugins/management-http/src/main/java/resources/css/common.css Tue Nov 15 10:41:20 2016
@@ -380,7 +380,8 @@ div .messages {
 .infoPane
 {
     margin-left: 5px;
-    padding: 5px 5px 5px 1.2em;
+    margin-bottom: 5px;
+    padding: 5px 5px 0px 1.2em;
     font-style: italic;
     background:url("../images/notification.svg") no-repeat left center;
     background-size: 1em;
@@ -655,9 +656,9 @@ td.advancedSearchField, col.autoWidth {
     background-size: 1em;
 }
 
-#message-content-preview{
+#message-content-preview
+{
     width: 100%;
-    height: 10.2em;
 }
 
 #message-content-preview .dgrid,
@@ -665,3 +666,58 @@ td.advancedSearchField, col.autoWidth {
 {
     height: 10em;
 }
+
+.hexDumpBox
+{
+    border: solid;
+    border-width: 1px;
+    white-space: nowrap;
+}
+
+.hexBox
+{
+    display: inline-block;
+    padding-right: 25px;
+}
+
+.asciiBox
+{
+    display: inline-block;
+}
+
+.hexDumpHeadRow
+{
+    display: table-row;
+    font-family: monospace;
+    font-weight: bold;
+}
+
+.hexDumpRow
+{
+    display: table-row;
+}
+
+.hexCountCell
+{
+    padding-right: 25px;
+    font-weight: bold;
+    display: table-cell;
+    font-family: monospace;
+}
+
+.hexDumpCell
+{
+    padding-right: 5px;
+    display: table-cell;
+    font-family: monospace;
+}
+
+.hexDumpCell:last-child
+{
+    padding-right: 0;
+}
+
+.hexDumpCellHighlight
+{
+    background-color: darkgray;
+}

Modified: qpid/java/branches/remove-queue-runner/broker-plugins/management-http/src/main/java/resources/dashboard/AddWidgetDialogContent.html
URL: http://svn.apache.org/viewvc/qpid/java/branches/remove-queue-runner/broker-plugins/management-http/src/main/java/resources/dashboard/AddWidgetDialogContent.html?rev=1769772&r1=1769771&r2=1769772&view=diff
==============================================================================
--- qpid/java/branches/remove-queue-runner/broker-plugins/management-http/src/main/java/resources/dashboard/AddWidgetDialogContent.html (original)
+++ qpid/java/branches/remove-queue-runner/broker-plugins/management-http/src/main/java/resources/dashboard/AddWidgetDialogContent.html Tue Nov 15 10:41:20 2016
@@ -19,6 +19,7 @@
 <div style="width:50vw">
     <form data-dojo-attach-point="addWidgetForm" data-dojo-type="dijit/form/Form" id="${id}_addWidgetForm">
         <div>
+            <div class="infoPane">Please, double-click on a row to add the corresponding widget into dashboard</div>
             <div data-dojo-attach-point="queryBrowserNode"></div>
         </div>
         <div class="dijitDialogPaneActionBar">

Modified: qpid/java/branches/remove-queue-runner/broker-plugins/management-http/src/main/java/resources/js/qpid/common/util.js
URL: http://svn.apache.org/viewvc/qpid/java/branches/remove-queue-runner/broker-plugins/management-http/src/main/java/resources/js/qpid/common/util.js?rev=1769772&r1=1769771&r2=1769772&view=diff
==============================================================================
--- qpid/java/branches/remove-queue-runner/broker-plugins/management-http/src/main/java/resources/js/qpid/common/util.js (original)
+++ qpid/java/branches/remove-queue-runner/broker-plugins/management-http/src/main/java/resources/js/qpid/common/util.js Tue Nov 15 10:41:20 2016
@@ -75,6 +75,22 @@ define(["dojo/_base/xhr",
               updater)
     {
         var util = {};
+
+        if (Number.isInteger)
+        {
+            util.isInteger = function(value)
+            {
+                return Number.isInteger(value);
+            };
+        }
+        else
+        {
+            util.isInteger = function(value)
+            {
+                return typeof value === "number" && isFinite(value) && Math.floor(value) === value;
+            };
+        }
+
         if (Array.isArray)
         {
             util.isArray = function (object)

Modified: qpid/java/branches/remove-queue-runner/broker-plugins/management-http/src/main/java/resources/js/qpid/management/DashboardTab.js
URL: http://svn.apache.org/viewvc/qpid/java/branches/remove-queue-runner/broker-plugins/management-http/src/main/java/resources/js/qpid/management/DashboardTab.js?rev=1769772&r1=1769771&r2=1769772&view=diff
==============================================================================
--- qpid/java/branches/remove-queue-runner/broker-plugins/management-http/src/main/java/resources/js/qpid/management/DashboardTab.js (original)
+++ qpid/java/branches/remove-queue-runner/broker-plugins/management-http/src/main/java/resources/js/qpid/management/DashboardTab.js Tue Nov 15 10:41:20 2016
@@ -168,12 +168,12 @@ define(["dojo/parser",
                 message: "<div>Dashbord contains unsaved changes.<br/>Would you like to close it anyway?</div>",
                 confirmationId: "dashboard.confirmation.close.changed"
             })
-                .then(lang.hitch(this, this.destroy));
+                .then(lang.hitch(this, function(){this.destroy(true);}));
 
             return false;
         };
 
-        DashboardTab.prototype.destroy = function ()
+        DashboardTab.prototype.destroy = function (destroyContentPane)
         {
             if (this.destroyed)
             {
@@ -188,6 +188,12 @@ define(["dojo/parser",
                 this.dashboardWidget.destroyRecursive();
                 this.dashboardWidget = null;
             }
+
+            if (destroyContentPane)
+            {
+                this.contentPane.getParent().removeChild(this.contentPane);
+                this.contentPane.destroyRecursive();
+            }
         };
 
         DashboardTab.stopDisplayingConfirmation = false;

Modified: qpid/java/branches/remove-queue-runner/broker-plugins/management-http/src/main/java/resources/js/qpid/management/QueryTab.js
URL: http://svn.apache.org/viewvc/qpid/java/branches/remove-queue-runner/broker-plugins/management-http/src/main/java/resources/js/qpid/management/QueryTab.js?rev=1769772&r1=1769771&r2=1769772&view=diff
==============================================================================
--- qpid/java/branches/remove-queue-runner/broker-plugins/management-http/src/main/java/resources/js/qpid/management/QueryTab.js (original)
+++ qpid/java/branches/remove-queue-runner/broker-plugins/management-http/src/main/java/resources/js/qpid/management/QueryTab.js Tue Nov 15 10:41:20 2016
@@ -164,12 +164,12 @@ define(["dojo/parser",
                 message: "<div>Query contains unsaved changes.<br/>Would you like to close it anyway?</div>",
                 confirmationId: "query.confirmation.close.changed"
             })
-                .then(lang.hitch(this, this.destroy));
+                .then(lang.hitch(this, function(){this.destroy(true);}));
 
             return false;
         };
 
-        QueryTab.prototype.destroy = function ()
+        QueryTab.prototype.destroy = function (destroyContentPane)
         {
             if (this.destroyed)
             {
@@ -184,6 +184,12 @@ define(["dojo/parser",
                 this.queryWidget.destroyRecursive();
                 this.queryWidget = null;
             }
+
+            if (destroyContentPane)
+            {
+                this.contentPane.getParent().removeChild(this.contentPane);
+                this.contentPane.destroyRecursive();
+            }
         };
 
         return QueryTab;

Modified: qpid/java/branches/remove-queue-runner/broker-plugins/management-http/src/main/java/resources/js/qpid/management/dashboard/DashboardWidget.js
URL: http://svn.apache.org/viewvc/qpid/java/branches/remove-queue-runner/broker-plugins/management-http/src/main/java/resources/js/qpid/management/dashboard/DashboardWidget.js?rev=1769772&r1=1769771&r2=1769772&view=diff
==============================================================================
--- qpid/java/branches/remove-queue-runner/broker-plugins/management-http/src/main/java/resources/js/qpid/management/dashboard/DashboardWidget.js (original)
+++ qpid/java/branches/remove-queue-runner/broker-plugins/management-http/src/main/java/resources/js/qpid/management/dashboard/DashboardWidget.js Tue Nov 15 10:41:20 2016
@@ -92,7 +92,15 @@ define(["dojo/_base/declare",
                     }, this.queryBrowserNode);
                     this._queryBrowser.on("open", lang.hitch(this, this._onOpenQuery));
                 },
-
+                startup: function ()
+                {
+                    this.inherited(arguments);
+                    this._queryBrowser.startup();
+                },
+                resizeQueryBrowser: function ()
+                {
+                    this._queryBrowser.resize();
+                },
                 update: function ()
                 {
                     return this._queryBrowser.update();
@@ -171,7 +179,7 @@ define(["dojo/_base/declare",
                     this._addWidgetDialogContent.on("cancel",
                         lang.hitch(this._addWidgetDialog, this._addWidgetDialog.hide));
                     this._addWidgetDialogContent.on("add", lang.hitch(this, this._onWidgetChosen));
-
+                    this._addWidgetDialog.on("show", lang.hitch(this._addWidgetDialogContent, this._addWidgetDialogContent.resizeQueryBrowser));
                     this._saveDashboardDialogContent = new PreferenceSaveDialogContent({management: this.management});
                     this._saveDashboardDialog =
                         new dijit.Dialog({title: "Save Dashboard", content: this._saveDashboardDialogContent});

Modified: qpid/java/branches/remove-queue-runner/broker-plugins/management-http/src/main/java/resources/js/qpid/management/query/DropDownSelect.js
URL: http://svn.apache.org/viewvc/qpid/java/branches/remove-queue-runner/broker-plugins/management-http/src/main/java/resources/js/qpid/management/query/DropDownSelect.js?rev=1769772&r1=1769771&r2=1769772&view=diff
==============================================================================
--- qpid/java/branches/remove-queue-runner/broker-plugins/management-http/src/main/java/resources/js/qpid/management/query/DropDownSelect.js (original)
+++ qpid/java/branches/remove-queue-runner/broker-plugins/management-http/src/main/java/resources/js/qpid/management/query/DropDownSelect.js Tue Nov 15 10:41:20 2016
@@ -87,7 +87,7 @@ define(["dojo/_base/declare",
                 this._selectedItems = this._optionsPanel.get("selectedItems");
                 popup.close(this._optionsDialog);
                 this._optionsPanel.resetItems();
-                this.emit("change", this._selectedItems);
+                this.emit("change", lang.clone(this._selectedItems));
             },
             _hideAndResetSearch: function ()
             {

Modified: qpid/java/branches/remove-queue-runner/broker-plugins/management-http/src/main/java/resources/js/qpid/management/query/WhereExpression.js
URL: http://svn.apache.org/viewvc/qpid/java/branches/remove-queue-runner/broker-plugins/management-http/src/main/java/resources/js/qpid/management/query/WhereExpression.js?rev=1769772&r1=1769771&r2=1769772&view=diff
==============================================================================
--- qpid/java/branches/remove-queue-runner/broker-plugins/management-http/src/main/java/resources/js/qpid/management/query/WhereExpression.js (original)
+++ qpid/java/branches/remove-queue-runner/broker-plugins/management-http/src/main/java/resources/js/qpid/management/query/WhereExpression.js Tue Nov 15 10:41:20 2016
@@ -31,12 +31,13 @@ define(["dojo/_base/declare",
     return declare("qpid.management.query.WhereExpression", [ContentPane, Evented], {
         whereExpression: "",
         whereFieldsSelector: null,
-        _whereItems: {},
+        _whereItems: null,
         userPreferences: null,
 
         postCreate: function ()
         {
             this.inherited(arguments);
+            this._whereItems = {};
             if (this.whereFieldsSelector)
             {
                 this.whereFieldsSelector.on("change", lang.hitch(this, this._whereExpressionChanged));

Modified: qpid/java/branches/remove-queue-runner/broker-plugins/management-http/src/main/java/resources/js/qpid/management/showMessage.js
URL: http://svn.apache.org/viewvc/qpid/java/branches/remove-queue-runner/broker-plugins/management-http/src/main/java/resources/js/qpid/management/showMessage.js?rev=1769772&r1=1769771&r2=1769772&view=diff
==============================================================================
--- qpid/java/branches/remove-queue-runner/broker-plugins/management-http/src/main/java/resources/js/qpid/management/showMessage.js (original)
+++ qpid/java/branches/remove-queue-runner/broker-plugins/management-http/src/main/java/resources/js/qpid/management/showMessage.js Tue Nov 15 10:41:20 2016
@@ -30,6 +30,7 @@ define(["dojo/dom",
         "qpid/common/properties",
         "dojox/html/entities",
         "qpid/common/util",
+        "qpid/common/HexDumpWidget",
         "dojo/text!showMessage.html",
         'dojo/_base/declare',
         'dstore/Memory',
@@ -53,6 +54,7 @@ define(["dojo/dom",
               properties,
               entities,
               util,
+              HexDumpWidget,
               template,
               declare,
               Memory,
@@ -95,6 +97,90 @@ define(["dojo/dom",
 
         };
 
+        showMessage.createPreviewWidget = function(contentData, widgetDiv)
+        {
+            if (typeof contentData !== 'object')
+            {
+                return new dijit.form.SimpleTextarea({
+                    value: contentData,
+                    rows: 4,
+                    readOnly: true
+                }, widgetDiv);
+            }
+            else
+            {
+                if (Array.isArray(contentData))
+                {
+                    var isByteArray = true;
+
+                    for (var i = 0; i < contentData.length; i++)
+                    {
+                        var element = contentData[i];
+                        if (!util.isInteger(element) || element < -128 || element > 127)
+                        {
+                            isByteArray = false;
+                            break;
+                        }
+                    }
+
+                    if (isByteArray)
+                    {
+                        return new HexDumpWidget({data: contentData}, widgetDiv);
+                    }
+                    else
+                    {
+                        var columns = {
+                            value: {
+                                label: 'Item'
+                            }
+                        };
+                        var items = [];
+                        for (var i = 0; i < contentData.length; i++)
+                        {
+                            items.push({
+                                id: i,
+                                value: json.stringify(contentData[i])
+                            });
+                        }
+                        var store = new (declare([Memory, Trackable]))({
+                            data: items
+                        });
+                        return new (declare([OnDemandGrid, DijitRegistry]))({
+                            collection: store,
+                            columns: columns
+                        }, widgetDiv);
+                    }
+
+                }
+                else
+                {
+                    var columns = {
+                        id: {
+                            label: 'Key'
+                        },
+                        value: {
+                            label: 'Value'
+                        }
+                    };
+                    var items = [];
+                    for (var i in contentData)
+                    {
+                        items.push({
+                            id: i,
+                            value: json.stringify(contentData[i])
+                        });
+                    }
+                    var store = new (declare([Memory, Trackable]))({
+                        data: items
+                    });
+                    return new (declare([OnDemandGrid, DijitRegistry]))({
+                        collection: store,
+                        columns: columns
+                    }, widgetDiv);
+                }
+            }
+        }
+
         showMessage.populateShowMessage = function (management, modelObj, data, includesConfidential)
         {
 
@@ -151,7 +237,7 @@ define(["dojo/dom",
                 }
             }
 
-            var preview = query('#preview', this.dialogNode)[0];
+            var contentAndPreview = query('#contentAndPreview', this.dialogNode)[0];
             var confidentialInformationWarning = query('#confidentialInformationWarning', this.dialogNode)[0];
             confidentialInformationWarning.style.display = includesConfidential ? "none" : "block";
             var confidentialCells = query('.confidential', this.dialogNode);
@@ -173,101 +259,47 @@ define(["dojo/dom",
                     type: modelObj.type
                 };
                 var parameters = {messageId: data.id};
-                var url = management.buildObjectURL(contentModelObj, parameters);
-
-                var href = query('a#message-download', this.dialogNode)[0];
-                href.title = url;
-                connect.connect(href, 'onclick', function ()
+                var download = registry.byId('message-download', this.dialogNode);
+                download.on("click", function ()
                 {
                     management.download(contentModelObj, parameters);
                 });
 
-                if (data.mimeType && (data.mimeType.match(/text\/.*/)
-                                      || data.mimeType === "amqp/list"
-                                      || data.mimeType === "amqp/map"
-                                      || data.mimeType === "jms/map-message"))
-                {
-                    var limit = 1024;
-                    preview.style.display = "block";
-                    var previewDetail = query('#preview-detail', preview)[0];
-                    previewDetail.innerHTML = (limit < data.size
-                        ? 'showing the first ' + limit + ' of ' + data.size + ' bytes'
-                        : 'showing all ' + data.size + ' bytes');
-                    var previewContent = query("#message-content-preview", preview)[0];
-                    var previewParameters = lang.mixin({limit: limit, returnJson: true}, parameters);
-                    management.load(contentModelObj, previewParameters, {
-                            handleAs: "text",
-                            headers: {"Content-Type": data.mimeType}
-                        })
-                        .then(function (content)
+                var limit = 1024;
+                var previewParameters = lang.mixin({
+                    limit: limit,
+                    returnJson: true
+                }, parameters);
+                management.load(contentModelObj, previewParameters, {
+                        handleAs: "json"
+                    })
+                    .then(function (content)
+                    {
+                        if (showMessage.previewWidget)
                         {
-                            if (showMessage.previewWidget)
-                            {
-                                showMessage.previewWidget.destroyRecursive();
-                            }
-                            var widgetDiv = construct.create("div", null, previewContent, "last");
-                            var contentWidget = null;
-                            if (data.mimeType === "amqp/list"
-                                || data.mimeType === "amqp/map"
-                                || data.mimeType === "jms/map-message")
-                            {
-                                var contentData = json.parse(content);
-                                var columns, items = [];
-                                if (data.mimeType === "amqp/list")
-                                {
-                                    columns = {
-                                        value: {
-                                            label: 'Item'
-                                        }
-                                    };
-                                    for (var i = 0; i < contentData.length; i++)
-                                    {
-                                        items.push({id: i, value: json.stringify(contentData[i])});
-                                    }
-                                }
-                                else
-                                {
-                                    columns = {
-                                        id: {
-                                            label: 'Key'
-                                        },
-                                        value: {
-                                            label: 'Value'
-                                        }
-                                    };
+                            showMessage.previewWidget.destroyRecursive();
+                        }
 
-                                    for (var i in contentData)
-                                    {
-                                        items.push({id: i, value: json.stringify(contentData[i])});
-                                    }
-                                }
-                                var store = new (declare([Memory, Trackable]))({
-                                    data: items
-                                });
-                                 contentWidget = new (declare([OnDemandGrid,DijitRegistry]))({
-                                    collection: store,
-                                    columns: columns
-                                }, widgetDiv);
+                        if (content == null || (Array.isArray(content) && content.length == 0))
+                        {
+                            contentAndPreview.style.display = "none";
+                        }
+                        else
+                        {
+                            contentAndPreview.style.display = "block";
+                            var previewDetail = query('#preview-detail', contentAndPreview)[0];
+                            previewDetail.innerHTML = (limit < data.size
+                                ? 'showing the first ' + limit + ' of ' + data.size + ' bytes'
+                                : 'showing all ' + data.size + ' bytes');
+                            var previewContent = query("#message-content-preview", contentAndPreview)[0];
 
-                            }
-                            else
-                            {
-                                contentWidget = new dijit.form.SimpleTextarea({
-                                    value: content,
-                                    rows: 4,
-                                    readOnly: true
-                                }, widgetDiv);
-                            }
+                            var widgetDiv = construct.create("div", null, previewContent, "last");
+                            var contentWidget = showMessage.createPreviewWidget(content, widgetDiv);
                             showMessage.previewWidget = contentWidget;
                             contentWidget.startup();
-                            registry.byId("showMessage") .show();
-                        });
-                }
-                else
-                {
-                    preview.style.display = "none";
-                    registry.byId("showMessage").show();
-                }
+                        }
+                        registry.byId("showMessage") .show();
+                    });
             }
             else
             {

Modified: qpid/java/branches/remove-queue-runner/broker-plugins/management-http/src/main/java/resources/showMessage.html
URL: http://svn.apache.org/viewvc/qpid/java/branches/remove-queue-runner/broker-plugins/management-http/src/main/java/resources/showMessage.html?rev=1769772&r1=1769771&r2=1769772&view=diff
==============================================================================
--- qpid/java/branches/remove-queue-runner/broker-plugins/management-http/src/main/java/resources/showMessage.html (original)
+++ qpid/java/branches/remove-queue-runner/broker-plugins/management-http/src/main/java/resources/showMessage.html Tue Nov 15 10:41:20 2016
@@ -16,7 +16,10 @@
   -->
 
 <div class="dijitHidden">
-    <div data-dojo-type="dijit.Dialog" style="width:600px;" data-dojo-props="title:'View Message'" id="showMessage">
+    <div data-dojo-type="dijit.Dialog" style="width:600px;"
+         data-dojo-props="title:'View Message',
+                          autofocus: false"
+         id="showMessage">
 
         <div id="confidentialInformationWarning" class="infoMessage">Confidential message information (headers
             and content) is not available on an insecure transport. Switch to a secure management transport (i.e. one
@@ -87,11 +90,11 @@
             <td style="width: 10em; vertical-align: top"><span style="font-weight: bold;">Content:</span></td>
             <td>
                 <div class="confidential">
-                    <a href="#" id="message-download">Download</a>
-                    <br/>
-                    <div id="preview">
+                    <div id="contentAndPreview">
                         Preview (<span id="preview-detail"></span>):<br/>
                         <div id="message-content-preview"></div>
+                        <br/>
+                        <input type="button" id="message-download" label="Download Content" dojoType="dijit.form.Button"/>
                     </div>
                 </div>
                 <div class="confidentialPlaceholder highlightedText">Not available</div>

Modified: qpid/java/branches/remove-queue-runner/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer_0_10.java
URL: http://svn.apache.org/viewvc/qpid/java/branches/remove-queue-runner/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer_0_10.java?rev=1769772&r1=1769771&r2=1769772&view=diff
==============================================================================
--- qpid/java/branches/remove-queue-runner/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer_0_10.java (original)
+++ qpid/java/branches/remove-queue-runner/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer_0_10.java Tue Nov 15 10:41:20 2016
@@ -401,7 +401,6 @@ public class BasicMessageConsumer_0_10 e
            
             _0_10session.getQpidSession().messageFlush
                 (getConsumerTagString(), Option.UNRELIABLE, Option.SYNC);
-            _0_10session.getQpidSession().sync();
             _0_10session.getQpidSession().messageFlow
                 (getConsumerTagString(), MessageCreditUnit.BYTE,
                  0xFFFFFFFF, Option.UNRELIABLE);
@@ -414,6 +413,7 @@ public class BasicMessageConsumer_0_10 e
                                                 _capacity,
                                                 Option.UNRELIABLE);
             }
+            _0_10session.getQpidSession().sync();
             _0_10session.syncDispatchQueue(false);
             o = super.getMessageFromQueue(-1);
         }

Modified: qpid/java/branches/remove-queue-runner/common/src/main/java/org/apache/qpid/transport/codec/AbstractDecoder.java
URL: http://svn.apache.org/viewvc/qpid/java/branches/remove-queue-runner/common/src/main/java/org/apache/qpid/transport/codec/AbstractDecoder.java?rev=1769772&r1=1769771&r2=1769772&view=diff
==============================================================================
--- qpid/java/branches/remove-queue-runner/common/src/main/java/org/apache/qpid/transport/codec/AbstractDecoder.java (original)
+++ qpid/java/branches/remove-queue-runner/common/src/main/java/org/apache/qpid/transport/codec/AbstractDecoder.java Tue Nov 15 10:41:20 2016
@@ -27,7 +27,7 @@ import org.apache.qpid.transport.RangeSe
 import org.apache.qpid.transport.Struct;
 import org.apache.qpid.transport.Type;
 
-import java.io.UnsupportedEncodingException;
+import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.LinkedHashMap;
@@ -120,23 +120,6 @@ public abstract class AbstractDecoder im
         return readUint64();
     }
 
-    private static final String decode(byte[] bytes, int offset, int length, String charset)
-    {
-        try
-        {
-            return new String(bytes, offset, length, charset);
-        }
-        catch (UnsupportedEncodingException e)
-        {
-            throw new RuntimeException(e);
-        }
-    }
-
-    private static final String decode(byte[] bytes, String charset)
-    {
-        return decode(bytes, 0, bytes.length, charset);
-    }
-
     public String readStr8()
     {
         short size = readUint8();
@@ -145,7 +128,7 @@ public abstract class AbstractDecoder im
 
         if (str == null)
         {
-            str = decode(bin.array(), bin.offset(), bin.size(), "UTF-8");
+            str = new String(bin.array(), bin.offset(), bin.size(), StandardCharsets.UTF_8);
             if(bin.hasExcessCapacity())
             {
                 str8cache.put(bin.copy(), str);
@@ -163,7 +146,7 @@ public abstract class AbstractDecoder im
         int size = readUint16();
         byte[] bytes = new byte[size];
         get(bytes);
-        return decode(bytes, "UTF-8");
+        return new String(bytes, StandardCharsets.UTF_8);
     }
 
     public byte[] readVbin8()
@@ -221,11 +204,6 @@ public abstract class AbstractDecoder im
         return new UUID(msb, lsb);
     }
 
-    public String readContent()
-    {
-        throw new Error("Deprecated");
-    }
-
     public Struct readStruct(int type)
     {
         Struct st = Struct.create(type);
@@ -276,10 +254,10 @@ public abstract class AbstractDecoder im
 
         if (count == 0)
         {
-            return Collections.EMPTY_MAP;
+            return Collections.emptyMap();
         }
 
-        Map<String,Object> result = new LinkedHashMap();
+        Map<String,Object> result = new LinkedHashMap<>();
         for (int i = 0; i < count; i++)
         {
             String key = readStr8();
@@ -305,10 +283,10 @@ public abstract class AbstractDecoder im
 
         if (count == 0)
         {
-            return Collections.EMPTY_LIST;
+            return Collections.emptyList();
         }
 
-        List<Object> result = new ArrayList();
+        List<Object> result = new ArrayList<>();
         for (int i = 0; i < count; i++)
         {
             byte code = get();
@@ -334,10 +312,10 @@ public abstract class AbstractDecoder im
 
         if (count == 0)
         {
-            return Collections.EMPTY_LIST;
+            return Collections.emptyList();
         }
 
-        List<Object> result = new ArrayList<Object>();
+        List<Object> result = new ArrayList<>();
         for (int i = 0; i < count; i++)
         {
             Object value = read(t);

Modified: qpid/java/branches/remove-queue-runner/common/src/main/java/org/apache/qpid/transport/codec/AbstractEncoder.java
URL: http://svn.apache.org/viewvc/qpid/java/branches/remove-queue-runner/common/src/main/java/org/apache/qpid/transport/codec/AbstractEncoder.java?rev=1769772&r1=1769771&r2=1769772&view=diff
==============================================================================
--- qpid/java/branches/remove-queue-runner/common/src/main/java/org/apache/qpid/transport/codec/AbstractEncoder.java (original)
+++ qpid/java/branches/remove-queue-runner/common/src/main/java/org/apache/qpid/transport/codec/AbstractEncoder.java Tue Nov 15 10:41:20 2016
@@ -22,8 +22,8 @@ package org.apache.qpid.transport.codec;
 
 import static org.apache.qpid.transport.util.Functions.lsb;
 
-import java.io.UnsupportedEncodingException;
 import java.nio.ByteBuffer;
+import java.nio.charset.StandardCharsets;
 import java.util.HashMap;
 import java.util.LinkedHashMap;
 import java.util.List;
@@ -145,18 +145,6 @@ public abstract class AbstractEncoder im
         writeUint64(l);
     }
 
-    private static final byte[] encode(String s, String charset)
-    {
-        try
-        {
-            return s.getBytes(charset);
-        }
-        catch (UnsupportedEncodingException e)
-        {
-            throw new RuntimeException(e);
-        }
-    }
-
     public void writeStr8(String s)
     {
         if (s == null)
@@ -167,7 +155,11 @@ public abstract class AbstractEncoder im
         byte[] bytes = str8cache.get(s);
         if (bytes == null)
         {
-            bytes = encode(s, "UTF-8");
+            bytes = s.getBytes(StandardCharsets.UTF_8);
+            if (bytes.length > 255)
+            {
+                throw new IllegalArgumentException(String.format("String too long (%d) for str8", bytes.length));
+            }
             str8cache.put(s, bytes);
         }
         writeUint8((short) bytes.length);
@@ -181,7 +173,12 @@ public abstract class AbstractEncoder im
             s = "";
         }
 
-        byte[] bytes = encode(s, "UTF-8");
+        byte[] bytes = s.getBytes(StandardCharsets.UTF_8);
+        if (bytes.length > 65535)
+        {
+            throw new IllegalArgumentException(String.format("String too long (%d) for str16", bytes.length));
+        }
+
         writeUint16(bytes.length);
         put(bytes);
     }

Modified: qpid/java/branches/remove-queue-runner/doc/java-broker/src/docbkx/management/channels/Java-Broker-Management-Channel-REST-API.xml
URL: http://svn.apache.org/viewvc/qpid/java/branches/remove-queue-runner/doc/java-broker/src/docbkx/management/channels/Java-Broker-Management-Channel-REST-API.xml?rev=1769772&r1=1769771&r2=1769772&view=diff
==============================================================================
--- qpid/java/branches/remove-queue-runner/doc/java-broker/src/docbkx/management/channels/Java-Broker-Management-Channel-REST-API.xml (original)
+++ qpid/java/branches/remove-queue-runner/doc/java-broker/src/docbkx/management/channels/Java-Broker-Management-Channel-REST-API.xml Tue Nov 15 10:41:20 2016
@@ -342,6 +342,8 @@ curl --user admin -X PUT  -d '{}' http:/
     </para>
   </section>
 
+  <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="Java-Broker-Management-Channel-REST-Query-API.xml"/>
+
   <section xml:id="Java-Broker-Management-Channel-REST-API-CORS">
     <title>Cross Origin Resource Sharing (CORS)</title>
     <para> The Broker supports Cross Origin Resource Sharing (CORS)

Modified: qpid/java/branches/remove-queue-runner/doc/java-broker/src/docbkx/management/managing/Java-Broker-Management-Managing-Truststores.xml
URL: http://svn.apache.org/viewvc/qpid/java/branches/remove-queue-runner/doc/java-broker/src/docbkx/management/managing/Java-Broker-Management-Managing-Truststores.xml?rev=1769772&r1=1769771&r2=1769772&view=diff
==============================================================================
--- qpid/java/branches/remove-queue-runner/doc/java-broker/src/docbkx/management/managing/Java-Broker-Management-Managing-Truststores.xml (original)
+++ qpid/java/branches/remove-queue-runner/doc/java-broker/src/docbkx/management/managing/Java-Broker-Management-Managing-Truststores.xml Tue Nov 15 10:41:20 2016
@@ -22,10 +22,31 @@
 
 <section xmlns="http://docbook.org/ns/docbook" version="5.0" xml:id="Java-Broker-Management-Managing-Truststores">
     <title>Truststores</title>
-    <para> A <link linkend="Java-Broker-Concepts-Truststores">Truststore</link> is required by a
-        Port in order to SSL client authentication. Some authentication provides also use a
-        truststore when connecting to authentication systems that are protected by a private issuer
-        SSL certificate.</para>
+    <para>
+        <link linkend="Java-Broker-Concepts-Truststores">Truststores</link>
+        have a number of roles within
+        the Broker.
+        <itemizedlist>
+            <listitem>
+                <para>A truststore is required by a Port in order to support SSL client authentication.</para>
+            </listitem>
+            <listitem>
+                <para>Truststores have a optional role in end to end message encryption. The Broker acts as a
+                    <link xmlns:xlink="http://www.w3.org/1999/xlink"
+                          xlink:href="https://en.wikipedia.org/wiki/Key_server_(cryptographic)">
+                        Key Server
+                    </link>
+                    so that publishing applications have convenient access to recipient's public keys.
+                </para>
+            </listitem>
+            <listitem>
+                <para>Some authentication providers also use a truststore when connecting to authentication systems that
+                    are protected by a private issuer
+                    SSL certificate.
+                </para>
+            </listitem>
+        </itemizedlist>
+    </para>
     <section xml:id="Java-Broker-Management-Managing-Truststores-Types">
         <title>Types</title>
         <para>The following truststore types are supported. <itemizedlist>
@@ -55,6 +76,11 @@
                     <para><emphasis>Name the truststore</emphasis>. Used to identify the
                         truststore.</para>
                 </listitem>
+                <listitem>
+                    <para><emphasis>Exposed as Message Source</emphasis>. If enabled, the Broker
+                        will distribute certificates contained within the trustore to clients.
+                        Used by the end to end message encryption feature.</para>
+                </listitem>
             </itemizedlist>
         </para>
         <para>The following attributes apply to <emphasis>File Trust Stores</emphasis> only.</para>

Modified: qpid/java/branches/remove-queue-runner/doc/java-broker/src/docbkx/runtime/Java-Broker-Runtime-Memory.xml
URL: http://svn.apache.org/viewvc/qpid/java/branches/remove-queue-runner/doc/java-broker/src/docbkx/runtime/Java-Broker-Runtime-Memory.xml?rev=1769772&r1=1769771&r2=1769772&view=diff
==============================================================================
--- qpid/java/branches/remove-queue-runner/doc/java-broker/src/docbkx/runtime/Java-Broker-Runtime-Memory.xml (original)
+++ qpid/java/branches/remove-queue-runner/doc/java-broker/src/docbkx/runtime/Java-Broker-Runtime-Memory.xml Tue Nov 15 10:41:20 2016
@@ -57,7 +57,7 @@
     <section>
       <title>Direct</title>
       <para>
-        The world ouside of the JVM, in particular the operating system (OS), does not know about Java heap memory and uses other structures like C arrays.
+        The world outside of the JVM, in particular the operating system (OS), does not know about Java heap memory and uses other structures like C arrays.
         In order to interact with these systems Java needs to copy data between its own heap memory and these native structures.
         This can become a bottle neck when there is a lot of exchange between Java and the OS like in I/O (both disk and network) heavy applications.
         Java's solution to this is to allow programmers to request <literal>ByteBuffer</literal>s from so called direct memory.
@@ -158,7 +158,7 @@
   <section xml:id="Java-Broker-Runtime-Memory-Defaults">
     <title>Defaults</title>
     <para>
-      By default Qpid uses these settiongs:
+      By default Qpid uses these settings:
       <itemizedlist>
         <listitem>
           0.5 GB heap memory
@@ -173,7 +173,7 @@
           Start flow-to-disk at 40% direct memory utilisation.
         </listitem>
       </itemizedlist>
-      As an example, this would accomodate a broker with 50 connections, each serving 5 sessions, and each session having 1000 messages of 1 kB on queues in the broker.
+      As an example, this would accommodate a broker with 50 connections, each serving 5 sessions, and each session having 1000 messages of 1 kB on queues in the broker.
       This means a total of 250 concurrent sessions and a total of 250000 messages without flowing messages to disk.
     </para>
   </section>
@@ -224,8 +224,15 @@
             memory<subscript>direct</subscript> = 2 MB + (200 B + averageSize<subscript>msg</subscript> *2)*  N<subscript>messages</subscript> + 1MB * N<subscript>connections</subscript>
           </mathphrase>
         </informalequation>
+      </para>
+      <para>
         Where <mathphrase>N</mathphrase> denotes the total number of connections/sessions/messages on the broker. Furthermore, for direct memory only the messages that have not been flown to disk are relevant.
       </para>
+      <note>
+        <para>The formulae assume the worst case in terms of memory usage: persistent messages and TLS connections. Transient messages consume less heap memory than peristent and plain connections consume less direct memory than TLS
+          connections.
+        </para>
+      </note>
     </section>
     <section>
       <title>Things to Consider</title>
@@ -236,7 +243,7 @@
           This can have impact on performance in the transient case where otherwise no disk I/O would be involved.
         </para>
         <para>
-          Having to little heap memory will result in poor performance due to frequent garbage collection events. See <xref linkend="Java-Broker-Runtime-Memory-Low-Memory"/> for more details.
+          Having too little heap memory will result in poor performance due to frequent garbage collection events. See <xref linkend="Java-Broker-Runtime-Memory-Low-Memory"/> for more details.
         </para>
       </section>
       <section>

Modified: qpid/java/branches/remove-queue-runner/doc/jms-client-0-8/src/docbkx/JMS-Client-Appendix-Exceptions.xml
URL: http://svn.apache.org/viewvc/qpid/java/branches/remove-queue-runner/doc/jms-client-0-8/src/docbkx/JMS-Client-Appendix-Exceptions.xml?rev=1769772&r1=1769771&r2=1769772&view=diff
==============================================================================
--- qpid/java/branches/remove-queue-runner/doc/jms-client-0-8/src/docbkx/JMS-Client-Appendix-Exceptions.xml (original)
+++ qpid/java/branches/remove-queue-runner/doc/jms-client-0-8/src/docbkx/JMS-Client-Appendix-Exceptions.xml Tue Nov 15 10:41:20 2016
@@ -103,6 +103,15 @@
               group) has not been permissioned within the Broker's <link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="${qpidJavaBrokerBook}Java-Broker-Security-ACLs.html">Access Control List
                 (ACL)</link>.</para></entry>
         </row>
+        <row xml:id="JMS-Client-0-8-Appendix-Exceptions-CertificateException">
+          <entry>CertificateException</entry>
+          <entry>Unable to find certificate for recipient '&lt;recipient&gt;'</entry>
+          <entry>
+            <para>When using end to end message encryption, this exception indicates the the message recipent's
+              principal cannot be found in the truststore. See <xref linkend="JMS-Client-Message-Encryption"/>
+            </para>
+          </entry>
+        </row>
       </tbody>
     </tgroup>
   </table>

Modified: qpid/java/branches/remove-queue-runner/doc/jms-client-0-8/src/docbkx/JMS-Client-Message-Encryption.xml
URL: http://svn.apache.org/viewvc/qpid/java/branches/remove-queue-runner/doc/jms-client-0-8/src/docbkx/JMS-Client-Message-Encryption.xml?rev=1769772&r1=1769771&r2=1769772&view=diff
==============================================================================
--- qpid/java/branches/remove-queue-runner/doc/jms-client-0-8/src/docbkx/JMS-Client-Message-Encryption.xml (original)
+++ qpid/java/branches/remove-queue-runner/doc/jms-client-0-8/src/docbkx/JMS-Client-Message-Encryption.xml Tue Nov 15 10:41:20 2016
@@ -88,8 +88,16 @@
                 <link linkend="JMS-Client-0-8-Connection-URL-BrokerOptions-EncryptionRemoteTrustStore">encryption_remote_trust_store</link>
                 option. Such a connection URL might look somthing like:
             </para>
-            <programlisting>amqp://username:password@clientid/test?brokerlist='tcp://localhost:5672?encryption_remote_trust_store='$certificates%5c/certstore''</programlisting>
-
+            <programlisting>amqp://username:password@clientid/test?brokerlist='tcp://localhost:5672?encryption_remote_trust_store='$certificates%255c/certstore''</programlisting>
+            <para>
+                The <literal>$certificates/</literal> prefix is mandatory.
+                However, in order to prevent the client from interpreting this the wrong way several layers of escaping and encoding need to take place.
+                The slash character ('/') needs to be escaped by a backslash ('\') which needs to be doubly URL encoded resulting in <literal>$certificates%255c/</literal>.
+            </para>
+            <para>
+                Note that to use the broker-distributed certificates the broker must be configured to expose the trust store as a message source.
+                See the broker documentation on TrustStores for more details.
+            </para>
         </section>
         <section xml:id="JMS-Client-Message-Encryption-Sending-Enabling-Encryption">
             <title>Enabling Encryption</title>
@@ -107,7 +115,7 @@
             <para>
                 In order to encrypt all messages sent to a given Destination, the option
                 <link linkend="JMS-Client-0-8-Binding-URL-Options-SendEncrypted">sendencrypted</link> can be used.  Note
-                that enabling encryption on the address can be overridden by explicitly seting the property
+                that enabling encryption on the address can be overridden by explicitly setting the property
                 <literal>x-qpid-encrypt</literal> to false on an individual message. An example address would look like:
             </para>
             <programlisting>direct:///queue/queue?sendencrypted='true'</programlisting>
@@ -170,4 +178,216 @@
 
         </section>
     </section>
+    <section  xml:id="JMS-Client-Message-Encryption-Example">
+        <title>Message Encryption Example</title>
+        <section xml:id="JMS-Client-Message-Encryption-Example-Introduction">
+            <title>Introduction</title>
+            <para>
+                In this example we will setup the Qpid Broker for Java and two clients who will send each other encrypted messages.
+                The clients will use self signed certificates and the certificates will be distributed by the Broker.
+            </para>
+        </section>
+        <section xml:id="JMS-Client-Message-Encryption-Example-Prerequisites">
+            <title>Prerequisites</title>
+            <para>
+                For this example it is assumed the Broker is already running and that Management is enabled on port
+                8443.
+            </para>
+            <para>
+                The example requires two (one for each client) self-signed X.509 certificates and the corresponding
+                keys. We refer to these as
+                <literal>client_1/2.cert</literal>
+                and
+                <literal>client_1/2.key</literal>
+                throughout the text below.
+            </para>
+            <para>
+                The following
+                <link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="https://www.openssl.org">openssl</link>
+                commands can be used to generate self signed certicates suitable for this test.
+                <programlisting>
+<![CDATA[openssl req -x509 -newkey rsa:4096 -keyout client_1.key -out client_1.cert -days 365 -nodes -subj "/C=US/O=Apache/OU=Qpid/CN=client1"
+openssl req -x509 -newkey rsa:4096 -keyout client_2.key -out client_2.cert -days 365 -nodes -subj "/C=US/O=Apache/OU=Qpid/CN=client2"]]>
+                </programlisting>
+            </para>
+        </section>
+        <section xml:id="JMS-Client-Message-Encryption-Example-Broker-Config">
+            <title>Broker Configuration</title>
+            <para>
+                In this example we want the broker to distribute the client certificates.
+                Essentially, we want the broker to act as a<link xmlns:xlink="http://www.w3.org/1999/xlink"
+                                                                 xlink:href="https://en.wikipedia.org/wiki/Key_server_(cryptographic)">
+                Key Server</link>.
+                Use
+                <link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="${oracleKeytool}">java's keytool</link>
+                to create a trust store containing the two client certificates.
+                <programlisting>
+<![CDATA[keytool -importcert -file client_1.cert -alias client1 -keystore mytruststore.jks
+keytool -importcert -file client_2.cert -alias client2 -keystore mytruststore.jks]]>
+                </programlisting>
+                Now a FileTrustStore can be created on the broker pointing to the java trust store that was just
+                created.
+                This can be done via the Web Management Console or the REST API:
+                <programlisting>curl -v -u admin https://localhost:8443/api/v6.1/truststore/clientcerts -X PUT -d
+                    '{"type": "FileTrustStore", "stroeUrl": "&lt;path_to_truststore&gt;", "password": "&lt;your_truststore_password&gt;"}'
+                </programlisting>
+                The TrustStore must be configured to expose the certificates as a message source to the clients:
+                <programlisting>curl -v -u admin https://localhost:8443/api/v6.1/truststore/clientcerts -X POST -d
+                    '{"exposedAsMessageSource": true}'
+                </programlisting>
+            </para>
+        </section>
+        <section xml:id="JMS-Client-Message-Encryption-Example-Client-Config">
+            <title>Client Configuration</title>
+            <para>
+                The configuration for the clients happens in the connection URL. In this example this is provided via a
+                JNDI properties file.
+            </para>
+            <para>
+                On the producing side, in order to encrypt a message for a recipient, the Qpid client needs the
+                recipient's public certificate which is distributed by the Broker following our above broker setup. The
+                <literal>encryption_remote_trust_store</literal>
+                element within the connection URL provides the name of the truststore.
+            </para>
+            <para>
+                On the receiving side, in order to decrypt a message it needs a JKS keystore with the private key
+                matching the public certificate.
+                For this example, the keystores can again be created with a two-step process involving
+                <link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="https://www.openssl.org">openssl</link>
+                and <link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="${oracleKeytool}">java's keytool</link>.
+                <programlisting>
+<![CDATA[openssl pkcs12 -export -in client_1.cert -inkey client_1.key -out client_1.pkcs12 -name "client1"
+openssl pkcs12 -export -in client_2.cert -inkey client_2.key -out client_2.pkcs12 -name "client2"
+
+keytool -importkeystore -destkeystore client_1.jks -srckeystore client_1.pkcs12 -srcstoretype PKCS12
+keytool -importkeystore -destkeystore client_2.jks -srckeystore client_2.pkcs12 -srcstoretype PKCS12]]>
+                </programlisting>
+
+            </para>
+            <para>
+                The final JNDI properties file should look similar to this:
+                <programlisting>
+java.naming.factory.initial = org.apache.qpid.jndi.PropertiesFileInitialContextFactory
+
+# connection factories. This is where end-to-end encryption is configured on the client.
+# connectionfactory.[jndiname] = [ConnectionURL]
+connectionfactory.producerConnectionFactory = amqp://&lt;username&gt;:&lt;password&gt;@?brokerlist='tcp://localhost:5672?encryption_remote_trust_store='$certificates%255c/clientcerts''
+connectionfactory.consumer1ConnectionFactory = amqp://&lt;username&gt;:&lt;password&gt;@?brokerlist='tcp://localhost:5672?encryption_key_store='path/to/client_1.jks'&amp;encryption_key_store_password='&lt;keystore_password&gt;''
+connectionfactory.consumer2ConnectionFactory = amqp://&lt;username&gt;:&lt;password&gt;@?brokerlist='tcp://localhost:5672?encryption_key_store='path/to/client_2.jks'&amp;encryption_key_store_password='&lt;keystore_password&gt;''
+
+# Rest of JNDI configuration. For example
+# destination.[jniName] = [Address Format]
+queue.myTestQueue = testQueue
+                </programlisting>
+            </para>
+        </section>
+        <section xml:id="JMS-Client-Message-Encryption-Example-Application">
+            <title>Application Code</title>
+            <para>
+                On the producing side, the application needs to enable encryption and indicate the intended recipient(s)
+                of each message. This is done via the
+                <literal>x-qpid-encrypt</literal>
+                and
+                <literal>x-qpid-encrypt-recipients</literal>
+                message properties. Note that the order of the relative distinguished name (RDN) entries within the
+                recipent's distinguished name (DNs) is significant. If the order does not match that recorded in
+                truststore, a
+                <link linkend="JMS-Client-0-8-Appendix-Exceptions-CertificateException">CertificateException</link>
+                will be encountered.
+            </para>
+            <para>
+                On the receiving side, there is nothing to do.  The application code does not have to add decryption code as this is handled transparently by the Qpid client library.
+                However, the receiving application should gracefully handle failures in decryption in which case the encrypted message will be delivered as a BytesMessage.
+                <programlisting language="java">
+// imports omitted for brevity
+
+public class EncryptionExample {
+    public EncryptionExample() {
+    }
+
+    public static void main(String[] args) throws Exception {
+        EncryptionExample encryptionExampleApp = new EncryptionExample();
+        encryptionExampleApp.runProducerExample();
+        encryptionExampleApp.runReceiverExample();
+    }
+
+    private void runProducerExample() throws Exception
+    {
+        Connection connection = createConnection("producerConnectionFactory");
+        try {
+            Session session = connection.createSession(true, Session.SESSION_TRANSACTED);
+            Destination destination = createDesination("myTestQueue");
+
+            MessageProducer messageProducer = session.createProducer(destination);
+            TextMessage message = session.createTextMessage("Hello world!");
+
+            // ============== Enable encryption for this message ==============
+            message.setBooleanProperty("x-qpid-encrypt", true);
+            // ============== Configure recipients for encryption ==============
+            message.setStringProperty("x-qpid-encrypt-recipients", "CN=client1, OU=Qpid, O=Apache, C=US");
+
+            messageProducer.send(message);
+            session.commit();
+        }
+        finally {
+            connection.close();
+        }
+    }
+
+    private void runReceiverExample() throws Exception
+    {
+        Connection connection = createConnection("consumer1ConnectionFactory");
+        try {
+            connection.start();
+            Session session = connection.createSession(true, Session.SESSION_TRANSACTED);
+            Destination destination = createDesination("myTestQueue");
+            MessageConsumer messageConsumer = session.createConsumer(destination);
+            Message message = messageConsumer.receive();
+            if (message instanceof TextMessage) {
+                // application logic
+                System.out.println(((TextMessage) message).getText());
+            } else if (message instanceof BytesMessage) {
+                // handle potential decryption failure
+                System.out.println("Potential decryption problem. Application not in list of intended recipients?");
+            }
+            session.commit();
+        }
+        finally {
+            connection.close();
+        }
+    }
+
+    ///////////////////////////////////////
+    // The following is boilerplate code //
+    ///////////////////////////////////////
+
+    private Connection createConnection(final String connectionFactoryName) throws JMSException, IOException, NamingException
+    {
+        try (InputStream resourceAsStream = this.getClass().getResourceAsStream("example.properties")) {
+            Properties properties = new Properties();
+            properties.load(resourceAsStream);
+            Context context = new InitialContext(properties);
+            ConnectionFactory connectionFactory = (ConnectionFactory) context.lookup(connectionFactoryName);
+            final Connection connection = connectionFactory.createConnection();
+            context.close();
+            return connection;
+        }
+    }
+
+    private Destination createDesination(String desinationJndiName) throws IOException, NamingException
+    {
+        try (InputStream resourceAsStream = this.getClass().getResourceAsStream("example.properties")) {
+            Properties properties = new Properties();
+            properties.load(resourceAsStream);
+            Context context = new InitialContext(properties);
+            Destination destination = (Destination) context.lookup(desinationJndiName);
+            context.close();
+            return destination;
+        }
+    }
+}
+                </programlisting>
+            </para>
+        </section>
+    </section>
 </chapter>



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org