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 '<recipient>'</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": "<path_to_truststore>", "password": "<your_truststore_password>"}'
+ </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://<username>:<password>@?brokerlist='tcp://localhost:5672?encryption_remote_trust_store='$certificates%255c/clientcerts''
+connectionfactory.consumer1ConnectionFactory = amqp://<username>:<password>@?brokerlist='tcp://localhost:5672?encryption_key_store='path/to/client_1.jks'&encryption_key_store_password='<keystore_password>''
+connectionfactory.consumer2ConnectionFactory = amqp://<username>:<password>@?brokerlist='tcp://localhost:5672?encryption_key_store='path/to/client_2.jks'&encryption_key_store_password='<keystore_password>''
+
+# 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