summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Godfrey <rgodfrey@apache.org>2014-08-25 15:25:00 +0000
committerRobert Godfrey <rgodfrey@apache.org>2014-08-25 15:25:00 +0000
commit19478e74524f27e26f01117b1b973829718ed44d (patch)
tree214cee6e0e1fb25a553aaaa490b775450ea9e8e2
parente0e8f4c5087c1c5dc787740d6bd862755bd8daf1 (diff)
downloadqpid-python-19478e74524f27e26f01117b1b973829718ed44d.tar.gz
Merging from trunk r1618230:1618433 in the Java tree
git-svn-id: https://svn.apache.org/repos/asf/qpid/branches/0.30@1620344 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--qpid/java/bdbstore/src/main/java/resources/js/qpid/management/virtualhost/bdb_ha/edit.js18
-rw-r--r--qpid/java/bdbstore/src/main/java/resources/js/qpid/management/virtualhost/bdb_ha/show.js4
-rw-r--r--qpid/java/bdbstore/src/main/java/resources/virtualhost/bdb_ha/edit.html59
-rw-r--r--qpid/java/bdbstore/src/main/java/resources/virtualhostnode/bdb/add.html3
-rw-r--r--qpid/java/bdbstore/src/main/java/resources/virtualhostnode/bdb_ha/add.html4
-rw-r--r--qpid/java/bdbstore/src/main/java/resources/virtualhostnode/bdb_ha/add/existinggroup/add.html19
-rw-r--r--qpid/java/bdbstore/src/main/java/resources/virtualhostnode/bdb_ha/add/newgroup/add.html18
-rw-r--r--qpid/java/bdbstore/src/main/java/resources/virtualhostnode/bdb_ha/edit.html21
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/consumer/ConsumerTarget.java2
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/AbstractConfiguredObject.java25
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/Broker.java12
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/ConfiguredAutomatedAttribute.java76
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/Connection.java1
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/ManagedAttribute.java1
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/Protocol.java2
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java8
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/AmqpPort.java12
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/AmqpPortImpl.java89
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/HttpPort.java12
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/JmxPort.java12
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/RmiPort.java56
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/RmiPortImpl.java82
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/queue/QueueConsumerImpl.java5
-rw-r--r--qpid/java/broker-core/src/test/java/org/apache/qpid/server/consumer/MockConsumer.java4
-rw-r--r--qpid/java/broker-core/src/test/java/org/apache/qpid/server/model/ConfigureObjectTypeRegistryTest.java37
-rw-r--r--qpid/java/broker-core/src/test/java/org/apache/qpid/server/model/testmodel/Test2RootCategory.java5
-rw-r--r--qpid/java/broker-core/src/test/java/org/apache/qpid/server/model/testmodel/Test2RootCategoryImpl.java16
-rw-r--r--qpid/java/broker-core/src/test/java/org/apache/qpid/server/model/testmodel/TestChildCategory.java35
-rw-r--r--qpid/java/broker-core/src/test/java/org/apache/qpid/server/model/testmodel/TestChildCategoryImpl.java60
-rw-r--r--qpid/java/broker-core/src/test/java/org/apache/qpid/server/model/testmodel/TestModel.java11
-rw-r--r--qpid/java/broker-core/src/test/java/org/apache/qpid/server/model/testmodel/TestRootCategory.java6
-rw-r--r--qpid/java/broker-core/src/test/java/org/apache/qpid/server/model/testmodel/TestRootCategoryImpl.java10
-rw-r--r--qpid/java/broker-core/src/test/java/org/apache/qpid/server/queue/StandardQueueTest.java5
-rw-r--r--qpid/java/broker-plugins/amqp-0-10-protocol/src/main/java/org/apache/qpid/server/protocol/v0_10/ConsumerTarget_0_10.java45
-rw-r--r--qpid/java/broker-plugins/amqp-0-10-protocol/src/main/java/org/apache/qpid/server/protocol/v0_10/ServerConnection.java20
-rw-r--r--qpid/java/broker-plugins/amqp-0-10-protocol/src/main/java/org/apache/qpid/server/protocol/v0_10/ServerConnectionDelegate.java18
-rw-r--r--qpid/java/broker-plugins/amqp-0-8-protocol/src/main/java/org/apache/qpid/server/protocol/v0_8/AMQProtocolEngine.java47
-rw-r--r--qpid/java/broker-plugins/amqp-0-8-protocol/src/main/java/org/apache/qpid/server/protocol/v0_8/AMQProtocolSession.java8
-rw-r--r--qpid/java/broker-plugins/amqp-0-8-protocol/src/main/java/org/apache/qpid/server/protocol/v0_8/ClientDeliveryMethod.java2
-rw-r--r--qpid/java/broker-plugins/amqp-0-8-protocol/src/main/java/org/apache/qpid/server/protocol/v0_8/ConsumerTarget_0_8.java22
-rw-r--r--qpid/java/broker-plugins/amqp-0-8-protocol/src/main/java/org/apache/qpid/server/protocol/v0_8/handler/BasicGetMethodHandler.java21
-rw-r--r--qpid/java/broker-plugins/amqp-0-8-protocol/src/main/java/org/apache/qpid/server/protocol/v0_8/output/ProtocolOutputConverter.java6
-rw-r--r--qpid/java/broker-plugins/amqp-0-8-protocol/src/main/java/org/apache/qpid/server/protocol/v0_8/output/ProtocolOutputConverterImpl.java121
-rw-r--r--qpid/java/broker-plugins/amqp-0-8-protocol/src/test/java/org/apache/qpid/server/protocol/v0_8/InternalTestProtocolSession.java13
-rw-r--r--qpid/java/broker-plugins/amqp-1-0-protocol/src/main/java/org/apache/qpid/server/protocol/v1_0/ConsumerTarget_1_0.java4
-rw-r--r--qpid/java/broker-plugins/amqp-1-0-protocol/src/main/java/org/apache/qpid/server/protocol/v1_0/MessageConverter_to_1_0.java24
-rwxr-xr-xqpid/java/broker-plugins/amqp-1-0-protocol/src/main/java/org/apache/qpid/server/protocol/v1_0/MessageMetaData_1_0.java11
-rw-r--r--qpid/java/broker-plugins/derby-store/src/main/java/resources/js/qpid/management/virtualhost/derby/edit.js4
-rw-r--r--qpid/java/broker-plugins/derby-store/src/main/java/resources/virtualhostnode/derby/add.html3
-rw-r--r--qpid/java/broker-plugins/jdbc-store/src/main/java/resources/virtualhostnode/jdbc/add.html10
-rw-r--r--qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/MessageServlet.java7
-rw-r--r--qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/MetaDataServlet.java17
-rw-r--r--qpid/java/broker-plugins/management-http/src/main/java/resources/addBinding.html2
-rw-r--r--qpid/java/broker-plugins/management-http/src/main/java/resources/addExchange.html71
-rw-r--r--qpid/java/broker-plugins/management-http/src/main/java/resources/addPort.html303
-rw-r--r--qpid/java/broker-plugins/management-http/src/main/java/resources/addQueue.html446
-rw-r--r--qpid/java/broker-plugins/management-http/src/main/java/resources/addVirtualHostNodeAndVirtualHost.html6
-rw-r--r--qpid/java/broker-plugins/management-http/src/main/java/resources/css/common.css20
-rw-r--r--qpid/java/broker-plugins/management-http/src/main/java/resources/editVirtualHost.html175
-rw-r--r--qpid/java/broker-plugins/management-http/src/main/java/resources/index.html2
-rw-r--r--qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/metadata.js57
-rw-r--r--qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/util.js45
-rw-r--r--qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/widgetconfigurer.js97
-rw-r--r--qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/Broker.js20
-rw-r--r--qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/KeyStore.js1
-rw-r--r--qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/addAccessControlProvider.js4
-rw-r--r--qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/addBinding.js8
-rw-r--r--qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/addGroupProvider.js4
-rw-r--r--qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/addKeystore.js29
-rw-r--r--qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/addPort.js76
-rw-r--r--qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/addQueue.js12
-rw-r--r--qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/addVirtualHostNodeAndVirtualHost.js62
-rw-r--r--qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/editVirtualHost.js3
-rw-r--r--qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/editVirtualHostNode.js2
-rw-r--r--qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/plugin/managementhttp.js4
-rw-r--r--qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/plugin/managementjmx.js4
-rw-r--r--qpid/java/broker-plugins/management-http/src/main/java/resources/strings.html21
-rw-r--r--qpid/java/broker-plugins/management-http/src/main/java/resources/virtualhost/providedstore/add.html6
-rw-r--r--qpid/java/broker-plugins/management-http/src/main/java/resources/virtualhost/providedstore/edit.html6
-rw-r--r--qpid/java/broker-plugins/management-http/src/main/java/resources/virtualhost/sizemonitoring/add.html9
-rw-r--r--qpid/java/broker-plugins/management-http/src/main/java/resources/virtualhost/sizemonitoring/edit.html7
-rw-r--r--qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagementPluginImpl.java1
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnection.java118
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate.java11
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate_0_10.java34
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate_8_0.java40
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageProducer_0_10.java43
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageProducer_0_8.java16
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/handler/CloseWhenNoRouteSettingsHelper.java5
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionStartMethodHandler.java18
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/message/AbstractJMSMessageFactory.java168
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/jms/ConnectionURL.java5
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/configuration/ClientProperties.java13
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/framing/BasicContentHeaderProperties.java48
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/framing/FieldTable.java14
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/properties/ConnectionStartProperties.java3
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/transport/Connection.java8
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/util/ByteBufferInputStream.java5
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/util/GZIPUtils.java119
-rw-r--r--qpid/java/common/src/test/java/org/apache/qpid/util/GZIPUtilsTest.java102
-rw-r--r--qpid/java/pom.xml1
-rw-r--r--qpid/java/systests/src/test/java/org/apache/qpid/systest/MessageCompressionTest.java236
102 files changed, 2812 insertions, 831 deletions
diff --git a/qpid/java/bdbstore/src/main/java/resources/js/qpid/management/virtualhost/bdb_ha/edit.js b/qpid/java/bdbstore/src/main/java/resources/js/qpid/management/virtualhost/bdb_ha/edit.js
index 087caf34c6..ed34bbbd7a 100644
--- a/qpid/java/bdbstore/src/main/java/resources/js/qpid/management/virtualhost/bdb_ha/edit.js
+++ b/qpid/java/bdbstore/src/main/java/resources/js/qpid/management/virtualhost/bdb_ha/edit.js
@@ -16,10 +16,11 @@
* specific language governing permissions and limitations
* under the License.
*/
-define(["qpid/common/util", "dijit/registry", "dojo/_base/window", "dojo/domReady!"],
- function (util, registry, win)
+define(["qpid/common/util", "qpid/common/metadata", "dijit/registry", "dojo/_base/window", "dojo/domReady!"],
+ function (util, metadata, registry, win)
{
- var fieldNames = ["storeUnderfullSize", "storeOverfullSize"];
+ var fieldNames = ["storeUnderfullSize", "storeOverfullSize",
+ "localTransactionSynchronizationPolicy", "remoteTransactionSynchronizationPolicy"];
return {
show: function(data)
{
@@ -28,17 +29,6 @@ define(["qpid/common/util", "dijit/registry", "dojo/_base/window", "dojo/domRead
registry.byId("editVirtualHost.storeUnderfullSize").set("regExpGen", util.numericOrContextVarRegexp);
registry.byId("editVirtualHost.storeOverfullSize").set("regExpGen", util.numericOrContextVarRegexp);
- var widget = registry.byId("editVirtualHost.localTransactionSynchronizationPolicy-" + data.data["localTransactionSynchronizationPolicy"]);
- if (widget)
- {
- widget.set("checked", true);
- }
- widget = registry.byId("editVirtualHost.remoteTransactionSynchronizationPolicy-" + data.data["remoteTransactionSynchronizationPolicy"]);
- if (widget)
- {
- widget.set("checked", true);
- }
-
var that = this;
this.permittedNodes = registry.byId("editVirtualHost.permittedNodes");
this.permittedNodesList = registry.byId("editVirtualHost.permittedNodesList");
diff --git a/qpid/java/bdbstore/src/main/java/resources/js/qpid/management/virtualhost/bdb_ha/show.js b/qpid/java/bdbstore/src/main/java/resources/js/qpid/management/virtualhost/bdb_ha/show.js
index 9cf6bdea66..f211d19d16 100644
--- a/qpid/java/bdbstore/src/main/java/resources/js/qpid/management/virtualhost/bdb_ha/show.js
+++ b/qpid/java/bdbstore/src/main/java/resources/js/qpid/management/virtualhost/bdb_ha/show.js
@@ -47,8 +47,8 @@ define(["qpid/common/util", "dojo/query", "dojo/domReady!"],
}
this["permittedNodes"].innerHTML = permittedNodesMarkup ;
- var localSyncPolicy = data[localTransactionSynchronizationPolicy].toLowerCase();
- var remoteSyncPolicy = data[remoteTransactionSynchronizationPolicy].toLowerCase();
+ var localSyncPolicy = data[localTransactionSynchronizationPolicy] ? data[localTransactionSynchronizationPolicy].toLowerCase() : "";
+ var remoteSyncPolicy = data[remoteTransactionSynchronizationPolicy] ? data[remoteTransactionSynchronizationPolicy].toLowerCase() : "";
for(var i=0; i<this[localTransactionSynchronizationPolicy].children.length;i++)
{
diff --git a/qpid/java/bdbstore/src/main/java/resources/virtualhost/bdb_ha/edit.html b/qpid/java/bdbstore/src/main/java/resources/virtualhost/bdb_ha/edit.html
index cad6b9301e..9d0b0ab860 100644
--- a/qpid/java/bdbstore/src/main/java/resources/virtualhost/bdb_ha/edit.html
+++ b/qpid/java/bdbstore/src/main/java/resources/virtualhost/bdb_ha/edit.html
@@ -27,7 +27,8 @@
name: 'storeOverfullSize',
placeHolder: 'size in bytes',
required: false,
- title: 'Enter ceiling (in bytes) at which store will begin to throttle sessions producing messages'"/>
+ title: 'Enter ceiling (in bytes) at which store will begin to throttle sessions producing messages',
+ promptMessage: 'Ceiling (in bytes) at which store will begin to throttle sessions producing messages'"/>
</div>
</div>
<div class="clear">
@@ -39,7 +40,8 @@
name: 'storeUnderfullSize',
placeHolder: 'size in bytes',
required: false,
- title: 'Enter floor (in bytes) at which store will cease to throttle sessions producing messages'"/>
+ title: 'Enter floor (in bytes) at which store will cease to throttle sessions producing messages',
+ promptMessage: 'Floor (in bytes) at which store will cease to throttle sessions producing messages'"/>
</div>
</div>
@@ -74,8 +76,9 @@
data-dojo-props="
name: 'permittedNode',
placeHolder: 'host:port',
- title: 'Enter address',
- intermediateChanges: true" />
+ intermediateChanges: true,
+ title: 'Enter address of node to be permitted into the group',
+ promptMessage: 'Address of node to be permitted into the group'" />
</div>
<button data-dojo-type="dijit/form/Button" id="editVirtualHost.permittedNodeAdd" data-dojo-props="label: '+'"></button>
</div>
@@ -86,42 +89,30 @@
<div class="formBox clear">
<fieldset>
- <legend>High availability durability</legend>
- <div>
- <div class="haOptionLabel">Master transaction sync policy</div>
+ <legend>High availability durability</legend>
<div>
- <input data-dojo-type="dijit/form/RadioButton" type="radio" name="localTransactionSynchronizationPolicy" value="SYNC" id="editVirtualHost.localTransactionSynchronizationPolicy-SYNC"/>
- <label>SYNC (the transaction will be written and synchronized to the disk; highest durability)</label>
- </div>
-
- <div>
- <input data-dojo-type="dijit/form/RadioButton" type="radio" name="localTransactionSynchronizationPolicy" value="WRITE_NO_SYNC" id="editVirtualHost.localTransactionSynchronizationPolicy-WRITE_NO_SYNC"/>
- <label>WRITE_NO_SYNC (the transaction will be written only; the synchronization will be performed later)</label>
- </div>
+ <div class="haOptionLabel">Master transaction sync policy</div>
- <div>
- <input data-dojo-type="dijit/form/RadioButton" type="radio" name="localTransactionSynchronizationPolicy" value="NO_SYNC" id="editVirtualHost.localTransactionSynchronizationPolicy-NO_SYNC"/>
- <label>NO_SYNC (write later; the transaction will be written and synchronized later; lowest durability)</label>
- </div>
- </div>
- <br/>
- <div>
- <div class="haOptionLabel">Replica transaction sync policy</div>
- <div>
- <input data-dojo-type="dijit/form/RadioButton" type="radio" name="remoteTransactionSynchronizationPolicy" value="SYNC" id="editVirtualHost.remoteTransactionSynchronizationPolicy-SYNC"/>
- <label>SYNC (the transaction will be written and synchronized to the disk; highest durability)</label>
+ <select id="editVirtualHost.localTransactionSynchronizationPolicy"
+ name="localTransactionSynchronizationPolicy"
+ data-dojo-type="dojox/form/CheckedMultiSelect">
+ <option value="SYNC">SYNC (the transaction will be written and synchronized to the disk; highest durability)</option>
+ <option value="WRITE_NO_SYNC">WRITE_NO_SYNC (the transaction will be written only; the synchronization will be performed later)</option>
+ <option value="NO_SYNC">NO_SYNC (write later; the transaction will be written and synchronized later; lowest durability)</option>
+ </select>
</div>
-
+ <br/>
<div>
- <input data-dojo-type="dijit/form/RadioButton" type="radio" name="remoteTransactionSynchronizationPolicy" value="WRITE_NO_SYNC" id="editVirtualHost.remoteTransactionSynchronizationPolicy-WRITE_NO_SYNC"/>
- <label>WRITE_NO_SYNC (the transaction will be written only; the synchronization will be performed later)</label>
- </div>
+ <div class="haOptionLabel">Replica transaction sync policy</div>
- <div>
- <input data-dojo-type="dijit/form/RadioButton" type="radio" name="remoteTransactionSynchronizationPolicy" value="NO_SYNC" id="editVirtualHost.remoteTransactionSynchronizationPolicy-NO_SYNC"/>
- <label>NO_SYNC (write later; the transaction will be written and synchronized later; lowest durability)</label>
+ <select id="editVirtualHost.remoteTransactionSynchronizationPolicy"
+ name="remoteTransactionSynchronizationPolicy"
+ data-dojo-type="dojox/form/CheckedMultiSelect">
+ <option value="SYNC">SYNC (the transaction will be written and synchronized to the disk; highest durability)</option>
+ <option value="WRITE_NO_SYNC">WRITE_NO_SYNC (the transaction will be written only; the synchronization will be performed later)</option>
+ <option value="NO_SYNC">NO_SYNC (write later; the transaction will be written and synchronized later; lowest durability)</option>
+ </select>
</div>
- </div>
</fieldset>
</div>
diff --git a/qpid/java/bdbstore/src/main/java/resources/virtualhostnode/bdb/add.html b/qpid/java/bdbstore/src/main/java/resources/virtualhostnode/bdb/add.html
index 9ce23084c5..c16dd675d2 100644
--- a/qpid/java/bdbstore/src/main/java/resources/virtualhostnode/bdb/add.html
+++ b/qpid/java/bdbstore/src/main/java/resources/virtualhostnode/bdb/add.html
@@ -27,7 +27,8 @@
data-dojo-props="
name: 'storePath',
placeHolder: 'path/to/store',
- title: 'Enter store path'" />
+ title: 'Enter store path',
+ promptMessage: 'File system location for the configuration store.'"/>
</div>
</div>
diff --git a/qpid/java/bdbstore/src/main/java/resources/virtualhostnode/bdb_ha/add.html b/qpid/java/bdbstore/src/main/java/resources/virtualhostnode/bdb_ha/add.html
index c7e44a38b2..6973cf9002 100644
--- a/qpid/java/bdbstore/src/main/java/resources/virtualhostnode/bdb_ha/add.html
+++ b/qpid/java/bdbstore/src/main/java/resources/virtualhostnode/bdb_ha/add.html
@@ -31,7 +31,9 @@
data-dojo-props="store:groupStore,
searchAttr:'name',
required: true,
- placeHolder: 'choose new or existing'"
+ placeHolder: 'choose new or existing',
+ promptMessage: 'Create a new group or join to an existing one',
+ title: 'Choose whether to create a new group or join to an existing one'"
name="group"
id="addVirtualHostNode.group" />
</div>
diff --git a/qpid/java/bdbstore/src/main/java/resources/virtualhostnode/bdb_ha/add/existinggroup/add.html b/qpid/java/bdbstore/src/main/java/resources/virtualhostnode/bdb_ha/add/existinggroup/add.html
index 820a94e754..d8f1ae5c57 100644
--- a/qpid/java/bdbstore/src/main/java/resources/virtualhostnode/bdb_ha/add/existinggroup/add.html
+++ b/qpid/java/bdbstore/src/main/java/resources/virtualhostnode/bdb_ha/add/existinggroup/add.html
@@ -30,8 +30,8 @@
name: 'groupName',
placeHolder: 'group name',
required: true,
- missingMessage: 'The group name must be supplied',
- title: 'Enter the group name'" />
+ promptMessage: 'Name of the existing group',
+ title: 'Enter name of the existing group'," />
</div>
</div>
<div class="clear">
@@ -43,8 +43,8 @@
name: 'helperNodeName',
placeHolder: 'node name from group',
required: true,
- missingMessage: 'A node name must be supplied',
- title: 'Enter a node name'" />
+ promptMessage: 'Node name of an existing group member.',
+ title: 'Enter node name of an existing member of the group'" />
</div>
</div>
<div class="clear">
@@ -56,8 +56,8 @@
name: 'helperAddress',
placeHolder: 'node address from group',
required: true,
- missingMessage: 'Node host and port must be supplied',
- title: 'Enter address'" />
+ promptMessage: 'Node address of the existing group member.',
+ title: 'Enter node address of the existing group member'" />
</div>
</div>
</fieldset>
@@ -76,8 +76,8 @@
name: 'address',
placeHolder: 'host:port',
required: true,
- missingMessage: 'Node host and port must be supplied',
- title: 'Enter address'" />
+ promptMessage: 'Node hostname and port number that new node will use.<br/>Other nodes will use connect to this address to replicate messages',
+ title: 'Enter node hostname and port number that new node will use'" />
</div>
</div>
<div class="clear">
@@ -88,7 +88,8 @@
data-dojo-props="
name: 'storePath',
placeHolder: 'path/to/store',
- title: 'Enter store path'" />
+ promptMessage: 'File system location for the store',
+ title: 'Enter file system location for the store'" />
</div>
</div>
</fieldset>
diff --git a/qpid/java/bdbstore/src/main/java/resources/virtualhostnode/bdb_ha/add/newgroup/add.html b/qpid/java/bdbstore/src/main/java/resources/virtualhostnode/bdb_ha/add/newgroup/add.html
index 1d3b2a1906..c25bae3419 100644
--- a/qpid/java/bdbstore/src/main/java/resources/virtualhostnode/bdb_ha/add/newgroup/add.html
+++ b/qpid/java/bdbstore/src/main/java/resources/virtualhostnode/bdb_ha/add/newgroup/add.html
@@ -27,8 +27,8 @@
name: 'groupName',
placeHolder: 'group name',
required: true,
- missingMessage: 'A group name must be supplied',
- title: 'Enter a group name'" />
+ title: 'Enter name to identify the new group',
+ promptMessage: 'Name to identify the new group.'"/>
</div>
</div>
<div class="clear">
@@ -40,8 +40,8 @@
name: 'address',
placeHolder: 'host:port',
required: true,
- missingMessage: 'Node host and port must be supplied',
- title: 'Enter address'" />
+ title: 'Enter node hostname and port number that new node will use',
+ promptMessage: 'Node hostname and port number that new node will use.<br/>Other nodes will use connect to this address to replicate messages'" />
</div>
</div>
<div class="clear">
@@ -52,7 +52,8 @@
data-dojo-props="
name: 'storePath',
placeHolder: 'path/to/store',
- title: 'Enter store path'" />
+ title: 'Enter file system location for the store',
+ promptMessage: 'File system location for the store'" />
</div>
</div>
<div class="clear formBox">
@@ -66,7 +67,7 @@
data-dojo-props="
name: 'permittedNodesList',
readOnly : 'true',
- title: 'Enter permitted nodes'">
+ title: 'Enter list of the other node address that will form the group'">
</select> <!-- must use closing tag rather than shorthand - dojo bug? -->
</div>
<button data-dojo-type="dijit/form/Button" id="addVirtualHostNode.permittedNodeRemove" data-dojo-props="label: '-'" ></button>
@@ -81,8 +82,9 @@
data-dojo-props="
name: 'permittedNode',
placeHolder: 'host:port',
- title: 'Enter address',
- intermediateChanges: true" />
+ intermediateChanges: true,
+ title: 'Enter address of node to be permitted into the group',
+ promptMessage: 'Address of node to be permitted into the group'" />
</div>
<button data-dojo-type="dijit/form/Button" id="addVirtualHostNode.permittedNodeAdd" data-dojo-props="label: '+'"></button>
</div>
diff --git a/qpid/java/bdbstore/src/main/java/resources/virtualhostnode/bdb_ha/edit.html b/qpid/java/bdbstore/src/main/java/resources/virtualhostnode/bdb_ha/edit.html
index 189eb6f7b6..f163390fa2 100644
--- a/qpid/java/bdbstore/src/main/java/resources/virtualhostnode/bdb_ha/edit.html
+++ b/qpid/java/bdbstore/src/main/java/resources/virtualhostnode/bdb_ha/edit.html
@@ -25,8 +25,7 @@
placeHolder: 'Group Name',
required: true,
disabled: true,
- missingMessage: 'A group name must be supplied',
- title: 'Enter group name'" />
+ title: 'Name of the group'" />
</div>
</div>
<div class="clear">
@@ -39,9 +38,7 @@
placeHolder: 'host:port',
required: true,
disabled: true,
- missingMessage: 'A Host and Port must be supplied',
- invalidMessage: 'Must be of the form host:port',
- title: 'Enter Host and Port name'" />
+ title: 'Node address of the group member'" />
</div>
</div>
<div class="clear">
@@ -51,8 +48,9 @@
data-dojo-type="dijit/form/ValidationTextBox"
data-dojo-props="
name: 'storePath',
- placeHolder: 'path/to/store',
- title: 'Enter configuration store path'" />
+ title: 'File system location for the store',
+ promptMessage: 'File system location for the store'" />
+
</div>
</div>
<div class="clear">
@@ -63,7 +61,8 @@
data-dojo-props="
name: 'designatedPrimary',
required: false,
- title: 'Designate node as primary. It is applicable only to 2-nodes cluster'" />
+ title: 'Designate node as primary allowing it to operate solo in a group of two.',
+ promptMessage: 'Designate node as primary allowing it to operate solo operate solo in a group of two'" />
</div>
</div>
<div class="clear">
@@ -80,8 +79,9 @@
data-dojo-props="
name: 'priority',
required: false,
- title: 'Select node priority for election as a Master',
store: nodePriorityStore,
+ title: 'Set the election priority associated with this node',
+ promptMessage: 'Election priority associated with this node.<br/>Elections will choose the node with the most recent transactions.<br/>If there is a tie, priority is used as a tie-breaker.',
searchAttr: 'name'" />
</div>
</div>
@@ -95,7 +95,8 @@
data-dojo-props="
name: 'quorumOverride',
required: false,
- title: 'Enter quorum override. 0 signifies simple majority',
+ title: 'Select minimum required number of nodes or choose Majority',
+ promptMessage: 'Modifies the minimum number of nodes required to be present to elect a master or commit transactions.<br/>Majority signifies that a natural majority of nodes must be present.',
store: nodeQuorumOverrideStore,
searchAttr: 'name'" />
</div>
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/consumer/ConsumerTarget.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/consumer/ConsumerTarget.java
index f8585344b0..b7be1bfd9b 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/consumer/ConsumerTarget.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/consumer/ConsumerTarget.java
@@ -50,7 +50,7 @@ public interface ConsumerTarget
AMQSessionModel getSessionModel();
- void send(MessageInstance entry, boolean batch);
+ long send(MessageInstance entry, boolean batch);
void flushBatched();
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/AbstractConfiguredObject.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/AbstractConfiguredObject.java
index f944821c6f..b191db8523 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/AbstractConfiguredObject.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/AbstractConfiguredObject.java
@@ -1431,15 +1431,22 @@ public abstract class AbstractConfiguredObject<X extends ConfiguredObject<X>> im
static String interpolate(ConfiguredObject<?> object, String value)
{
- Map<String,String> inheritedContext = new HashMap<String, String>();
- generateInheritedContext(object.getModel(), object, inheritedContext);
- return Strings.expand(value, false,
- JSON_SUBSTITUTION_RESOLVER,
- getOwnAttributeResolver(object),
- new Strings.MapResolver(inheritedContext),
- Strings.JAVA_SYS_PROPS_RESOLVER,
- Strings.ENV_VARS_RESOLVER,
- object.getModel().getTypeRegistry().getDefaultContextResolver());
+ if(object == null)
+ {
+ return value;
+ }
+ else
+ {
+ Map<String, String> inheritedContext = new HashMap<String, String>();
+ generateInheritedContext(object.getModel(), object, inheritedContext);
+ return Strings.expand(value, false,
+ JSON_SUBSTITUTION_RESOLVER,
+ getOwnAttributeResolver(object),
+ new Strings.MapResolver(inheritedContext),
+ Strings.JAVA_SYS_PROPS_RESOLVER,
+ Strings.ENV_VARS_RESOLVER,
+ object.getModel().getTypeRegistry().getDefaultContextResolver());
+ }
}
private static OwnAttributeResolver getOwnAttributeResolver(final ConfiguredObject<?> object)
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/Broker.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/Broker.java
index 982ebb01c6..1a9390f210 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/Broker.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/Broker.java
@@ -128,6 +128,18 @@ public interface Broker<X extends Broker<X>> extends ConfiguredObject<X>, EventL
@ManagedAttribute( defaultValue = "false")
boolean getStatisticsReportingResetEnabled();
+ String BROKER_MESSAGE_COMPRESSION_ENABLED = "broker.messageCompressionEnabled";
+ @ManagedContextDefault(name = BROKER_MESSAGE_COMPRESSION_ENABLED)
+ boolean DEFAULT_MESSAGE_COMPRESSION_ENABLED = true;
+
+ @ManagedAttribute( defaultValue = "${"+ BROKER_MESSAGE_COMPRESSION_ENABLED +"}")
+ boolean isMessageCompressionEnabled();
+
+ String MESSAGE_COMPRESSION_THRESHOLD_SIZE = "connection.messageCompressionThresholdSize";
+ @ManagedContextDefault(name = MESSAGE_COMPRESSION_THRESHOLD_SIZE)
+ int DEFAULT_MESSAGE_COMPRESSION_THRESHOLD_SIZE = 102400;
+
+
@DerivedAttribute( persist = true )
String getModelVersion();
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/ConfiguredAutomatedAttribute.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/ConfiguredAutomatedAttribute.java
index 236e7fdccc..4ef1d315dd 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/ConfiguredAutomatedAttribute.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/ConfiguredAutomatedAttribute.java
@@ -20,11 +20,23 @@
*/
package org.apache.qpid.server.model;
+import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+
+import org.apache.log4j.Logger;
public class ConfiguredAutomatedAttribute<C extends ConfiguredObject, T> extends ConfiguredObjectAttribute<C,T>
{
+ private static final Logger LOGGER = Logger.getLogger(ConfiguredAutomatedAttribute.class);
+
private final ManagedAttribute _annotation;
+ private final Method _validValuesMethod;
ConfiguredAutomatedAttribute(final Class<C> clazz,
final Method getter,
@@ -32,6 +44,53 @@ public class ConfiguredAutomatedAttribute<C extends ConfiguredObject, T> extend
{
super(clazz, getter);
_annotation = annotation;
+ Method validValuesMethod = null;
+
+ if(_annotation.validValues().length == 1)
+ {
+ String validValue = _annotation.validValues()[0];
+
+ validValuesMethod = getValidValuesMethod(validValue, clazz);
+ }
+ _validValuesMethod = validValuesMethod;
+ }
+
+ private Method getValidValuesMethod(final String validValue, final Class<C> clazz)
+ {
+ if(validValue.matches("([\\w][\\w\\d_]+\\.)+[\\w][\\w\\d_\\$]*#[\\w\\d_]+\\s*\\(\\s*\\)"))
+ {
+ String function = validValue;
+ try
+ {
+ String className = function.split("#")[0].trim();
+ String methodName = function.split("#")[1].split("\\(")[0].trim();
+ Class<?> validValueCalculatingClass = Class.forName(className);
+ Method method = validValueCalculatingClass.getMethod(methodName);
+ if (Modifier.isStatic(method.getModifiers()) && Modifier.isPublic(method.getModifiers()))
+ {
+ if (Collection.class.isAssignableFrom(method.getReturnType()))
+ {
+ if (method.getGenericReturnType() instanceof ParameterizedType)
+ {
+ Type parameterizedType =
+ ((ParameterizedType) method.getGenericReturnType()).getActualTypeArguments()[0];
+ if (parameterizedType == String.class)
+ {
+ return method;
+ }
+ }
+ }
+ }
+
+ }
+ catch (ClassNotFoundException | NoSuchMethodException e)
+ {
+ LOGGER.warn("The validValues of the " + getName() + " attribute in class " + clazz.getSimpleName()
+ + " has value '" + validValue + "' which looks like it should be a method,"
+ + " but no such method could be used.", e );
+ }
+ }
+ return null;
}
public boolean isAutomated()
@@ -69,4 +128,21 @@ public class ConfiguredAutomatedAttribute<C extends ConfiguredObject, T> extend
return _annotation.description();
}
+ public Collection<String> validValues()
+ {
+ if(_validValuesMethod != null)
+ {
+ try
+ {
+ return (Collection<String>) _validValuesMethod.invoke(null);
+ }
+ catch (InvocationTargetException | IllegalAccessException e)
+ {
+ LOGGER.warn("Could not execute the validValues generation method " + _validValuesMethod.getName(), e);
+ return Collections.emptySet();
+ }
+ }
+ return Arrays.asList(_annotation.validValues());
+ }
+
}
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/Connection.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/Connection.java
index 7a965c19d7..5b3965904e 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/Connection.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/Connection.java
@@ -43,6 +43,7 @@ public interface Connection<X extends Connection<X>> extends ConfiguredObject<X>
String TRANSPORT = "transport";
String PORT = "port";
+
@DerivedAttribute
String getClientId();
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/ManagedAttribute.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/ManagedAttribute.java
index 2a72c5c5ac..d8b36f487c 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/ManagedAttribute.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/ManagedAttribute.java
@@ -34,4 +34,5 @@ public @interface ManagedAttribute
boolean persist() default true;
String defaultValue() default "";
String description() default "";
+ String[] validValues() default {};
}
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/Protocol.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/Protocol.java
index 22ea1d9706..a943c0f54c 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/Protocol.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/Protocol.java
@@ -87,6 +87,6 @@ public enum Protocol
public static enum ProtocolType
{
- AMQP, HTTP, JMX, RMI;
+ AMQP, HTTP, JMX, RMI
}
}
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java
index 67c713e9d9..af46bae1c4 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java
@@ -92,6 +92,8 @@ public class BrokerAdapter extends AbstractConfiguredObject<BrokerAdapter> imple
private int _statisticsReportingPeriod;
@ManagedAttributeField
private boolean _statisticsReportingResetEnabled;
+ @ManagedAttributeField
+ private boolean _messageCompressionEnabled;
private State _state = State.UNINITIALIZED;
@@ -360,6 +362,12 @@ public class BrokerAdapter extends AbstractConfiguredObject<BrokerAdapter> imple
}
@Override
+ public boolean isMessageCompressionEnabled()
+ {
+ return _messageCompressionEnabled;
+ }
+
+ @Override
public String getModelVersion()
{
return BrokerModel.MODEL_VERSION;
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/AmqpPort.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/AmqpPort.java
index 0d3ec6d3bb..fa599b4d5f 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/AmqpPort.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/AmqpPort.java
@@ -20,10 +20,14 @@
*/
package org.apache.qpid.server.model.port;
+import java.util.Set;
+
import org.apache.qpid.server.model.AuthenticationProvider;
import org.apache.qpid.server.model.ManagedAttribute;
import org.apache.qpid.server.model.ManagedObject;
import org.apache.qpid.server.model.Port;
+import org.apache.qpid.server.model.Protocol;
+import org.apache.qpid.server.model.Transport;
import org.apache.qpid.server.virtualhost.VirtualHostImpl;
@ManagedObject( category = false, type = "AMQP")
@@ -57,5 +61,13 @@ public interface AmqpPort<X extends AmqpPort<X>> extends Port<X>
@ManagedAttribute( mandatory = true )
AuthenticationProvider getAuthenticationProvider();
+
+ @ManagedAttribute( defaultValue = "TCP",
+ validValues = {"org.apache.qpid.server.model.port.AmqpPortImpl#getAllAvailableTransportCombinations()"})
+ Set<Transport> getTransports();
+
+ @ManagedAttribute( validValues = {"org.apache.qpid.server.model.port.AmqpPortImpl#getAllAvailableProtocolCombinations()"} )
+ Set<Protocol> getProtocols();
+
VirtualHostImpl getVirtualHost(String name);
}
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/AmqpPortImpl.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/AmqpPortImpl.java
index e6e2d7bbb8..6f6d04c335 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/AmqpPortImpl.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/AmqpPortImpl.java
@@ -19,9 +19,12 @@
*/
package org.apache.qpid.server.model.port;
+import java.io.IOException;
+import java.io.StringWriter;
import java.security.GeneralSecurityException;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
import java.util.EnumSet;
import java.util.HashSet;
import java.util.Map;
@@ -32,6 +35,8 @@ import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
+import org.codehaus.jackson.map.ObjectMapper;
+
import org.apache.qpid.server.configuration.BrokerProperties;
import org.apache.qpid.server.configuration.IllegalConfigurationException;
import org.apache.qpid.server.logging.messages.BrokerMessages;
@@ -43,6 +48,7 @@ import org.apache.qpid.server.model.Protocol;
import org.apache.qpid.server.model.State;
import org.apache.qpid.server.model.Transport;
import org.apache.qpid.server.model.TrustStore;
+import org.apache.qpid.server.plugin.ProtocolEngineCreator;
import org.apache.qpid.server.plugin.QpidServiceLoader;
import org.apache.qpid.server.plugin.TransportProviderFactory;
import org.apache.qpid.server.transport.AcceptingTransport;
@@ -275,4 +281,87 @@ public class AmqpPortImpl extends AbstractPortWithAuthProvider<AmqpPortImpl> imp
return null;
}
+ public static Set<Protocol> getInstalledProtocols()
+ {
+ Set<Protocol> protocols = new HashSet<>();
+ for(ProtocolEngineCreator installedEngine : (new QpidServiceLoader<ProtocolEngineCreator>()).instancesOf(ProtocolEngineCreator.class))
+ {
+ protocols.add(installedEngine.getVersion());
+ }
+ return protocols;
+ }
+
+ @SuppressWarnings("unused")
+ public static Collection<String> getAllAvailableProtocolCombinations()
+ {
+ Set<Protocol> protocols = getInstalledProtocols();
+
+ Set<Set<String>> last = new HashSet<>();
+ for(Protocol protocol : protocols)
+ {
+ last.add(Collections.singleton(protocol.name()));
+ }
+
+ Set<Set<String>> protocolCombinations = new HashSet<>(last);
+ for(int i = 1; i < protocols.size(); i++)
+ {
+ Set<Set<String>> current = new HashSet<>();
+ for(Set<String> set : last)
+ {
+ for(Protocol p : protocols)
+ {
+ if(!set.contains(p.name()))
+ {
+ Set<String> potential = new HashSet<>(set);
+ potential.add(p.name());
+ current.add(potential);
+ }
+ }
+ }
+ protocolCombinations.addAll(current);
+ last = current;
+ }
+ Set<String> combinationsAsString = new HashSet<>(protocolCombinations.size());
+ ObjectMapper mapper = new ObjectMapper();
+ for(Set<String> combination : protocolCombinations)
+ {
+ try(StringWriter writer = new StringWriter())
+ {
+ mapper.writeValue(writer, combination);
+ combinationsAsString.add(writer.toString());
+ }
+ catch (IOException e)
+ {
+ throw new IllegalArgumentException("Unexpected IO Exception generating JSON string", e);
+ }
+ }
+ return Collections.unmodifiableSet(combinationsAsString);
+ }
+
+ @SuppressWarnings("unused")
+ public static Collection<String> getAllAvailableTransportCombinations()
+ {
+ Set<Set<Transport>> combinations = new HashSet<>();
+
+ for(TransportProviderFactory providerFactory : (new QpidServiceLoader<TransportProviderFactory>()).instancesOf(TransportProviderFactory.class))
+ {
+ combinations.addAll(providerFactory.getSupportedTransports());
+ }
+
+ Set<String> combinationsAsString = new HashSet<>(combinations.size());
+ ObjectMapper mapper = new ObjectMapper();
+ for(Set<Transport> combination : combinations)
+ {
+ try(StringWriter writer = new StringWriter())
+ {
+ mapper.writeValue(writer, combination);
+ combinationsAsString.add(writer.toString());
+ }
+ catch (IOException e)
+ {
+ throw new IllegalArgumentException("Unexpected IO Exception generating JSON string", e);
+ }
+ }
+ return Collections.unmodifiableSet(combinationsAsString);
+ }
}
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/HttpPort.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/HttpPort.java
index b169b07e35..fa2af121ae 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/HttpPort.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/HttpPort.java
@@ -20,10 +20,14 @@
*/
package org.apache.qpid.server.model.port;
+import java.util.Set;
+
import org.apache.qpid.server.model.AuthenticationProvider;
import org.apache.qpid.server.model.ManagedAttribute;
import org.apache.qpid.server.model.ManagedObject;
import org.apache.qpid.server.model.Port;
+import org.apache.qpid.server.model.Protocol;
+import org.apache.qpid.server.model.Transport;
@ManagedObject( category = false, type = "HTTP")
public interface HttpPort<X extends HttpPort<X>> extends Port<X>
@@ -42,5 +46,13 @@ public interface HttpPort<X extends HttpPort<X>> extends Port<X>
@ManagedAttribute( mandatory = true )
AuthenticationProvider getAuthenticationProvider();
+
+ @ManagedAttribute( defaultValue = "TCP",
+ validValues = {"[ \"TCP\" ]", "[ \"SSL\" ]", "[ \"TCP\", \"SSL\" ]"})
+ Set<Transport> getTransports();
+
+ @ManagedAttribute( validValues = { "[ \"HTTP\"]"} )
+ Set<Protocol> getProtocols();
+
void setPortManager(PortManager manager);
}
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/JmxPort.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/JmxPort.java
index 56c77cbb03..48754e92e4 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/JmxPort.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/JmxPort.java
@@ -20,10 +20,14 @@
*/
package org.apache.qpid.server.model.port;
+import java.util.Set;
+
import org.apache.qpid.server.model.AuthenticationProvider;
import org.apache.qpid.server.model.ManagedAttribute;
import org.apache.qpid.server.model.ManagedObject;
import org.apache.qpid.server.model.Port;
+import org.apache.qpid.server.model.Protocol;
+import org.apache.qpid.server.model.Transport;
@ManagedObject( category = false, type = "JMX")
public interface JmxPort<X extends JmxPort<X>> extends Port<X>
@@ -42,5 +46,13 @@ public interface JmxPort<X extends JmxPort<X>> extends Port<X>
@ManagedAttribute( mandatory = true )
AuthenticationProvider getAuthenticationProvider();
+
+ @ManagedAttribute( defaultValue = "TCP",
+ validValues = {"[ \"TCP\" ]", "[ \"SSL\" ]"})
+ Set<Transport> getTransports();
+
+ @ManagedAttribute( validValues = { "[ \"JMX_RMI\"]"} )
+ Set<Protocol> getProtocols();
+
void setPortManager(PortManager manager);
}
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/RmiPort.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/RmiPort.java
index ed975d041a..d2420aa343 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/RmiPort.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/RmiPort.java
@@ -20,65 +20,27 @@
*/
package org.apache.qpid.server.model.port;
-import java.util.Collections;
-import java.util.Map;
import java.util.Set;
-import org.apache.qpid.server.configuration.IllegalConfigurationException;
-import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.model.ManagedAttribute;
import org.apache.qpid.server.model.ManagedObject;
-import org.apache.qpid.server.model.ManagedObjectFactoryConstructor;
+import org.apache.qpid.server.model.Port;
import org.apache.qpid.server.model.Protocol;
-import org.apache.qpid.server.model.State;
import org.apache.qpid.server.model.Transport;
@ManagedObject( category = false, type = "RMI")
-public class RmiPort extends AbstractPort<RmiPort>
+public interface RmiPort<X extends RmiPort<X>> extends Port<X>
{
- private PortManager _portManager;
- @ManagedObjectFactoryConstructor
- public RmiPort(final Map<String, Object> attributes,
- final Broker<?> broker)
- {
- super(attributes, broker);
- }
+ @ManagedAttribute( validValues = { "[ \"RMI\"]"} )
+ Set<Protocol> getProtocols();
- @Override
- public void onValidate()
- {
- super.onValidate();
+ @ManagedAttribute( defaultValue = "TCP",
+ validValues = {"[ \"TCP\" ]"})
+ Set<Transport> getTransports();
- validateOnlyOneInstance();
- if (getTransports().contains(Transport.SSL))
- {
- throw new IllegalConfigurationException("Can't create RMI registry port which requires SSL");
- }
+ public void setPortManager(PortManager manager);
- }
- @Override
- protected Set<Protocol> getDefaultProtocols()
- {
- return Collections.singleton(Protocol.RMI);
- }
-
- public void setPortManager(PortManager manager)
- {
- _portManager = manager;
- }
-
- @Override
- protected State onActivate()
- {
- if(_portManager != null && _portManager.isActivationAllowed(this))
- {
- return super.onActivate();
- }
- else
- {
- return State.QUIESCED;
- }
- }
}
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/RmiPortImpl.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/RmiPortImpl.java
new file mode 100644
index 0000000000..e236b7cb91
--- /dev/null
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/RmiPortImpl.java
@@ -0,0 +1,82 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.server.model.port;
+
+import java.util.Collections;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.qpid.server.configuration.IllegalConfigurationException;
+import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.model.ManagedObjectFactoryConstructor;
+import org.apache.qpid.server.model.Protocol;
+import org.apache.qpid.server.model.State;
+import org.apache.qpid.server.model.Transport;
+
+public class RmiPortImpl extends AbstractPort<RmiPortImpl> implements RmiPort<RmiPortImpl>
+{
+ private PortManager _portManager;
+
+ @ManagedObjectFactoryConstructor
+ public RmiPortImpl(final Map<String, Object> attributes,
+ final Broker<?> broker)
+ {
+ super(attributes, broker);
+ }
+
+ @Override
+ public void onValidate()
+ {
+ super.onValidate();
+
+ validateOnlyOneInstance();
+
+ if (getTransports().contains(Transport.SSL))
+ {
+ throw new IllegalConfigurationException("Can't create RMI registry port which requires SSL");
+ }
+
+ }
+
+ @Override
+ protected Set<Protocol> getDefaultProtocols()
+ {
+ return Collections.singleton(Protocol.RMI);
+ }
+
+ public void setPortManager(PortManager manager)
+ {
+ _portManager = manager;
+ }
+
+ @Override
+ protected State onActivate()
+ {
+ if(_portManager != null && _portManager.isActivationAllowed(this))
+ {
+ return super.onActivate();
+ }
+ else
+ {
+ return State.QUIESCED;
+ }
+ }
+}
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/queue/QueueConsumerImpl.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/queue/QueueConsumerImpl.java
index d80aa92007..4044c938db 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/queue/QueueConsumerImpl.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/queue/QueueConsumerImpl.java
@@ -471,9 +471,8 @@ class QueueConsumerImpl
public final void send(final QueueEntry entry, final boolean batch)
{
_deliveredCount.incrementAndGet();
- ServerMessage message = entry.getMessage();
- _deliveredBytes.addAndGet(message.getSize());
- _target.send(entry, batch);
+ long size = _target.send(entry, batch);
+ _deliveredBytes.addAndGet(size);
}
@Override
diff --git a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/consumer/MockConsumer.java b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/consumer/MockConsumer.java
index 8d025c50dc..ad33ecadcf 100644
--- a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/consumer/MockConsumer.java
+++ b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/consumer/MockConsumer.java
@@ -167,13 +167,15 @@ public class MockConsumer implements ConsumerTarget
{
}
- public void send(MessageInstance entry, boolean batch)
+ public long send(MessageInstance entry, boolean batch)
{
+ long size = entry.getMessage().getSize();
if (messages.contains(entry))
{
entry.setRedelivered();
}
messages.add(entry);
+ return size;
}
public void flushBatched()
diff --git a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/model/ConfigureObjectTypeRegistryTest.java b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/model/ConfigureObjectTypeRegistryTest.java
index 8bd599f22f..3301c046a8 100644
--- a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/model/ConfigureObjectTypeRegistryTest.java
+++ b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/model/ConfigureObjectTypeRegistryTest.java
@@ -20,12 +20,14 @@
*/
package org.apache.qpid.server.model;
+import java.util.Arrays;
import java.util.Collection;
import junit.framework.TestCase;
import org.apache.qpid.server.model.testmodel.Test2RootCategory;
import org.apache.qpid.server.model.testmodel.Test2RootCategoryImpl;
+import org.apache.qpid.server.model.testmodel.TestChildCategory;
import org.apache.qpid.server.model.testmodel.TestModel;
import org.apache.qpid.server.model.testmodel.TestRootCategory;
import org.apache.qpid.server.model.testmodel.TestRootCategoryImpl;
@@ -76,6 +78,21 @@ public class ConfigureObjectTypeRegistryTest extends TestCase
Test2RootCategory.DEFAULTED_VALUE_DEFAULT);
}
+ public void testValidValues()
+ {
+ checkValidValues("validValue",_typeRegistry.getAttributes((Class) TestRootCategoryImpl.class),
+ Arrays.asList( TestRootCategory.VALID_VALUE1, TestRootCategory.VALID_VALUE2 ) );
+
+ checkValidValues("validValue", _typeRegistry.getAttributes((Class) Test2RootCategoryImpl.class),
+ Test2RootCategoryImpl.functionGeneratedValidValues());
+
+
+ checkValidValues("validValueNotInterpolated", _typeRegistry.getAttributes((Class) TestChildCategory.class),
+ Arrays.asList(TestChildCategory.NON_INTERPOLATED_VALID_VALUE));
+
+
+ }
+
private void checkDefaultedValue(final Collection<ConfiguredObjectAttribute<?, ?>> attrs,
final String defaultedValueDefault)
{
@@ -92,4 +109,24 @@ public class ConfigureObjectTypeRegistryTest extends TestCase
}
assertTrue("Could not find attribute defaultedValue", found);
}
+
+ private void checkValidValues(final String attrName, final Collection<ConfiguredObjectAttribute<?, ?>> attrs,
+ final Collection<String> validValues)
+ {
+ boolean found = false;
+ for(ConfiguredObjectAttribute<?, ?> attr : attrs)
+ {
+ if(attr.getName().equals(attrName))
+ {
+ Collection<String> foundValues = ((ConfiguredAutomatedAttribute<?, ?>) attr).validValues();
+ assertEquals("Valid values not as expected, counts differ", validValues.size(), foundValues.size());
+ assertTrue("Valid values do not include all expected values", foundValues.containsAll(validValues));
+ assertTrue("Valid values contain unexpected addtional values", validValues.containsAll(foundValues));
+ found = true;
+ break;
+ }
+
+ }
+ assertTrue("Could not find attribute " + attrName, found);
+ }
}
diff --git a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/model/testmodel/Test2RootCategory.java b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/model/testmodel/Test2RootCategory.java
index e47c76cbbb..23f03db507 100644
--- a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/model/testmodel/Test2RootCategory.java
+++ b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/model/testmodel/Test2RootCategory.java
@@ -26,10 +26,15 @@ import org.apache.qpid.server.model.ManagedAttribute;
public interface Test2RootCategory<X extends Test2RootCategory<X>> extends TestRootCategory<X>
{
String DEFAULTED_VALUE_DEFAULT = "differentDefault";
+
@Override
@ManagedAttribute( defaultValue = DEFAULTED_VALUE_DEFAULT)
String getDefaultedValue();
+ @Override
+ @ManagedAttribute( validValues = {"org.apache.qpid.server.model.testmodel.Test2RootCategoryImpl#functionGeneratedValidValues()"})
+ String getValidValue();
+
@DerivedAttribute
public int getDerivedAttribute();
}
diff --git a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/model/testmodel/Test2RootCategoryImpl.java b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/model/testmodel/Test2RootCategoryImpl.java
index 022e0a256f..e98a9fa3dc 100644
--- a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/model/testmodel/Test2RootCategoryImpl.java
+++ b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/model/testmodel/Test2RootCategoryImpl.java
@@ -20,6 +20,8 @@
*/
package org.apache.qpid.server.model.testmodel;
+import java.util.Collection;
+import java.util.Collections;
import java.util.Map;
import org.apache.qpid.server.configuration.updater.CurrentThreadTaskExecutor;
@@ -49,6 +51,9 @@ public class Test2RootCategoryImpl extends AbstractConfiguredObject<Test2RootCat
@ManagedAttributeField
private Map<String,String> _mapValue;
+ @ManagedAttributeField
+ private String _validValue;
+
@ManagedObjectFactoryConstructor
public Test2RootCategoryImpl(final Map<String, Object> attributes)
{
@@ -93,6 +98,12 @@ public class Test2RootCategoryImpl extends AbstractConfiguredObject<Test2RootCat
}
@Override
+ public String getValidValue()
+ {
+ return _validValue;
+ }
+
+ @Override
public int getDerivedAttribute()
{
return 0;
@@ -115,4 +126,9 @@ public class Test2RootCategoryImpl extends AbstractConfiguredObject<Test2RootCat
{
return null;
}
+
+ public static Collection<String> functionGeneratedValidValues()
+ {
+ return Collections.singleton("generated");
+ }
}
diff --git a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/model/testmodel/TestChildCategory.java b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/model/testmodel/TestChildCategory.java
new file mode 100644
index 0000000000..0c8dcc8744
--- /dev/null
+++ b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/model/testmodel/TestChildCategory.java
@@ -0,0 +1,35 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.server.model.testmodel;
+
+import org.apache.qpid.server.model.ConfiguredObject;
+import org.apache.qpid.server.model.ManagedAttribute;
+import org.apache.qpid.server.model.ManagedObject;
+
+@ManagedObject
+public interface TestChildCategory<X extends TestChildCategory<X>> extends ConfiguredObject<X>
+{
+
+ String NON_INTERPOLATED_VALID_VALUE = "${file.separator}";
+
+ @ManagedAttribute(validValues = { NON_INTERPOLATED_VALID_VALUE })
+ String getValidValueNotInterpolated();
+}
diff --git a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/model/testmodel/TestChildCategoryImpl.java b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/model/testmodel/TestChildCategoryImpl.java
new file mode 100644
index 0000000000..b5a4182f79
--- /dev/null
+++ b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/model/testmodel/TestChildCategoryImpl.java
@@ -0,0 +1,60 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.server.model.testmodel;
+
+import java.util.Map;
+
+import org.apache.qpid.server.model.AbstractConfiguredObject;
+import org.apache.qpid.server.model.ManagedAttributeField;
+import org.apache.qpid.server.model.ManagedObject;
+import org.apache.qpid.server.model.ManagedObjectFactoryConstructor;
+import org.apache.qpid.server.model.State;
+
+@ManagedObject( category = false , type = "test" )
+public class TestChildCategoryImpl
+ extends AbstractConfiguredObject<TestChildCategoryImpl> implements TestChildCategory<TestChildCategoryImpl>
+{
+
+
+ @ManagedAttributeField
+ private String _validValueNotInterpolated;
+
+
+ @ManagedObjectFactoryConstructor
+ public TestChildCategoryImpl(final Map<String, Object> attributes, TestRootCategory<?> parent)
+ {
+ super(parentsMap(parent), attributes);
+ }
+
+ @Override
+ public State getState()
+ {
+ return null;
+ }
+
+
+
+ @Override
+ public String getValidValueNotInterpolated()
+ {
+ return _validValueNotInterpolated;
+ }
+}
diff --git a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/model/testmodel/TestModel.java b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/model/testmodel/TestModel.java
index fc98b51731..ab9d753b7d 100644
--- a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/model/testmodel/TestModel.java
+++ b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/model/testmodel/TestModel.java
@@ -36,7 +36,8 @@ public class TestModel extends Model
private static final Model INSTANCE = new TestModel();
private Class<? extends ConfiguredObject>[] _supportedClasses =
new Class[] {
- TestRootCategory.class
+ TestRootCategory.class,
+ TestChildCategory.class
};
private final ConfiguredObjectFactory _objectFactory;
@@ -77,7 +78,9 @@ public class TestModel extends Model
@Override
public Collection<Class<? extends ConfiguredObject>> getChildTypes(final Class<? extends ConfiguredObject> parent)
{
- return Collections.emptySet();
+ return TestRootCategory.class.isAssignableFrom(parent)
+ ? Collections.<Class<? extends ConfiguredObject>>singleton(TestChildCategory.class)
+ : Collections.<Class<? extends ConfiguredObject>>emptySet();
}
@Override
@@ -89,7 +92,9 @@ public class TestModel extends Model
@Override
public Collection<Class<? extends ConfiguredObject>> getParentTypes(final Class<? extends ConfiguredObject> child)
{
- return Collections.emptySet();
+ return TestChildCategory.class.isAssignableFrom(child)
+ ? Collections.<Class<? extends ConfiguredObject>>singleton(TestRootCategory.class)
+ : Collections.<Class<? extends ConfiguredObject>>emptySet();
}
@Override
diff --git a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/model/testmodel/TestRootCategory.java b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/model/testmodel/TestRootCategory.java
index 954fe4dcb1..7f804006b2 100644
--- a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/model/testmodel/TestRootCategory.java
+++ b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/model/testmodel/TestRootCategory.java
@@ -42,9 +42,15 @@ public interface TestRootCategory<X extends TestRootCategory<X>> extends Configu
String getAutomatedNonPersistedValue();
String DEFAULTED_VALUE_DEFAULT = "myDefaultVar";
+ String VALID_VALUE1 = "FOO";
+ String VALID_VALUE2 = "BAR";
+
@ManagedAttribute( defaultValue = DEFAULTED_VALUE_DEFAULT)
String getDefaultedValue();
+ @ManagedAttribute(validValues = {VALID_VALUE1, VALID_VALUE2} )
+ String getValidValue();
+
@ManagedAttribute
String getStringValue();
diff --git a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/model/testmodel/TestRootCategoryImpl.java b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/model/testmodel/TestRootCategoryImpl.java
index d549086686..0c6a0cb0ca 100644
--- a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/model/testmodel/TestRootCategoryImpl.java
+++ b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/model/testmodel/TestRootCategoryImpl.java
@@ -49,6 +49,10 @@ public class TestRootCategoryImpl extends AbstractConfiguredObject<TestRootCateg
@ManagedAttributeField
private Map<String,String> _mapValue;
+ @ManagedAttributeField
+ private String _validValue;
+
+
@ManagedObjectFactoryConstructor
public TestRootCategoryImpl(final Map<String, Object> attributes)
{
@@ -109,4 +113,10 @@ public class TestRootCategoryImpl extends AbstractConfiguredObject<TestRootCateg
{
return null;
}
+
+ @Override
+ public String getValidValue()
+ {
+ return _validValue;
+ }
}
diff --git a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/queue/StandardQueueTest.java b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/queue/StandardQueueTest.java
index ce1c95e674..f13886d2b2 100644
--- a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/queue/StandardQueueTest.java
+++ b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/queue/StandardQueueTest.java
@@ -208,10 +208,11 @@ public class StandardQueueTest extends AbstractQueueTestBase
* @param entry
* @param batch
*/
- public void send(MessageInstance entry, boolean batch)
+ public long send(MessageInstance entry, boolean batch)
{
- super.send(entry, batch);
+ long size = super.send(entry, batch);
latch.countDown();
+ return size;
}
};
diff --git a/qpid/java/broker-plugins/amqp-0-10-protocol/src/main/java/org/apache/qpid/server/protocol/v0_10/ConsumerTarget_0_10.java b/qpid/java/broker-plugins/amqp-0-10-protocol/src/main/java/org/apache/qpid/server/protocol/v0_10/ConsumerTarget_0_10.java
index 7ab3fbb1f5..ec0c38ec42 100644
--- a/qpid/java/broker-plugins/amqp-0-10-protocol/src/main/java/org/apache/qpid/server/protocol/v0_10/ConsumerTarget_0_10.java
+++ b/qpid/java/broker-plugins/amqp-0-10-protocol/src/main/java/org/apache/qpid/server/protocol/v0_10/ConsumerTarget_0_10.java
@@ -20,6 +20,7 @@
*/
package org.apache.qpid.server.protocol.v0_10;
+import java.nio.ByteBuffer;
import java.util.Collections;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -51,6 +52,7 @@ import org.apache.qpid.transport.MessageProperties;
import org.apache.qpid.transport.MessageTransfer;
import org.apache.qpid.transport.Method;
import org.apache.qpid.transport.Option;
+import org.apache.qpid.util.GZIPUtils;
public class ConsumerTarget_0_10 extends AbstractConsumerTarget implements FlowCreditManager.FlowCreditManagerListener
{
@@ -198,7 +200,7 @@ public class ConsumerTarget_0_10 extends AbstractConsumerTarget implements FlowC
private final AddMessageDispositionListenerAction _postIdSettingAction;
- public void send(final MessageInstance entry, boolean batch)
+ public long send(final MessageInstance entry, boolean batch)
{
ServerMessage serverMsg = entry.getMessage();
@@ -264,11 +266,44 @@ public class ConsumerTarget_0_10 extends AbstractConsumerTarget implements FlowC
deliveryProps.setRedelivered(entry.isRedelivered());
- Header header = new Header(deliveryProps, messageProps, msg.getHeader() == null ? null : msg.getHeader().getNonStandardProperties());
+ boolean msgCompressed = messageProps != null && GZIPUtils.GZIP_CONTENT_ENCODING.equals(messageProps.getContentEncoding());
+
+ ByteBuffer body = msg.getBody();
- xfr = batch ? new MessageTransfer(getConsumer().getName(),_acceptMode,_acquireMode,header,msg.getBody(), BATCHED)
- : new MessageTransfer(getConsumer().getName(),_acceptMode,_acquireMode,header,msg.getBody());
+ boolean compressionSupported = _session.getConnection().getConnectionDelegate().isCompressionSupported();
+
+ if(msgCompressed && !compressionSupported)
+ {
+ byte[] uncompressed = GZIPUtils.uncompressBufferToArray(body);
+ if(uncompressed != null)
+ {
+ messageProps.setContentEncoding(null);
+ body = ByteBuffer.wrap(uncompressed);
+ }
+ }
+ else if(!msgCompressed
+ && compressionSupported
+ && (messageProps == null || messageProps.getContentEncoding()==null)
+ && body.remaining() > _session.getConnection().getMessageCompressionThreshold())
+ {
+ byte[] compressed = GZIPUtils.compressBufferToArray(body);
+ if(compressed != null)
+ {
+ if(messageProps == null)
+ {
+ messageProps = new MessageProperties();
+ }
+ messageProps.setContentEncoding(GZIPUtils.GZIP_CONTENT_ENCODING);
+ body = ByteBuffer.wrap(compressed);
+ }
+ }
+ long size = body == null ? 0 : body.remaining();
+
+ Header header = new Header(deliveryProps, messageProps, msg.getHeader() == null ? null : msg.getHeader().getNonStandardProperties());
+
+ xfr = batch ? new MessageTransfer(getConsumer().getName(),_acceptMode,_acquireMode,header, body, BATCHED)
+ : new MessageTransfer(getConsumer().getName(),_acceptMode,_acquireMode,header, body);
if(_acceptMode == MessageAcceptMode.NONE && _acquireMode != MessageAcquireMode.PRE_ACQUIRED)
{
@@ -311,7 +346,7 @@ public class ConsumerTarget_0_10 extends AbstractConsumerTarget implements FlowC
{
recordUnacknowledged(entry);
}
-
+ return size;
}
void recordUnacknowledged(MessageInstance entry)
diff --git a/qpid/java/broker-plugins/amqp-0-10-protocol/src/main/java/org/apache/qpid/server/protocol/v0_10/ServerConnection.java b/qpid/java/broker-plugins/amqp-0-10-protocol/src/main/java/org/apache/qpid/server/protocol/v0_10/ServerConnection.java
index 8ddd04f51a..60bb5c6112 100644
--- a/qpid/java/broker-plugins/amqp-0-10-protocol/src/main/java/org/apache/qpid/server/protocol/v0_10/ServerConnection.java
+++ b/qpid/java/broker-plugins/amqp-0-10-protocol/src/main/java/org/apache/qpid/server/protocol/v0_10/ServerConnection.java
@@ -74,7 +74,7 @@ public class ServerConnection extends Connection implements AMQConnectionModel<S
private final StatisticsCounter _messagesDelivered, _dataDelivered, _messagesReceived, _dataReceived;
private final long _connectionId;
private final Object _reference = new Object();
- private VirtualHostImpl _virtualHost;
+ private VirtualHostImpl<?,?,?> _virtualHost;
private Port<?> _port;
private AtomicLong _lastIoTime = new AtomicLong();
private boolean _blocking;
@@ -87,6 +87,7 @@ public class ServerConnection extends Connection implements AMQConnectionModel<S
new CopyOnWriteArrayList<SessionModelListener>();
private volatile boolean _stopped;
+ private int _messageCompressionThreshold;
public ServerConnection(final long connectionId, Broker broker)
{
@@ -172,14 +173,22 @@ public class ServerConnection extends Connection implements AMQConnectionModel<S
super.setConnectionDelegate(delegate);
}
- public VirtualHostImpl getVirtualHost()
+ public VirtualHostImpl<?,?,?> getVirtualHost()
{
return _virtualHost;
}
- public void setVirtualHost(VirtualHostImpl virtualHost)
+ public void setVirtualHost(VirtualHostImpl<?,?,?> virtualHost)
{
_virtualHost = virtualHost;
+ _messageCompressionThreshold =
+ virtualHost.getContextValue(Integer.class,
+ Broker.MESSAGE_COMPRESSION_THRESHOLD_SIZE);
+
+ if(_messageCompressionThreshold <= 0)
+ {
+ _messageCompressionThreshold = Integer.MAX_VALUE;
+ }
}
@Override
@@ -639,4 +648,9 @@ public class ServerConnection extends Connection implements AMQConnectionModel<S
{
_taskList.remove(task);
}
+
+ public int getMessageCompressionThreshold()
+ {
+ return _messageCompressionThreshold;
+ }
}
diff --git a/qpid/java/broker-plugins/amqp-0-10-protocol/src/main/java/org/apache/qpid/server/protocol/v0_10/ServerConnectionDelegate.java b/qpid/java/broker-plugins/amqp-0-10-protocol/src/main/java/org/apache/qpid/server/protocol/v0_10/ServerConnectionDelegate.java
index bab2d802e8..cc9d66756b 100644
--- a/qpid/java/broker-plugins/amqp-0-10-protocol/src/main/java/org/apache/qpid/server/protocol/v0_10/ServerConnectionDelegate.java
+++ b/qpid/java/broker-plugins/amqp-0-10-protocol/src/main/java/org/apache/qpid/server/protocol/v0_10/ServerConnectionDelegate.java
@@ -64,6 +64,8 @@ public class ServerConnectionDelegate extends ServerDelegate
private final SubjectCreator _subjectCreator;
private int _maximumFrameSize;
+ private boolean _compressionSupported;
+
public ServerConnectionDelegate(Broker<?> broker, String localFQDN, SubjectCreator subjectCreator)
{
this(createConnectionProperties(broker), Collections.singletonList((Object)"en_US"), broker, localFQDN, subjectCreator);
@@ -111,6 +113,7 @@ public class ServerConnectionDelegate extends ServerDelegate
map.put(ServerPropertyNames.VERSION, QpidProperties.getReleaseVersion());
map.put(ServerPropertyNames.QPID_BUILD, QpidProperties.getBuildVersion());
map.put(ServerPropertyNames.QPID_INSTANCE_NAME, broker.getName());
+ map.put(ConnectionStartProperties.QPID_MESSAGE_COMPRESSION_SUPPORTED, String.valueOf(broker.isMessageCompressionEnabled()));
return map;
}
@@ -366,6 +369,16 @@ public class ServerConnectionDelegate extends ServerDelegate
public void connectionStartOk(Connection conn, ConnectionStartOk ok)
{
_clientProperties = ok.getClientProperties();
+ if(_clientProperties != null)
+ {
+ Object compressionSupported =
+ _clientProperties.get(ConnectionStartProperties.QPID_MESSAGE_COMPRESSION_SUPPORTED);
+ if (compressionSupported != null)
+ {
+ _compressionSupported = Boolean.parseBoolean(String.valueOf(compressionSupported));
+
+ }
+ }
super.connectionStartOk(conn, ok);
}
@@ -400,4 +413,9 @@ public class ServerConnectionDelegate extends ServerDelegate
int delay = (Integer)_broker.getAttribute(Broker.CONNECTION_HEART_BEAT_DELAY);
return delay == 0 ? super.getHeartbeatMax() : delay;
}
+
+ public boolean isCompressionSupported()
+ {
+ return _compressionSupported && _broker.isMessageCompressionEnabled();
+ }
}
diff --git a/qpid/java/broker-plugins/amqp-0-8-protocol/src/main/java/org/apache/qpid/server/protocol/v0_8/AMQProtocolEngine.java b/qpid/java/broker-plugins/amqp-0-8-protocol/src/main/java/org/apache/qpid/server/protocol/v0_8/AMQProtocolEngine.java
index 1c264e52c6..c193491e1e 100644
--- a/qpid/java/broker-plugins/amqp-0-8-protocol/src/main/java/org/apache/qpid/server/protocol/v0_8/AMQProtocolEngine.java
+++ b/qpid/java/broker-plugins/amqp-0-8-protocol/src/main/java/org/apache/qpid/server/protocol/v0_8/AMQProtocolEngine.java
@@ -103,7 +103,7 @@ public class AMQProtocolEngine implements ServerProtocolEngine, AMQProtocolSessi
private String _clientProduct = null;
private String _remoteProcessPid = null;
- private VirtualHostImpl _virtualHost;
+ private VirtualHostImpl<?,?,?> _virtualHost;
private final Map<Integer, AMQChannel<AMQProtocolEngine>> _channelMap =
new HashMap<Integer, AMQChannel<AMQProtocolEngine>>();
@@ -175,6 +175,8 @@ public class AMQProtocolEngine implements ServerProtocolEngine, AMQProtocolSessi
private volatile boolean _stopped;
private long _readBytes;
private boolean _authenticated;
+ private boolean _compressionSupported;
+ private int _messageCompressionThreshold;
public AMQProtocolEngine(Broker broker,
final NetworkConnection network,
@@ -208,7 +210,7 @@ public class AMQProtocolEngine implements ServerProtocolEngine, AMQProtocolSessi
return null;
}
});
-
+
_messagesDelivered = new StatisticsCounter("messages-delivered-" + getSessionID());
_dataDelivered = new StatisticsCounter("data-delivered-" + getSessionID());
_messagesReceived = new StatisticsCounter("messages-received-" + getSessionID());
@@ -539,6 +541,8 @@ public class AMQProtocolEngine implements ServerProtocolEngine, AMQProtocolSessi
_broker.getName());
serverProperties.setString(ConnectionStartProperties.QPID_CLOSE_WHEN_NO_ROUTE,
String.valueOf(_closeWhenNoRoute));
+ serverProperties.setString(ConnectionStartProperties.QPID_MESSAGE_COMPRESSION_SUPPORTED,
+ String.valueOf(_broker.isMessageCompressionEnabled()));
AMQMethodBody responseBody = getMethodRegistry().createConnectionStartBody((short) getProtocolMajorVersion(),
(short) pv.getActualMinorVersion(),
@@ -1131,6 +1135,15 @@ public class AMQProtocolEngine implements ServerProtocolEngine, AMQProtocolSessi
_logger.debug("Client set closeWhenNoRoute=" + _closeWhenNoRoute + " for protocol engine " + this);
}
}
+ String compressionSupported = clientProperties.getString(ConnectionStartProperties.QPID_MESSAGE_COMPRESSION_SUPPORTED);
+ if (compressionSupported != null)
+ {
+ _compressionSupported = Boolean.parseBoolean(compressionSupported);
+ if(_logger.isDebugEnabled())
+ {
+ _logger.debug("Client set compressionSupported=" + _compressionSupported + " for protocol engine " + this);
+ }
+ }
_clientVersion = clientProperties.getString(ConnectionStartProperties.VERSION_0_8);
_clientProduct = clientProperties.getString(ConnectionStartProperties.PRODUCT);
@@ -1181,17 +1194,24 @@ public class AMQProtocolEngine implements ServerProtocolEngine, AMQProtocolSessi
return getMethodRegistry();
}
- public VirtualHostImpl getVirtualHost()
+ public VirtualHostImpl<?,?,?> getVirtualHost()
{
return _virtualHost;
}
- public void setVirtualHost(VirtualHostImpl virtualHost) throws AMQException
+ public void setVirtualHost(VirtualHostImpl<?,?,?> virtualHost) throws AMQException
{
_virtualHost = virtualHost;
_virtualHost.getConnectionRegistry().registerConnection(this);
+
+ _messageCompressionThreshold = virtualHost.getContextValue(Integer.class,
+ Broker.MESSAGE_COMPRESSION_THRESHOLD_SIZE);
+ if(_messageCompressionThreshold <= 0)
+ {
+ _messageCompressionThreshold = Integer.MAX_VALUE;
+ }
}
public void addDeleteTask(Action<? super AMQProtocolEngine> task)
@@ -1595,15 +1615,16 @@ public class AMQProtocolEngine implements ServerProtocolEngine, AMQProtocolSessi
}
@Override
- public void deliverToClient(final ConsumerImpl sub, final ServerMessage message,
+ public long deliverToClient(final ConsumerImpl sub, final ServerMessage message,
final InstanceProperties props, final long deliveryTag)
{
- registerMessageDelivered(message.getSize());
- _protocolOutputConverter.writeDeliver(message,
+ long size = _protocolOutputConverter.writeDeliver(message,
props,
_channelId,
deliveryTag,
new AMQShortString(sub.getName()));
+ registerMessageDelivered(size);
+ return size;
}
}
@@ -1636,6 +1657,18 @@ public class AMQProtocolEngine implements ServerProtocolEngine, AMQProtocolSessi
return _closeWhenNoRoute;
}
+ @Override
+ public boolean isCompressionSupported()
+ {
+ return _compressionSupported && _broker.isMessageCompressionEnabled();
+ }
+
+ @Override
+ public int getMessageCompressionThreshold()
+ {
+ return _messageCompressionThreshold;
+ }
+
public EventLogger getEventLogger()
{
if(_virtualHost != null)
diff --git a/qpid/java/broker-plugins/amqp-0-8-protocol/src/main/java/org/apache/qpid/server/protocol/v0_8/AMQProtocolSession.java b/qpid/java/broker-plugins/amqp-0-8-protocol/src/main/java/org/apache/qpid/server/protocol/v0_8/AMQProtocolSession.java
index bab0aaf3da..8d5142338a 100644
--- a/qpid/java/broker-plugins/amqp-0-8-protocol/src/main/java/org/apache/qpid/server/protocol/v0_8/AMQProtocolSession.java
+++ b/qpid/java/broker-plugins/amqp-0-8-protocol/src/main/java/org/apache/qpid/server/protocol/v0_8/AMQProtocolSession.java
@@ -174,9 +174,9 @@ public interface AMQProtocolSession<T extends AMQProtocolSession<T>>
Object getReference();
- VirtualHostImpl getVirtualHost();
+ VirtualHostImpl<?,?,?> getVirtualHost();
- void setVirtualHost(VirtualHostImpl virtualHost) throws AMQException;
+ void setVirtualHost(VirtualHostImpl<?,?,?> virtualHost) throws AMQException;
public ProtocolOutputConverter getProtocolOutputConverter();
@@ -210,4 +210,8 @@ public interface AMQProtocolSession<T extends AMQProtocolSession<T>>
* can't be routed rather than returning the message.
*/
boolean isCloseWhenNoRoute();
+
+ boolean isCompressionSupported();
+
+ int getMessageCompressionThreshold();
}
diff --git a/qpid/java/broker-plugins/amqp-0-8-protocol/src/main/java/org/apache/qpid/server/protocol/v0_8/ClientDeliveryMethod.java b/qpid/java/broker-plugins/amqp-0-8-protocol/src/main/java/org/apache/qpid/server/protocol/v0_8/ClientDeliveryMethod.java
index fa26a73f93..c7871e8b9a 100644
--- a/qpid/java/broker-plugins/amqp-0-8-protocol/src/main/java/org/apache/qpid/server/protocol/v0_8/ClientDeliveryMethod.java
+++ b/qpid/java/broker-plugins/amqp-0-8-protocol/src/main/java/org/apache/qpid/server/protocol/v0_8/ClientDeliveryMethod.java
@@ -26,6 +26,6 @@ import org.apache.qpid.server.message.ServerMessage;
public interface ClientDeliveryMethod
{
- void deliverToClient(final ConsumerImpl sub, final ServerMessage message, final InstanceProperties props,
+ long deliverToClient(final ConsumerImpl sub, final ServerMessage message, final InstanceProperties props,
final long deliveryTag);
}
diff --git a/qpid/java/broker-plugins/amqp-0-8-protocol/src/main/java/org/apache/qpid/server/protocol/v0_8/ConsumerTarget_0_8.java b/qpid/java/broker-plugins/amqp-0-8-protocol/src/main/java/org/apache/qpid/server/protocol/v0_8/ConsumerTarget_0_8.java
index 7c2efe64e6..d5eed242e7 100644
--- a/qpid/java/broker-plugins/amqp-0-8-protocol/src/main/java/org/apache/qpid/server/protocol/v0_8/ConsumerTarget_0_8.java
+++ b/qpid/java/broker-plugins/amqp-0-8-protocol/src/main/java/org/apache/qpid/server/protocol/v0_8/ConsumerTarget_0_8.java
@@ -116,7 +116,7 @@ public abstract class ConsumerTarget_0_8 extends AbstractConsumerTarget implemen
* @throws org.apache.qpid.AMQException
*/
@Override
- public void send(MessageInstance entry, boolean batch)
+ public long send(MessageInstance entry, boolean batch)
{
// We don't decrement the reference here as we don't want to consume the message
// but we do want to send it to the client.
@@ -124,7 +124,7 @@ public abstract class ConsumerTarget_0_8 extends AbstractConsumerTarget implemen
synchronized (getChannel())
{
long deliveryTag = getChannel().getNextDeliveryTag();
- sendToClient(entry.getMessage(), entry.getInstanceProperties(), deliveryTag);
+ return sendToClient(entry.getMessage(), entry.getInstanceProperties(), deliveryTag);
}
}
@@ -177,7 +177,7 @@ public abstract class ConsumerTarget_0_8 extends AbstractConsumerTarget implemen
* @param batch
*/
@Override
- public void send(MessageInstance entry, boolean batch)
+ public long send(MessageInstance entry, boolean batch)
{
// if we do not need to wait for client acknowledgements
// we can decrement the reference count immediately.
@@ -194,17 +194,17 @@ public abstract class ConsumerTarget_0_8 extends AbstractConsumerTarget implemen
MessageReference ref = message.newReference();
InstanceProperties props = entry.getInstanceProperties();
entry.delete();
-
+ long size;
synchronized (getChannel())
{
getChannel().getProtocolSession().setDeferFlush(batch);
long deliveryTag = getChannel().getNextDeliveryTag();
- sendToClient(message, props, deliveryTag);
+ size = sendToClient(message, props, deliveryTag);
}
ref.release();
-
+ return size;
}
@@ -291,7 +291,7 @@ public abstract class ConsumerTarget_0_8 extends AbstractConsumerTarget implemen
* @param batch
*/
@Override
- public void send(MessageInstance entry, boolean batch)
+ public long send(MessageInstance entry, boolean batch)
{
@@ -303,9 +303,9 @@ public abstract class ConsumerTarget_0_8 extends AbstractConsumerTarget implemen
addUnacknowledgedMessage(entry);
recordMessageDelivery(entry, deliveryTag);
entry.addStateChangeListener(getReleasedStateChangeListener());
- sendToClient(entry.getMessage(), entry.getInstanceProperties(), deliveryTag);
+ long size = sendToClient(entry.getMessage(), entry.getInstanceProperties(), deliveryTag);
entry.incrementDeliveryCount();
-
+ return size;
}
}
@@ -502,9 +502,9 @@ public abstract class ConsumerTarget_0_8 extends AbstractConsumerTarget implemen
}
}
- protected void sendToClient(final ServerMessage message, final InstanceProperties props, final long deliveryTag)
+ protected long sendToClient(final ServerMessage message, final InstanceProperties props, final long deliveryTag)
{
- _deliveryMethod.deliverToClient(getConsumer(), message, props, deliveryTag);
+ return _deliveryMethod.deliverToClient(getConsumer(), message, props, deliveryTag);
}
diff --git a/qpid/java/broker-plugins/amqp-0-8-protocol/src/main/java/org/apache/qpid/server/protocol/v0_8/handler/BasicGetMethodHandler.java b/qpid/java/broker-plugins/amqp-0-8-protocol/src/main/java/org/apache/qpid/server/protocol/v0_8/handler/BasicGetMethodHandler.java
index 0026bad063..c3bdedf44d 100644
--- a/qpid/java/broker-plugins/amqp-0-8-protocol/src/main/java/org/apache/qpid/server/protocol/v0_8/handler/BasicGetMethodHandler.java
+++ b/qpid/java/broker-plugins/amqp-0-8-protocol/src/main/java/org/apache/qpid/server/protocol/v0_8/handler/BasicGetMethodHandler.java
@@ -21,6 +21,9 @@
package org.apache.qpid.server.protocol.v0_8.handler;
+import java.security.AccessControlException;
+import java.util.EnumSet;
+
import org.apache.log4j.Logger;
import org.apache.qpid.AMQException;
@@ -30,26 +33,23 @@ import org.apache.qpid.framing.BasicGetEmptyBody;
import org.apache.qpid.framing.MethodRegistry;
import org.apache.qpid.protocol.AMQConstant;
import org.apache.qpid.server.consumer.ConsumerImpl;
+import org.apache.qpid.server.flow.FlowCreditManager;
+import org.apache.qpid.server.flow.MessageOnlyCreditManager;
import org.apache.qpid.server.message.InstanceProperties;
import org.apache.qpid.server.message.MessageInstance;
import org.apache.qpid.server.message.MessageSource;
import org.apache.qpid.server.message.ServerMessage;
import org.apache.qpid.server.protocol.v0_8.AMQChannel;
-import org.apache.qpid.server.flow.FlowCreditManager;
-import org.apache.qpid.server.flow.MessageOnlyCreditManager;
import org.apache.qpid.server.protocol.v0_8.AMQMessage;
import org.apache.qpid.server.protocol.v0_8.AMQProtocolSession;
+import org.apache.qpid.server.protocol.v0_8.ClientDeliveryMethod;
import org.apache.qpid.server.protocol.v0_8.ConsumerTarget_0_8;
-import org.apache.qpid.server.queue.AMQQueue;
+import org.apache.qpid.server.protocol.v0_8.RecordDeliveryMethod;
import org.apache.qpid.server.protocol.v0_8.state.AMQStateManager;
import org.apache.qpid.server.protocol.v0_8.state.StateAwareMethodListener;
-import org.apache.qpid.server.protocol.v0_8.ClientDeliveryMethod;
-import org.apache.qpid.server.protocol.v0_8.RecordDeliveryMethod;
+import org.apache.qpid.server.queue.AMQQueue;
import org.apache.qpid.server.virtualhost.VirtualHostImpl;
-import java.security.AccessControlException;
-import java.util.EnumSet;
-
public class BasicGetMethodHandler implements StateAwareMethodListener<BasicGetBody>
{
private static final Logger _log = Logger.getLogger(BasicGetMethodHandler.class);
@@ -202,17 +202,18 @@ public class BasicGetMethodHandler implements StateAwareMethodListener<BasicGetB
}
@Override
- public void deliverToClient(final ConsumerImpl sub, final ServerMessage message,
+ public long deliverToClient(final ConsumerImpl sub, final ServerMessage message,
final InstanceProperties props, final long deliveryTag)
{
_singleMessageCredit.useCreditForMessage(message.getSize());
- _session.getProtocolOutputConverter().writeGetOk(message,
+ long size =_session.getProtocolOutputConverter().writeGetOk(message,
props,
_channel.getChannelId(),
deliveryTag,
_queue.getQueueDepthMessages());
_deliveredMessage = true;
+ return size;
}
public boolean hasDeliveredMessage()
diff --git a/qpid/java/broker-plugins/amqp-0-8-protocol/src/main/java/org/apache/qpid/server/protocol/v0_8/output/ProtocolOutputConverter.java b/qpid/java/broker-plugins/amqp-0-8-protocol/src/main/java/org/apache/qpid/server/protocol/v0_8/output/ProtocolOutputConverter.java
index 7678ce812b..4ee5cbc17d 100644
--- a/qpid/java/broker-plugins/amqp-0-8-protocol/src/main/java/org/apache/qpid/server/protocol/v0_8/output/ProtocolOutputConverter.java
+++ b/qpid/java/broker-plugins/amqp-0-8-protocol/src/main/java/org/apache/qpid/server/protocol/v0_8/output/ProtocolOutputConverter.java
@@ -26,7 +26,6 @@
*/
package org.apache.qpid.server.protocol.v0_8.output;
-import org.apache.qpid.AMQException;
import org.apache.qpid.framing.AMQDataBlock;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.framing.ContentHeaderBody;
@@ -35,7 +34,6 @@ import org.apache.qpid.server.message.InstanceProperties;
import org.apache.qpid.server.message.MessageContentSource;
import org.apache.qpid.server.message.ServerMessage;
import org.apache.qpid.server.protocol.v0_8.AMQProtocolSession;
-import org.apache.qpid.server.queue.QueueEntry;
public interface ProtocolOutputConverter
{
@@ -46,12 +44,12 @@ public interface ProtocolOutputConverter
ProtocolOutputConverter newInstance(AMQProtocolSession session);
}
- void writeDeliver(final ServerMessage msg,
+ long writeDeliver(final ServerMessage msg,
final InstanceProperties props, int channelId,
long deliveryTag,
AMQShortString consumerTag);
- void writeGetOk(final ServerMessage msg,
+ long writeGetOk(final ServerMessage msg,
final InstanceProperties props,
int channelId,
long deliveryTag,
diff --git a/qpid/java/broker-plugins/amqp-0-8-protocol/src/main/java/org/apache/qpid/server/protocol/v0_8/output/ProtocolOutputConverterImpl.java b/qpid/java/broker-plugins/amqp-0-8-protocol/src/main/java/org/apache/qpid/server/protocol/v0_8/output/ProtocolOutputConverterImpl.java
index f786cb113a..9e41f7884c 100644
--- a/qpid/java/broker-plugins/amqp-0-8-protocol/src/main/java/org/apache/qpid/server/protocol/v0_8/output/ProtocolOutputConverterImpl.java
+++ b/qpid/java/broker-plugins/amqp-0-8-protocol/src/main/java/org/apache/qpid/server/protocol/v0_8/output/ProtocolOutputConverterImpl.java
@@ -20,6 +20,10 @@
*/
package org.apache.qpid.server.protocol.v0_8.output;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
import org.apache.qpid.AMQException;
import org.apache.qpid.framing.AMQBody;
import org.apache.qpid.framing.AMQDataBlock;
@@ -27,6 +31,7 @@ import org.apache.qpid.framing.AMQFrame;
import org.apache.qpid.framing.AMQMethodBody;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.framing.BasicCancelOkBody;
+import org.apache.qpid.framing.BasicContentHeaderProperties;
import org.apache.qpid.framing.BasicGetOkBody;
import org.apache.qpid.framing.BasicReturnBody;
import org.apache.qpid.framing.ContentHeaderBody;
@@ -34,16 +39,13 @@ import org.apache.qpid.framing.MethodRegistry;
import org.apache.qpid.framing.abstraction.MessagePublishInfo;
import org.apache.qpid.protocol.AMQVersionAwareProtocolSession;
import org.apache.qpid.server.message.InstanceProperties;
+import org.apache.qpid.server.message.MessageContentSource;
import org.apache.qpid.server.message.ServerMessage;
import org.apache.qpid.server.plugin.MessageConverter;
import org.apache.qpid.server.protocol.MessageConverterRegistry;
import org.apache.qpid.server.protocol.v0_8.AMQMessage;
-import org.apache.qpid.server.message.MessageContentSource;
import org.apache.qpid.server.protocol.v0_8.AMQProtocolSession;
-
-import java.io.DataOutput;
-import java.io.IOException;
-import java.nio.ByteBuffer;
+import org.apache.qpid.util.GZIPUtils;
class ProtocolOutputConverterImpl implements ProtocolOutputConverter
{
@@ -51,6 +53,7 @@ class ProtocolOutputConverterImpl implements ProtocolOutputConverter
private final MethodRegistry _methodRegistry;
private final AMQProtocolSession _protocolSession;
+ private static final AMQShortString GZIP_ENCODING = AMQShortString.valueOf(GZIPUtils.GZIP_CONTENT_ENCODING);
ProtocolOutputConverterImpl(AMQProtocolSession session, MethodRegistry methodRegistry)
{
@@ -64,7 +67,7 @@ class ProtocolOutputConverterImpl implements ProtocolOutputConverter
return _protocolSession;
}
- public void writeDeliver(final ServerMessage m,
+ public long writeDeliver(final ServerMessage m,
final InstanceProperties props, int channelId,
long deliveryTag,
AMQShortString consumerTag)
@@ -72,7 +75,7 @@ class ProtocolOutputConverterImpl implements ProtocolOutputConverter
final AMQMessage msg = convertToAMQMessage(m);
final boolean isRedelivered = Boolean.TRUE.equals(props.getProperty(InstanceProperties.Property.REDELIVERED));
AMQBody deliverBody = createEncodedDeliverBody(msg, isRedelivered, deliveryTag, consumerTag);
- writeMessageDelivery(msg, channelId, deliverBody);
+ return writeMessageDelivery(msg, channelId, deliverBody);
}
private AMQMessage convertToAMQMessage(ServerMessage serverMessage)
@@ -93,21 +96,97 @@ class ProtocolOutputConverterImpl implements ProtocolOutputConverter
return MessageConverterRegistry.getConverter(clazz, AMQMessage.class);
}
- private void writeMessageDelivery(AMQMessage message, int channelId, AMQBody deliverBody)
+ private long writeMessageDelivery(AMQMessage message, int channelId, AMQBody deliverBody)
{
- writeMessageDelivery(message, message.getContentHeaderBody(), channelId, deliverBody);
+ return writeMessageDelivery(message, message.getContentHeaderBody(), channelId, deliverBody);
}
- private void writeMessageDelivery(MessageContentSource message, ContentHeaderBody contentHeaderBody, int channelId, AMQBody deliverBody)
+ private long writeMessageDelivery(MessageContentSource message, ContentHeaderBody contentHeaderBody, int channelId, AMQBody deliverBody)
{
-
int bodySize = (int) message.getSize();
+ boolean msgCompressed = isCompressed(contentHeaderBody);
+ byte[] modifiedContent;
+
+ // straight through case
+ boolean compressionSupported = _protocolSession.isCompressionSupported();
+
+ if(msgCompressed && !compressionSupported &&
+ (modifiedContent = GZIPUtils.uncompressBufferToArray(message.getContent(0,bodySize))) != null)
+ {
+ BasicContentHeaderProperties modifiedProps =
+ new BasicContentHeaderProperties(contentHeaderBody.getProperties());
+ modifiedProps.setEncoding((String)null);
+
+ writeMessageDeliveryModified(channelId, deliverBody, modifiedProps, modifiedContent);
+
+ return modifiedContent.length;
+ }
+ else if(!msgCompressed
+ && compressionSupported
+ && contentHeaderBody.getProperties().getEncoding()==null
+ && bodySize > _protocolSession.getMessageCompressionThreshold()
+ && (modifiedContent = GZIPUtils.compressBufferToArray(message.getContent(0, bodySize))) != null)
+ {
+ BasicContentHeaderProperties modifiedProps =
+ new BasicContentHeaderProperties(contentHeaderBody.getProperties());
+ modifiedProps.setEncoding(GZIP_ENCODING);
+
+ writeMessageDeliveryModified(channelId, deliverBody, modifiedProps, modifiedContent);
+
+ return modifiedContent.length;
+ }
+ else
+ {
+ writeMessageDeliveryUnchanged(message, contentHeaderBody, channelId, deliverBody, bodySize);
+
+ return bodySize;
+ }
+ }
- if(bodySize == 0)
+ private int writeMessageDeliveryModified(final int channelId,
+ final AMQBody deliverBody,
+ final BasicContentHeaderProperties modifiedProps,
+ final byte[] content)
+ {
+ final int bodySize;
+ bodySize = content.length;
+ ContentHeaderBody modifiedHeaderBody =
+ new ContentHeaderBody(BASIC_CLASS_ID, 0, modifiedProps, bodySize);
+ final MessageContentSource wrappedSource = new MessageContentSource()
+ {
+ @Override
+ public int getContent(final ByteBuffer buf, final int offset)
+ {
+ int size = Math.min(buf.remaining(), content.length - offset);
+ buf.put(content, offset, size);
+ return size;
+ }
+
+ @Override
+ public ByteBuffer getContent(final int offset, final int size)
+ {
+ return ByteBuffer.wrap(content, offset, size);
+ }
+
+ @Override
+ public long getSize()
+ {
+ return content.length;
+ }
+ };
+ writeMessageDeliveryUnchanged(wrappedSource, modifiedHeaderBody, channelId, deliverBody, bodySize);
+ return bodySize;
+ }
+
+ private void writeMessageDeliveryUnchanged(final MessageContentSource message,
+ final ContentHeaderBody contentHeaderBody,
+ final int channelId, final AMQBody deliverBody, final int bodySize)
+ {
+ if (bodySize == 0)
{
SmallCompositeAMQBodyBlock compositeBlock = new SmallCompositeAMQBodyBlock(channelId, deliverBody,
- contentHeaderBody);
+ contentHeaderBody);
writeFrame(compositeBlock);
}
@@ -120,13 +199,14 @@ class ProtocolOutputConverterImpl implements ProtocolOutputConverter
int writtenSize = capacity;
- AMQBody firstContentBody = new MessageContentSourceBody(message,0,capacity);
+ AMQBody firstContentBody = new MessageContentSourceBody(message, 0, capacity);
CompositeAMQBodyBlock
- compositeBlock = new CompositeAMQBodyBlock(channelId, deliverBody, contentHeaderBody, firstContentBody);
+ compositeBlock =
+ new CompositeAMQBodyBlock(channelId, deliverBody, contentHeaderBody, firstContentBody);
writeFrame(compositeBlock);
- while(writtenSize < bodySize)
+ while (writtenSize < bodySize)
{
capacity = bodySize - writtenSize > maxBodySize ? maxBodySize : bodySize - writtenSize;
MessageContentSourceBody body = new MessageContentSourceBody(message, writtenSize, capacity);
@@ -137,6 +217,11 @@ class ProtocolOutputConverterImpl implements ProtocolOutputConverter
}
}
+ private boolean isCompressed(final ContentHeaderBody contentHeaderBody)
+ {
+ return GZIP_ENCODING.equals(contentHeaderBody.getProperties().getEncoding());
+ }
+
private class MessageContentSourceBody implements AMQBody
{
public static final byte TYPE = 3;
@@ -186,14 +271,14 @@ class ProtocolOutputConverterImpl implements ProtocolOutputConverter
}
}
- public void writeGetOk(final ServerMessage msg,
+ public long writeGetOk(final ServerMessage msg,
final InstanceProperties props,
int channelId,
long deliveryTag,
int queueSize)
{
AMQBody deliver = createEncodedGetOkBody(msg, props, deliveryTag, queueSize);
- writeMessageDelivery(convertToAMQMessage(msg), channelId, deliver);
+ return writeMessageDelivery(convertToAMQMessage(msg), channelId, deliver);
}
diff --git a/qpid/java/broker-plugins/amqp-0-8-protocol/src/test/java/org/apache/qpid/server/protocol/v0_8/InternalTestProtocolSession.java b/qpid/java/broker-plugins/amqp-0-8-protocol/src/test/java/org/apache/qpid/server/protocol/v0_8/InternalTestProtocolSession.java
index 7f4a3701cd..05ae5285ad 100644
--- a/qpid/java/broker-plugins/amqp-0-8-protocol/src/test/java/org/apache/qpid/server/protocol/v0_8/InternalTestProtocolSession.java
+++ b/qpid/java/broker-plugins/amqp-0-8-protocol/src/test/java/org/apache/qpid/server/protocol/v0_8/InternalTestProtocolSession.java
@@ -141,13 +141,13 @@ public class InternalTestProtocolSession extends AMQProtocolEngine implements Pr
{
}
- public void writeDeliver(final ServerMessage msg,
+ public long writeDeliver(final ServerMessage msg,
final InstanceProperties props, int channelId,
long deliveryTag,
AMQShortString consumerTag)
{
_deliveryCount.incrementAndGet();
-
+ long size = msg.getSize();
synchronized (_channelDelivers)
{
Map<String, LinkedList<DeliveryPair>> consumers = _channelDelivers.get(channelId);
@@ -168,14 +168,16 @@ public class InternalTestProtocolSession extends AMQProtocolEngine implements Pr
consumerDelivers.add(new DeliveryPair(deliveryTag, msg));
}
+ return size;
}
- public void writeGetOk(final ServerMessage msg,
+ public long writeGetOk(final ServerMessage msg,
final InstanceProperties props,
int channelId,
long deliveryTag,
int queueSize)
{
+ return msg.getSize();
}
public void awaitDelivery(int msgs)
@@ -244,11 +246,11 @@ public class InternalTestProtocolSession extends AMQProtocolEngine implements Pr
@Override
- public void deliverToClient(ConsumerImpl sub, ServerMessage message,
+ public long deliverToClient(ConsumerImpl sub, ServerMessage message,
InstanceProperties props, long deliveryTag)
{
_deliveryCount.incrementAndGet();
-
+ long size = message.getSize();
synchronized (_channelDelivers)
{
Map<String, LinkedList<DeliveryPair>> consumers = _channelDelivers.get(_channelId);
@@ -269,6 +271,7 @@ public class InternalTestProtocolSession extends AMQProtocolEngine implements Pr
consumerDelivers.add(new DeliveryPair(deliveryTag, message));
}
+ return size;
}
}
diff --git a/qpid/java/broker-plugins/amqp-1-0-protocol/src/main/java/org/apache/qpid/server/protocol/v1_0/ConsumerTarget_1_0.java b/qpid/java/broker-plugins/amqp-1-0-protocol/src/main/java/org/apache/qpid/server/protocol/v1_0/ConsumerTarget_1_0.java
index bceae85896..918a890af5 100644
--- a/qpid/java/broker-plugins/amqp-1-0-protocol/src/main/java/org/apache/qpid/server/protocol/v1_0/ConsumerTarget_1_0.java
+++ b/qpid/java/broker-plugins/amqp-1-0-protocol/src/main/java/org/apache/qpid/server/protocol/v1_0/ConsumerTarget_1_0.java
@@ -112,10 +112,12 @@ class ConsumerTarget_1_0 extends AbstractConsumerTarget
}
}
- public void send(MessageInstance entry, boolean batch)
+ public long send(MessageInstance entry, boolean batch)
{
// TODO
+ long size = entry.getMessage().getSize();
send(entry);
+ return size;
}
public void flushBatched()
diff --git a/qpid/java/broker-plugins/amqp-1-0-protocol/src/main/java/org/apache/qpid/server/protocol/v1_0/MessageConverter_to_1_0.java b/qpid/java/broker-plugins/amqp-1-0-protocol/src/main/java/org/apache/qpid/server/protocol/v1_0/MessageConverter_to_1_0.java
index 5b9bdc7244..3572b98cad 100644
--- a/qpid/java/broker-plugins/amqp-1-0-protocol/src/main/java/org/apache/qpid/server/protocol/v1_0/MessageConverter_to_1_0.java
+++ b/qpid/java/broker-plugins/amqp-1-0-protocol/src/main/java/org/apache/qpid/server/protocol/v1_0/MessageConverter_to_1_0.java
@@ -32,6 +32,7 @@ import org.apache.qpid.amqp_1_0.messaging.SectionEncoder;
import org.apache.qpid.amqp_1_0.messaging.SectionEncoderImpl;
import org.apache.qpid.amqp_1_0.type.Binary;
import org.apache.qpid.amqp_1_0.type.Section;
+import org.apache.qpid.amqp_1_0.type.Symbol;
import org.apache.qpid.amqp_1_0.type.codec.AMQPDescribedTypeRegistry;
import org.apache.qpid.amqp_1_0.type.messaging.AmqpValue;
import org.apache.qpid.amqp_1_0.type.messaging.Data;
@@ -43,6 +44,7 @@ import org.apache.qpid.server.virtualhost.VirtualHostImpl;
import org.apache.qpid.transport.codec.BBDecoder;
import org.apache.qpid.typedmessage.TypedBytesContentReader;
import org.apache.qpid.typedmessage.TypedBytesFormatException;
+import org.apache.qpid.util.GZIPUtils;
public abstract class MessageConverter_to_1_0<M extends ServerMessage> implements MessageConverter<M, Message_1_0>
{
@@ -202,7 +204,19 @@ public abstract class MessageConverter_to_1_0<M extends ServerMessage> implement
SectionEncoder sectionEncoder)
{
final String mimeType = serverMessage.getMessageHeader().getMimeType();
- Section bodySection = getBodySection(serverMessage, mimeType);
+ byte[] data = new byte[(int) serverMessage.getSize()];
+ serverMessage.getContent(ByteBuffer.wrap(data), 0);
+ byte[] uncompressed;
+
+ if(Symbol.valueOf(GZIPUtils.GZIP_CONTENT_ENCODING).equals(metaData.getPropertiesSection().getContentEncoding())
+ && (uncompressed = GZIPUtils.uncompressBufferToArray(ByteBuffer.wrap(data)))!=null)
+ {
+ data = uncompressed;
+ metaData.getPropertiesSection().setContentEncoding(null);
+ }
+
+
+ Section bodySection = convertMessageBody(mimeType, data);
final ByteBuffer allData = encodeConvertedMessage(metaData, bodySection, sectionEncoder);
@@ -279,14 +293,6 @@ public abstract class MessageConverter_to_1_0<M extends ServerMessage> implement
};
}
- protected Section getBodySection(final M serverMessage, final String mimeType)
- {
- byte[] data = new byte[(int) serverMessage.getSize()];
- serverMessage.getContent(ByteBuffer.wrap(data), 0);
-
- return convertMessageBody(mimeType, data);
- }
-
private ByteBuffer encodeConvertedMessage(MessageMetaData_1_0 metaData, Section bodySection, SectionEncoder sectionEncoder)
{
int headerSize = (int) metaData.getStorableSize();
diff --git a/qpid/java/broker-plugins/amqp-1-0-protocol/src/main/java/org/apache/qpid/server/protocol/v1_0/MessageMetaData_1_0.java b/qpid/java/broker-plugins/amqp-1-0-protocol/src/main/java/org/apache/qpid/server/protocol/v1_0/MessageMetaData_1_0.java
index 4540308f61..fbc24ba454 100755
--- a/qpid/java/broker-plugins/amqp-1-0-protocol/src/main/java/org/apache/qpid/server/protocol/v1_0/MessageMetaData_1_0.java
+++ b/qpid/java/broker-plugins/amqp-1-0-protocol/src/main/java/org/apache/qpid/server/protocol/v1_0/MessageMetaData_1_0.java
@@ -72,6 +72,17 @@ public class MessageMetaData_1_0 implements StorableMessageMetaData
this(sections, encodeSections(sections, encoder));
}
+ public Properties getPropertiesSection()
+ {
+ return _properties;
+ }
+
+
+ public Header getHeaderSection()
+ {
+ return _header;
+ }
+
private static ArrayList<ByteBuffer> encodeSections(final List<Section> sections, final SectionEncoder encoder)
{
ArrayList<ByteBuffer> encodedSections = new ArrayList<ByteBuffer>(sections.size());
diff --git a/qpid/java/broker-plugins/derby-store/src/main/java/resources/js/qpid/management/virtualhost/derby/edit.js b/qpid/java/broker-plugins/derby-store/src/main/java/resources/js/qpid/management/virtualhost/derby/edit.js
index c71c2c28de..3a3107b01a 100644
--- a/qpid/java/broker-plugins/derby-store/src/main/java/resources/js/qpid/management/virtualhost/derby/edit.js
+++ b/qpid/java/broker-plugins/derby-store/src/main/java/resources/js/qpid/management/virtualhost/derby/edit.js
@@ -16,8 +16,8 @@
* specific language governing permissions and limitations
* under the License.
*/
-define(["qpid/common/util", "dojo/domReady!"],
- function (util)
+define(["qpid/common/util", "dijit/registry", "dojo/domReady!"],
+ function (util, registry)
{
var fieldNames = ["storeUnderfullSize", "storeOverfullSize", "storePath"];
return {
diff --git a/qpid/java/broker-plugins/derby-store/src/main/java/resources/virtualhostnode/derby/add.html b/qpid/java/broker-plugins/derby-store/src/main/java/resources/virtualhostnode/derby/add.html
index 0ec1e89c24..4e82ab09e9 100644
--- a/qpid/java/broker-plugins/derby-store/src/main/java/resources/virtualhostnode/derby/add.html
+++ b/qpid/java/broker-plugins/derby-store/src/main/java/resources/virtualhostnode/derby/add.html
@@ -27,7 +27,8 @@
data-dojo-props="
name: 'storePath',
placeHolder: 'path/to/store',
- title: 'Enter store path'" />
+ title: 'Enter store path',
+ promptMessage: 'File system location for the configuration store'"/>
</div>
</div>
<div class="clear"></div>
diff --git a/qpid/java/broker-plugins/jdbc-store/src/main/java/resources/virtualhostnode/jdbc/add.html b/qpid/java/broker-plugins/jdbc-store/src/main/java/resources/virtualhostnode/jdbc/add.html
index f60f54e7d8..f9561d4c51 100644
--- a/qpid/java/broker-plugins/jdbc-store/src/main/java/resources/virtualhostnode/jdbc/add.html
+++ b/qpid/java/broker-plugins/jdbc-store/src/main/java/resources/virtualhostnode/jdbc/add.html
@@ -28,7 +28,7 @@
name: 'connectionUrl',
placeHolder: 'jdbc:provider:info',
required: true,
- missingMessage: 'JDBC URL must be supplied',
+ promptMessage: 'JDBC URL specifying the connection to the database',
title: 'Enter JDBC URL'"/>
</div>
</div>
@@ -41,7 +41,7 @@
name: 'username',
placeHolder: 'username',
required: true,
- missingMessage: 'Username must be supplied',
+ promptMessage: 'Database user name',
title: 'Enter username'" />
</div>
</div>
@@ -54,7 +54,7 @@
name: 'password',
placeHolder: 'password',
required: true,
- missingMessage: 'Password must be supplied',
+ promptMessage: 'Database password',
title: 'Enter password'" />
</div>
</div>
@@ -66,8 +66,8 @@
data-dojo-props="
name: 'connectionPoolType',
required: true,
- missingMessage: 'Connection Pool type must be supplied',
- title: 'Select Connection Pool',
+ promptMessage: 'Connection pool type to use when connecting to the database',
+ title: 'Select the connection pool type',
placeHolder: 'Select pool type'" />
</div>
</div>
diff --git a/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/MessageServlet.java b/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/MessageServlet.java
index 8de74d189b..cb77735a7b 100644
--- a/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/MessageServlet.java
+++ b/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/MessageServlet.java
@@ -143,7 +143,12 @@ public class MessageServlet extends AbstractServlet
throw new IllegalArgumentException("Could not find virtual host with name '" + vhostName + "'");
}
- return getQueueFromVirtualHost(queueName, vhost);
+ Queue queueFromVirtualHost = getQueueFromVirtualHost(queueName, vhost);
+ if (queueFromVirtualHost == null)
+ {
+ throw new IllegalArgumentException("Could not find queue with name '" + queueName + "' on virtual host '" + vhost.getName() + "'");
+ }
+ return queueFromVirtualHost;
}
private Queue getQueueFromVirtualHost(String queueName, VirtualHost<?,?,?> vhost)
diff --git a/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/MetaDataServlet.java b/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/MetaDataServlet.java
index c84eb3200b..35eff5c0b7 100644
--- a/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/MetaDataServlet.java
+++ b/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/MetaDataServlet.java
@@ -22,6 +22,7 @@ package org.apache.qpid.server.management.plugin.servlet.rest;
import java.io.IOException;
import java.io.Writer;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.Map;
@@ -52,8 +53,12 @@ public class MetaDataServlet extends AbstractServlet
super.init();
_instance = BrokerModel.getInstance();
+
+
}
+
+
@Override
protected void doGetWithSubjectAndActor(final HttpServletRequest request, final HttpServletResponse response)
throws ServletException, IOException
@@ -124,6 +129,18 @@ public class MetaDataServlet extends AbstractServlet
{
attrDetails.put("mandatory",((ConfiguredAutomatedAttribute)attribute).isMandatory());
}
+ if(!(((ConfiguredAutomatedAttribute)attribute).validValues()).isEmpty())
+ {
+ Collection<String> validValues = ((ConfiguredAutomatedAttribute<?,?>) attribute).validValues();
+
+ Collection<Object> convertedValues = new ArrayList<>(validValues.size());
+ for(String value : validValues)
+ {
+ convertedValues.add(attribute.convert(value,null));
+ }
+ attrDetails.put("validValues", convertedValues);
+ }
+
}
if(attribute.isSecure())
{
diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/addBinding.html b/qpid/java/broker-plugins/management-http/src/main/java/resources/addBinding.html
index a07419977b..1b30c6ddcc 100644
--- a/qpid/java/broker-plugins/management-http/src/main/java/resources/addBinding.html
+++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/addBinding.html
@@ -39,7 +39,7 @@
name: 'name',
placeHolder: 'Binding Key',
required: true,
- missingMessage: 'A binding key must be supplied',
+ promptMessage: 'Binding key',
title: 'Enter binding key'" />
</div>
</div>
diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/addExchange.html b/qpid/java/broker-plugins/management-http/src/main/java/resources/addExchange.html
index 8c9968e37a..77d5ed0bc1 100644
--- a/qpid/java/broker-plugins/management-http/src/main/java/resources/addExchange.html
+++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/addExchange.html
@@ -21,32 +21,53 @@
<div class="dijitHidden">
<div data-dojo-type="dijit.Dialog" style="width:600px;" data-dojo-props="title:'Add Exchange'" id="addExchange">
<form id="formAddExchange" method="post" dojoType="dijit.form.Form">
- <table cellpadding="0" cellspacing="2">
- <tr>
- <td valign="top"><strong>Exchange Name*: </strong></td>
- <td><input type="text" required="true" name="name" id="formAddExchange.name" placeholder="Exchange Name"
- dojoType="dijit.form.ValidationTextBox" missingMessage="A name must be supplied"
- data-dojo-props="regExp:'^(?!qpid\.|amq\.|\<\<default\>\>)[\x20-\x2e\x30-\x7F]{1,255}$', invalidMessage:'Illegal or reserved exchange name!'"/></td>
- </tr>
- <tr>
- <td valign="top"><strong>Durable? </strong></td>
- <td><input type="checkbox" name="durable" id="formAddExchange.durable" value="durable" checked="checked" dojoType="dijit.form.CheckBox" /></td>
- </tr>
- <tr>
- <td valign="top"><strong>Exchange Type: </strong></td>
- <td>
- <select name="type" id="formAddExchange.type" dojoType="dijit.form.FilteringSelect">
- <option value="direct">direct</option>
- <option value="topic">topic</option>
- <option value="headers">headers</option>
- <option value="fanout">fanout</option>
- </select>
- </td>
- </tr>
- </table>
+ <div class="clear">
+ <div class="formLabel-labelCell">Name*:</div>
+ <div class="formLabel-controlCell">
+ <input type="text" id="formAddExchange.name"
+ data-dojo-type="dijit/form/ValidationTextBox"
+ data-dojo-props="
+ name: 'name',
+ placeHolder: 'exchange name',
+ required: true,
+ promptMessage: 'Name of exchange',
+ title: 'Enter an exchange name',
+ regExp:'^(?!qpid\.|amq\.|\<\<default\>\>)[\x20-\x2e\x30-\x7F]{1,255}$',
+ invalidMessage:'Illegal or reserved exchange name!'"/>
+ </div>
+ </div>
+ <div class="clear">
+ <div class="formLabel-labelCell">Exchange Type:</div>
+ <div class="formLabel-controlCell">
+ <select id="formAddExchange.type"
+ dojoType="dijit.form.FilteringSelect"
+ data-dojo-props="
+ name: 'type',
+ promptMessage: 'Type of exchange - responsible for routing messages to queues'">
+ <option value="direct">direct</option>
+ <option value="topic">topic</option>
+ <option value="headers">headers</option>
+ <option value="fanout">fanout</option>
+ </select>
+ </div>
+ </div>
+ <div class="clear">
+ <div class="formLabel-labelCell">Durable?</div>
+ <div class="formLabel-controlCell">
+ <input type="checkbox" id="formAddExchange.durable"
+ dojoType="dijit.form.CheckBox"
+ data-dojo-props="
+ name: 'durable',
+ value: 'durable',
+ checked: true"/>
+ </div>
+ </div>
+
+
+ <div class="clear"></div>
+
<div class="dijitDialogPaneActionBar">
- <!-- submit buttons -->
- <input type="submit" value="Create Exchange" label="Create Exchange" dojoType="dijit.form.Button" />
+ <input type="submit" value="Create Exchange" label="Create Exchange" dojoType="dijit.form.Button" />
</div>
</form>
</div>
diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/addPort.html b/qpid/java/broker-plugins/management-http/src/main/java/resources/addPort.html
index 69d49248b8..a0f1d6d440 100644
--- a/qpid/java/broker-plugins/management-http/src/main/java/resources/addPort.html
+++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/addPort.html
@@ -20,94 +20,267 @@
-->
<div class="dijitHidden">
<div data-dojo-type="dijit.Dialog" data-dojo-props="title:'Port'" id="addPort">
- <form id="formAddPort" method="post" dojoType="dijit.form.Form">
- <div style="height:320px; width:420px; overflow: auto">
- <div class="hidden" id="portEditWarning">NOTE: changes will only take effect after Broker restart.</div>
+ <form id="formAddPort" method="post" data-dojo-type="dijit.form.Form">
+ <div class="hidden infoMessage" id="portEditWarning">NOTE: changes will only take effect after Broker restart.</div>
<div id="formAddPort:fields">
- <input type="text" required="true" name="name" id="formAddPort.name" placeholder="Name"
- data-dojo-props="label: 'Name*:'" dojoType="dijit.form.ValidationTextBox"
- missingMessage="A name must be supplied"/>
- <input type="text" required="true" id="formAddPort.port"
- data-dojo-props="label: 'Port Number*:', placeHolder: 'Enter port number'" dojoType="dijit.form.ValidationTextBox"
- name="port" missingMessage="A port number must be supplied"/>
- <select id="formAddPort.type" data-dojo-type="dijit.form.FilteringSelect"
- data-dojo-props="name: 'type', value: '',placeHolder: 'Select Port Type', label: 'Port Type*:'">
- <option value="AMQP" selected="selected">AMQP</option>
- <option value="JMX">JMX</option>
- <option value="HTTP">HTTP</option>
- </select>
+ <div class="clear">
+ <div class="formLabel-labelCell">
+ <label for="formAddPort.name">Name*:</label>
+ </div>
+ <div class="formLabel-controlCell">
+ <input id="formAddPort.name" type="text"
+ data-dojo-type="dijit.form.ValidationTextBox"
+ data-dojo-props="
+ name: 'name',
+ required: 'true',
+ placeHolder: 'name',
+ promptMessage: 'Name of port, must be unique',
+ title: 'Enter name of port'"/>
+ </div>
+ </div>
+ <div class="clear">
+ <div class="formLabel-labelCell">
+ <label for="formAddPort.port">Port Number*:</label>
+ </div>
+ <div class="formLabel-controlCell">
+ <input id="formAddPort.port" type="text"
+ data-dojo-type="dijit.form.ValidationTextBox"
+ data-dojo-props="
+ name: 'port',
+ required: 'true',
+ placeHolder: 'port number',
+ promptMessage: 'Port number to be bound',
+ title: 'Enter port number'"/>
+ </div>
+ </div>
+ <div class="clear">
+ <div class="formLabel-labelCell">
+ <label for="formAddPort.type">Port Type*:</label>
+ </div>
+ <div class="formLabel-controlCell">
+ <select id="formAddPort.type"
+ data-dojo-type="dijit.form.FilteringSelect"
+ data-dojo-props="
+ name: 'type',
+ label: 'Port Type*:',
+ value: '',
+ placeHolder: 'port type',
+ promptMessage: 'Port type',
+ title: 'Enter port type'">
+ <option value="AMQP" selected="selected">AMQP</option>
+ <option value="JMX">JMX</option>
+ <option value="HTTP">HTTP</option>
+ </select>
+ </div>
+ </div>
</div>
<div id="formAddPort:fieldsAuthenticationProvider">
- <select id="formAddPort.authenticationProvider" data-dojo-type="dijit.form.FilteringSelect"
- data-dojo-props="name:'authenticationProvider',label:'Authentication Provider*:', searchAttr: 'name', required: true, placeHolder: 'Select Provider'">
- </select>
+ <div class="clear">
+ <div class="formLabel-labelCell">
+ <label for="formAddPort.authenticationProvider">Authentication Provider*:</label>
+ </div>
+ <div class="formLabel-controlCell">
+ <select id="formAddPort.authenticationProvider"
+ data-dojo-type="dijit.form.FilteringSelect"
+ data-dojo-props="
+ name: 'authenticationProvider',
+ searchAttr: 'name',
+ required: true,
+ placeHolder: 'provider',
+ promptMessage: 'Authentication provider to authenticate users connecting to the port',
+ title: 'Associate the port with an authentication provider'">
+ </select>
+ </div>
+ </div>
</div>
<div id="formAddPort:fieldsBindingAddress">
- <input id="formAddPort.bindingAddress" type="text" name="bindingAddress" placeholder="*"
- dojoType="dijit.form.TextBox" data-dojo-props="label: 'Binding address:'"/>
+ <div class="clear">
+ <div class="formLabel-labelCell">
+ <label for="formAddPort.bindingAddress">Binding address:</label>
+ </div>
+ <div class="formLabel-controlCell">
+ <input id="formAddPort.bindingAddress" type="text"
+ data-dojo-type="dijit.form.ValidationTextBox"
+ data-dojo-props="
+ name: 'bindingAddress',
+ placeHolder: 'binding address',
+ promptMessage: 'Restricts the port to listen on the specified address only. The <code>*</code> wildcard signifies all addresses',
+ title: 'Enter a binding address'"/>
+ </div>
+ </div>
</div>
<div id="formAddPort:fieldsAMQP">
- <input id="formAddPort.protocolsDefault" type="checkbox" checked="checked"
- dojoType="dijit.form.CheckBox" data-dojo-props="label: 'Support default protocols:'"/>
- <select id="formAddPort.protocolsAMQP" name="protocols" data-dojo-type="dijit.form.MultiSelect" multiple="true"
- data-dojo-props="name: 'protocols', value: '', placeHolder: 'Select AMQP versions', label: 'AMQP versions:'"
- missingMessage="AMQP protocol(s) must be supplied">
- <option value="AMQP_0_8">AMQP 0.8</option>
- <option value="AMQP_0_9">AMQP 0.9</option>
- <option value="AMQP_0_9_1">AMQP 0.9.1</option>
- <option value="AMQP_0_10">AMQP 0.10</option>
- <option value="AMQP_1_0">AMQP 1.0</option>
- </select>
+ <div class="clear">
+ <div class="formLabel-labelCell">
+ <label for="formAddPort.protocolsDefault">Support default protocols:</label>
+ </div>
+ <div class="formLabel-controlCell">
+ <input id="formAddPort.protocolsDefault" type="checkbox"
+ dojoType="dijit.form.CheckBox"
+ data-dojo-props="checked: true"/>
+ </div>
+ </div>
+ <div class="clear">
+ <div class="formLabel-labelCell">
+ <label for="formAddPort.protocolsAMQP">AMQP protocols:</label>
+ </div>
+ <div class="formLabel-controlCell">
+ <select id="formAddPort.protocolsAMQP"
+ data-dojo-type="dijit.form.MultiSelect"
+ data-dojo-props="
+ name: 'protocols',
+ value: '',
+ placeHolder: 'AMQP protocols',
+ promptMessage: 'AMQP protocols to be associated with this port',
+ title: 'Select AMQP protocols to be associated with this port',
+ multiple: true">
+ <option value="AMQP_0_8">AMQP 0.8</option>
+ <option value="AMQP_0_9">AMQP 0.9</option>
+ <option value="AMQP_0_9_1">AMQP 0.9.1</option>
+ <option value="AMQP_0_10">AMQP 0.10</option>
+ <option value="AMQP_1_0">AMQP 1.0</option>
+ </select>
+ </div>
+ </div>
</div>
<div id="formAddPort:fieldsJMX">
- <select id="formAddPort.protocolsJMX" name="protocols" data-dojo-type="dijit.form.FilteringSelect"
- data-dojo-props="name: 'protocols', value: '', label: 'JMX protocol*:'" missingMessage="JMX protocol must be supplied">
- <option value="RMI">RMI</option>
- <option value="JMX_RMI">JMX RMI</option>
- </select>
+ <div class="clear">
+ <div class="formLabel-labelCell">
+ <label for="formAddPort.protocolsJMX">JMX protocol*:</label>
+ </div>
+ <div class="formLabel-controlCell">
+ <select id="formAddPort.protocolsJMX"
+ data-dojo-type="dijit.form.FilteringSelect"
+ data-dojo-props="
+ name: 'protocols',
+ value: '',
+ promptMessage: 'JMX protocol to be associated with this port',
+ title: 'Enter JMX protocol to be associated with this port'">
+ <option value="RMI">RMI</option>
+ <option value="JMX_RMI">JMX RMI</option>
+ </select>
+ </div>
+ </div>
</div>
+
<div id="formAddPort:fieldsHTTP">
- <select id="formAddPort.protocolsHTTP" name="protocols" data-dojo-type="dijit.form.FilteringSelect"
- data-dojo-props="name: 'protocols', value: 'HTTP', label: 'HTTP protocol*:'" missingMessage="HTTP protocol must be supplied">
- <option value="HTTP">HTTP</option>
- </select>
+ <div class="clear">
+ <div class="formLabel-labelCell">
+ <label for="formAddPort.protocolsHTTP">HTTP protocols*:</label>
+ </div>
+ <div class="formLabel-controlCell">
+ <select id="formAddPort.protocolsHTTP"
+ data-dojo-type="dijit.form.FilteringSelect"
+ data-dojo-props="
+ name: 'protocols',
+ value: 'HTTP',
+ label: 'HTTP protocol*:',
+ promptMessage: 'HTTP protocol to be associated with this port',
+ title: 'Enter HTTP protocol to be associated with this port'">
+ <option value="HTTP">HTTP</option>
+ </select>
+ </div>
+ </div>
</div>
+
<div id="formAddPort:transport" >
- <select id="formAddPort.transports" name="transports" data-dojo-type="dijit.form.MultiSelect" multiple="true"
- data-dojo-props="name: 'transports',label: 'Transport:',placeHolder: 'TCP', value: '' ">
- <option value="TCP">TCP</option>
- <option value="SSL">SSL</option>
- </select>
+ <div class="clear">
+ <div class="formLabel-labelCell">
+ <label for="formAddPort.transports">Transport:</label>
+ </div>
+ <div class="formLabel-controlCell">
+ <select id="formAddPort.transports"
+ data-dojo-type="dijit.form.MultiSelect"
+ data-dojo-props="
+ name: 'transports',
+ placeHolder: 'TCP',
+ value: '',
+ multiple: true,
+ promptMessage: 'Transport(s)',
+ title: 'Select transports'">
+ <option value="TCP">TCP</option>
+ <option value="SSL">SSL</option>
+ </select>
+ </div>
+ </div>
+ <div class="clear"/>
</div>
<div id="formAddPort:fieldsTransportSSL">
- <select id="formAddPort.keyStore" data-dojo-type="dijit.form.FilteringSelect"
- data-dojo-props="name:'keyStore',label:'Key Store*:', searchAttr: 'name', placeHolder: 'Select keystore', value: '', required: true ">
- </select>
+ <div class="clear">
+ <div class="formLabel-labelCell">
+ <label for="formAddPort.keyStore">Key Store*:</label>
+ </div>
+ <div class="formLabel-controlCell">
+ <select id="formAddPort.keyStore"
+ data-dojo-type="dijit.form.FilteringSelect"
+ data-dojo-props="
+ name: 'keyStore',
+ label: 'Key Store*:',
+ searchAttr: 'name',
+ placeHolder: 'keystore',
+ value: '',
+ required: true,
+ promptMessage: 'Keystore that provides the SSL certificate',
+ title: 'Select the keystore that provides the SSL certificate'">
+ </select>
+ </div>
+ </div>
</div>
<div id="formAddPort:fieldsClientAuth">
<div id="formAddPort:fieldsClientAuthCheckboxes">
- <input id="formAddPort.needClientAuth" type="checkbox" name="needClientAuth"
- dojoType="dijit.form.CheckBox" data-dojo-props="label: 'Need SSL Client Certificate:'" />
- <input id="formAddPort.wantClientAuth" type="checkbox" name="wantClientAuth"
- dojoType="dijit.form.CheckBox" data-dojo-props="label: 'Want SSL Client Certificate:'" />
+ <div class="clear">
+ <div class="formLabel-labelCell">
+ <label for="formAddPort.needClientAuth">Need SSL Client Certificate:</label>
+ </div>
+ <div class="formLabel-controlCell">
+ <input id="formAddPort.needClientAuth" type="checkbox"
+ data-dojo-type="dijit.form.CheckBox"
+ data-dojo-props="
+ name: 'needClientAuth'" />
+ </div>
+ </div>
+ <div class="clear">
+ <div class="formLabel-labelCell">
+ <label for="formAddPort.wantClientAuth">Want SSL Client Certificate:</label>
+ </div>
+ <div class="formLabel-controlCell">
+ <input id="formAddPort.wantClientAuth" type="checkbox"
+ data-dojo-type="dijit.form.CheckBox"
+ data-dojo-props="
+ name: 'wantClientAuth'" />
+ </div>
+ </div>
+ </div>
+ <div class="clear">
+ <div class="formLabel-labelCell">
+ Trust Stores:
+ </div>
+ </div>
+
+ <div class="clear">
+ <div class="formLabel-controlCell">
+ <table id="formAddPort.trustStores"
+ data-dojo-type="dojox.grid.EnhancedGrid"
+ data-dojo-props="
+ plugins: {indirectSelection: true},
+ rowSelector:'0px'"
+ style="height: 100px; width:400px">
+ <thead>
+ <tr>
+ <th field="name">Name</th>
+ <th field="peersOnly">Peers Only</th>
+ </tr>
+ </thead>
+ </table>
+ </div>
</div>
- <div><strong>Trust Stores:</strong></div>
- <table id="formAddPort.trustStores" data-dojo-type="dojox.grid.EnhancedGrid"
- data-dojo-props="label:'Trust Stores:',plugins:{indirectSelection: true},rowSelector:'0px' " style="height: 100px; width:400px">
- <thead>
- <tr>
- <th field="name">Name</th>
- <th field="peersOnly">Peers Only</th>
- </tr>
- </thead>
- </table>
</div>
<input type="hidden" id="formAddPort.id" name="id"/>
- </div>
+ <div class="clear"/>
<div class="dijitDialogPaneActionBar">
- <!-- submit buttons -->
- <input type="submit" value="Save Port" label="Save Port" dojoType="dijit.form.Button" />
+ <!-- submit buttons -->
+ <input type="submit" value="Save Port" label="Save Port" dojoType="dijit.form.Button" />
</div>
</form>
</div>
diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/addQueue.html b/qpid/java/broker-plugins/management-http/src/main/java/resources/addQueue.html
index 75d0888200..352e69893b 100644
--- a/qpid/java/broker-plugins/management-http/src/main/java/resources/addQueue.html
+++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/addQueue.html
@@ -21,216 +21,316 @@
<div class="dijitHidden">
<div data-dojo-type="dijit.Dialog" data-dojo-props="title:'Add Queue'" id="addQueue">
<form id="formAddQueue" method="post" dojoType="dijit.form.Form">
- <div style="height:250px; width:600px; overflow: auto">
- <table cellpadding="0" cellspacing="2">
- <tr>
- <td valign="top"><strong>Queue Name*: </strong></td>
- <td><input type="text" required="true" name="name" id="formAddQueue.name" placeholder="Queue Name"
- dojoType="dijit.form.ValidationTextBox" missingMessage="A name must be supplied" regexp="^[\x20-\x2e\x30-\x7F]{1,255}$"/></td>
- </tr>
- <tr>
- <td valign="top"><strong>Durable? </strong></td>
- <td><input type="checkbox" name="durable" id="formAddQueue.durable" value="durable" checked="checked" dojoType="dijit.form.CheckBox" /></td>
- </tr>
- <tr>
- <td valign="top"><strong>Persist Messages? </strong></td>
- <td>
- <select id="formAddQueue.messageDurability" name="messageDurability" data-dojo-type="dijit.form.FilteringSelect"
- data-dojo-props="name: 'messageDurability', value: '', searchAttr: 'name', placeHolder: '', value: '', required: false ">
- <option value="ALWAYS">Always</option>
- <option value="DEFAULT">Default</option>
- <option value="NEVER">Never</option>
- </select>
- </td>
- </tr>
- <tr>
- <td valign="top"><strong>Max Ttl: </strong></td>
- <td><input type="text" required="false" name="maximumMessageTtl" id="formAddQueue.maximumMessageTtl" placeholder="Ttl in ms."
- dojoType="dijit.form.ValidationTextBox"
- trim="true"
- regexp="[0-9]+"
- invalidMessage= "Invalid value" /></td>
- </tr>
- <tr>
- <td valign="top"><strong>Min Ttl: </strong></td>
- <td><input type="text" required="false" name="minimumMessageTtl" id="formAddQueue.minimumMessageTtl" placeholder="Ttl in ms."
- dojoType="dijit.form.ValidationTextBox"
- trim="true"
- regexp="[0-9]+"
- invalidMessage= "Invalid value" /></td>
- </tr>
- <tr>
- <td valign="top"><strong>Queue Type: </strong></td>
- <td>
+
+ <div class="clear">
+ <div class="formLabel-labelCell">Queue Name*:</div>
+ <div class="formLabel-controlCell">
+ <input type="text" id="formAddQueue.name"
+ data-dojo-type="dijit/form/ValidationTextBox"
+ data-dojo-props="
+ name: 'name',
+ placeHolder: 'queue name',
+ required: true,
+ promptMessage: 'Name of queue',
+ title: 'Enter a queue name',
+ regExp:'^[\x20-\x2e\x30-\x7F]{1,255}$'"/>
+ </div>
+ </div>
+ <div class="clear">
+ <div class="formLabel-labelCell">Queue Type:</div>
+ <div class="formLabel-controlCell">
<input type="radio" id="formAddQueueTypeStandard" name="type" value="standard" checked="checked" dojoType="dijit.form.RadioButton" />
<label for="formAddQueueTypeStandard">Standard</label>
- &nbsp;&nbsp;
+ &nbsp;
<input type="radio" id="formAddQueueTypePriority" name="type" value="priority" dojoType="dijit.form.RadioButton" />
<label for="formAddQueueTypePriority">Priority</label>
- &nbsp;&nbsp;
+ &nbsp;
<input type="radio" id="formAddQueueTypeLVQ" name="type" value="lvq" dojoType="dijit.form.RadioButton" />
<label for="formAddQueueTypeLVQ">LVQ</label>
- &nbsp;&nbsp;
+ &nbsp;
<input type="radio" id="formAddQueueTypeSorted" name="type" value="sorted" dojoType="dijit.form.RadioButton" />
<label for="formAddQueueTypeSorted">Sorted</label>
- </td>
- </tr>
- </table>
+ </div>
+ </div>
+ <div class="clear">
+ <div class="formLabel-labelCell">Durable?</div>
+ <div class="formLabel-controlCell">
+ <input type="checkbox" id="formAddQueue.durable"
+ dojoType="dijit.form.CheckBox"
+ data-dojo-props="
+ name: 'durable',
+ value: 'durable',
+ checked: true"/>
+ </div>
+ </div>
+ <div class="clear">
+ <div class="formLabel-labelCell">Persist Messages?</div>
+ <div class="formLabel-controlCell">
+ <select id="formAddQueue.messageDurability"
+ dojoType="dijit.form.FilteringSelect"
+ data-dojo-props="
+ name: 'messageDurability',
+ value: '',
+ searchAttr: 'name',
+ required: false,
+ promptMessage: 'Message durability override. If not default, messages arriving will have durability setting overridden',
+ title: 'Enter message durability override'">
+ <option value="ALWAYS">Always</option>
+ <option value="DEFAULT">Default</option>
+ <option value="NEVER">Never</option>
+ </select>
+ </div>
+ </div>
+ <div class="clear">
+ <div class="formLabel-labelCell">Maximum Ttl:</div>
+ <div class="formLabel-controlCell">
+ <input type="text" id="formAddQueue.maximumMessageTtl"
+ data-dojo-type="dijit/form/ValidationTextBox"
+ data-dojo-props="
+ name: 'maximumMessageTtl',
+ placeHolder: 'ttl in ms',
+ promptMessage: 'Maximum message time to live (ttl) in ms. Messages arriving with larger ttl values will be overridden by this value',
+ title: 'Enter the maximum message time to live in milliseconds',
+ trim: true"/>
+ </div>
+ </div>
+ <div class="clear">
+ <div class="formLabel-labelCell">Minimum Ttl:</div>
+ <div class="formLabel-controlCell">
+ <input type="text" id="formAddQueue.minimumMessageTtl"
+ data-dojo-type="dijit/form/ValidationTextBox"
+ data-dojo-props="
+ name: 'minimumMessageTtl',
+ placeHolder: 'ttl in ms',
+ promptMessage: 'Minimum message time to live (ttl) in ms. Messages arriving with smaller ttl values will be overridden by this value',
+ title: 'Enter the minimum message time to live in milliseconds',
+ trim: true"/>
+ </div>
+ </div>
+
<br/>
+ <div class="clear"></div>
+
<div id="formAddQueueTypePriority:fields" class="hidden"
data-dojo-type="dijit.TitlePane" data-dojo-props="title: 'Priority Queue Settings'">
- <table cellpadding="0" cellspacing="2">
- <tr>
- <td valign="top"><strong>Priorities: </strong></td>
- <td><input data-dojo-type="dijit.form.NumberSpinner" id="formAddQueue.priorities"
- name="priorities" value="10" smallDelta="1" constraints="{min:1,max:10,places:0}"/>
- </tr>
- </table>
+ <div class="clear">
+ <div class="formLabel-labelCell">Priorities:</div>
+ <div class="formLabel-controlCell">
+ <input type="text" id="formAddQueue.priorities"
+ data-dojo-type="dijit/form/ValidationTextBox"
+ data-dojo-props="
+ name: 'priorities',
+ placeHolder: 'number of priorities',
+ promptMessage: 'Number of priorities supported by the queue',
+ title: 'Enter the number of priorities supported by the queue',
+ trim: true"/>
+ </div>
+ </div>
+ <div class="clear"></div>
</div>
-
<div id="formAddQueueTypeLVQ:fields" class="hidden"
data-dojo-type="dijit.TitlePane" data-dojo-props="title: 'Last Value Queue Settings'">
- <table cellpadding="0" cellspacing="2">
- <tr>
- <td valign="top"><strong>LVQ Message Property: </strong></td>
- <td><input type="text" name="lvqKey" id="formAddQueue.lvqkey"
- placeholder="qpid.LVQ_key" dojoType="dijit.form.ValidationTextBox" /></td>
- </tr>
- </table>
+ <div class="clear">
+ <div class="formLabel-labelCell">LVQ Message Property:</div>
+ <div class="formLabel-controlCell">
+ <input type="text" id="formAddQueue.lvqkey"
+ data-dojo-type="dijit/form/ValidationTextBox"
+ data-dojo-props="
+ name: 'lvqKey',
+ placeHolder: 'lvq key',
+ promptMessage: 'Name of the message property used to perform the conflation',
+ title: 'Enter the name of the message property used to perform the conflation',
+ trim: true"/>
+ </div>
+ </div>
+ <div class="clear"></div>
</div>
<div id="formAddQueueTypeSorted:fields" class="hidden"
data-dojo-type="dijit.TitlePane" data-dojo-props="title: 'Sorted Queue Settings'">
- <table cellpadding="0" cellspacing="2">
- <tr>
- <td valign="top"><strong>Sort Message Property: </strong></td>
- <td><input type="text" name="sortKey" id="formAddQueue.sortkey" required="false"
- placeholder="" dojoType="dijit.form.ValidationTextBox" /></td>
- </tr>
- </table>
+ <div class="clear">
+ <div class="formLabel-labelCell">Sort Message Property*:</div>
+ <div class="formLabel-controlCell">
+ <input type="text" id="formAddQueue.sortkey"
+ data-dojo-type="dijit/form/ValidationTextBox"
+ data-dojo-props="
+ name: 'sortKey',
+ placeHolder: 'sort key',
+ promptMessage: 'Name of the message property used for sorting the messages on the queue',
+ title: 'Enter the name of the message property used for sorting the messages on the queue',
+ trim: true"/>
+ </div>
+ </div>
+ <div class="clear"></div>
</div>
<br/>
<div data-dojo-type="dijit.TitlePane" data-dojo-props="title: 'Flow Control Settings', open: false">
- <table cellpadding="0" cellspacing="2">
-
- <!-- x-qpid-capacity -->
- <tr>
- <td valign="top"><strong>Capacity: </strong></td>
- <td><input type="text" required="false" name="queueFlowControlSizeBytes" id="formAddQueue.capacity" placeholder="Size in bytes"
- dojoType="dijit.form.ValidationTextBox"
- trim="true"
- regexp="[0-9]+"
- invalidMessage= "Invalid value"/></td>
- </tr>
- <!-- x-qpid-flow-resume-capacity -->
- <tr>
- <td valign="top"><strong>Resume Capacity: </strong></td>
- <td><input type="text" required="false" name="queueFlowResumeSizeBytes" id="formAddQueue.flowResumeCapacity" placeholder="Size in bytes"
- dojoType="dijit.form.ValidationTextBox"
- trim="true"
- regexp="[0-9]+"
- invalidMessage= "Invalid value"/></td>
- </tr>
- </table>
+ <div class="clear">
+ <div class="formLabel-labelCell">Capacity:</div>
+ <div class="formLabel-controlCell">
+ <input type="text" id="formAddQueue.capacity"
+ data-dojo-type="dijit/form/ValidationTextBox"
+ data-dojo-props="
+ name: 'queueFlowControlSizeBytes',
+ placeHolder: 'size in bytes',
+ promptMessage: 'Ceiling (in bytes) at which queue will begin to throttle sessions producing messages',
+ title: 'Enter the ceiling (in bytes) at which queue will begin to throttle sessions producing messages',
+ trim: true"/>
+ </div>
+ </div>
+ <div class="clear">
+ <div class="formLabel-labelCell">Resume Capacity:</div>
+ <div class="formLabel-controlCell">
+ <input type="text" id="formAddQueue.flowResumeCapacity"
+ data-dojo-type="dijit/form/ValidationTextBox"
+ data-dojo-props="
+ name: 'queueFlowResumeSizeBytes',
+ placeHolder: 'size in bytes',
+ promptMessage: 'Floor (in bytes) at which queue will cease to throttle sessions producing messages',
+ title: 'Enter the floor (in bytes) at which queue will cease to throttle sessions producing messages',
+ trim: true"/>
+ </div>
+ </div>
+ <div class="clear"></div>
</div>
+
<br/>
<div data-dojo-type="dijit.TitlePane" data-dojo-props="title: 'Alerting Settings', open: false">
- <table cellpadding="0" cellspacing="2">
- <!-- x-qpid-maximum-message-count -->
- <tr>
- <td valign="top"><strong>Queue Depth: </strong></td>
- <td><input type="text" required="false" name="alertThresholdQueueDepthMessages" id="formAddQueue.maximumMessageCount" placeholder="Number of messages"
- dojoType="dijit.form.ValidationTextBox"
- trim="true"
- regexp="[0-9]+"
- invalidMessage= "Invalid value" /></td>
- </tr>
- <!-- x-qpid-maximum-queue-depth -->
- <tr>
- <td valign="top"><strong>Queue Depth: </strong></td>
- <td><input type="text" required="false" name="alertThresholdQueueDepthBytes" id="formAddQueue.maximumQueueDepth" placeholder="Total message size in bytes"
- dojoType="dijit.form.ValidationTextBox"
- trim="true"
- regexp="[0-9]+"
- invalidMessage= "Invalid value" /></td>
- </tr>
- <!-- x-qpid-maximum-message-age -->
- <tr>
- <td valign="top"><strong>Message Age: </strong></td>
- <td><input type="text" required="false" name="alertThresholdMessageAge" id="formAddQueue.maximumMessageAge" placeholder="Time in ms"
- dojoType="dijit.form.ValidationTextBox"
- trim="true"
- regexp="[0-9]+"
- invalidMessage= "Invalid value" /></td>
- </tr>
- <!-- x-qpid-maximum-message-size -->
- <tr>
- <td valign="top"><strong>Message Size: </strong></td>
- <td><input type="text" required="false" name="alertThresholdMessageSize" id="formAddQueue.maximumMessageSize" placeholder="Size in bytes"
- dojoType="dijit.form.ValidationTextBox"
- trim="true"
- regexp="[0-9]+"
- invalidMessage= "Invalid value"/></td>
- </tr>
- <!-- x-qpid-minimum-alert-repeat-gap -->
- <tr>
- <td valign="top"><strong>Gap between alerts: </strong></td>
- <td><input type="text" required="false" name="alertRepeatGap" id="formAddQueue.minimumAlertRepeatGap" placeholder="Time in ms"
- dojoType="dijit.form.ValidationTextBox"
- trim="true"
- regexp="[0-9]+"
- invalidMessage= "Invalid value" /></td>
- </tr>
- </table>
+ <div class="clear">
+ <div class="formLabel-labelCell">Queue Depth:</div>
+ <div class="formLabel-controlCell">
+ <input type="text" id="formAddQueue.maximumMessageCount"
+ data-dojo-type="dijit/form/ValidationTextBox"
+ data-dojo-props="
+ name: 'alertThresholdQueueDepthMessages',
+ placeHolder: 'number of messages',
+ promptMessage: 'Ceiling value for number of messages on queue before alerts will be generated',
+ title: 'Enter the ceiling value for number of messages on queue before alerts will be generated',
+ trim: true"/>
+ </div>
+ </div>
+ <div class="clear">
+ <div class="formLabel-labelCell">Queue Depth:</div>
+ <div class="formLabel-controlCell">
+ <input type="text" id="formAddQueue.maximumQueueDepth"
+ data-dojo-type="dijit/form/ValidationTextBox"
+ data-dojo-props="
+ name: 'alertThresholdQueueDepthBytes',
+ placeHolder: 'total message size in bytes',
+ promptMessage: 'Ceiling value (in bytes) for total size of all messages on the queue before alerts will be generated',
+ title: 'Enter the ceiling value (in bytes) for total size of all messages on the queue before alerts will be generated',
+ trim: true"/>
+ </div>
+ </div>
+ <div class="clear">
+ <div class="formLabel-labelCell">Message Age:</div>
+ <div class="formLabel-controlCell">
+ <input type="text" id="formAddQueue.maximumMessageAge"
+ data-dojo-type="dijit/form/ValidationTextBox"
+ data-dojo-props="
+ name: 'alertThresholdMessageAge',
+ placeHolder: 'time in ms',
+ promptMessage: 'Message age (in milliseconds) above which alerts will be generated',
+ title: 'Enter the message age (in milliseconds) above which alerts will be generated',
+ trim: true"/>
+ </div>
+ </div>
+ <div class="clear">
+ <div class="formLabel-labelCell">Message Size:</div>
+ <div class="formLabel-controlCell">
+ <input type="text" id="formAddQueue.maximumMessageSize"
+ data-dojo-type="dijit/form/ValidationTextBox"
+ data-dojo-props="
+ name: 'alertThresholdMessageSize',
+ placeHolder: 'message size in bytes',
+ promptMessage: 'Message size (in bytes) above which alerts will be generated',
+ title: 'Enter the message size (in bytes) above which alerts will be generated',
+ trim: true"/>
+ </div>
+ </div>
+ <div class="clear">
+ <div class="formLabel-labelCell">Gap between alerts:</div>
+ <div class="formLabel-controlCell">
+ <input type="text" id="formAddQueue.alertRepeatGap"
+ data-dojo-type="dijit/form/ValidationTextBox"
+ data-dojo-props="
+ name: 'alertRepeatGap',
+ placeHolder: 'time in ms',
+ promptMessage: 'Minimum time (in milliseconds) between each alert',
+ title: 'Enter the minimum time (in milliseconds) between each alert.',
+ trim: true"/>
+ </div>
+ </div>
+ <div class="clear"></div>
</div>
+
<br/>
<div data-dojo-type="dijit.TitlePane" data-dojo-props="title: 'Other Settings', open: false">
- <table cellpadding="0" cellspacing="2">
+ <div class="clear">
+ <div class="formLabel-labelCell">Maximum Delivery Retries:</div>
+ <div class="formLabel-controlCell">
+ <input type="text" id="formAddQueue.maximumDeliveryAttempts"
+ data-dojo-type="dijit/form/ValidationTextBox"
+ data-dojo-props="
+ name: 'maximumDeliveryAttempts',
+ placeHolder: 'number of retries',
+ promptMessage: 'Maximum number of delivery attempts before the message will be sent to the alternate exchange',
+ title: 'Enter the maximum number of delivery attempts before the message will be sent to the alternate exchange',
+ trim: true"/>
+ </div>
+ </div>
+ <div class="clear">
+ <div class="formLabel-labelCell">Create DLQ?</div>
+ <div class="formLabel-controlCell">
+ <input type="checkbox" id="formAddQueue.dlqEnabled"
+ dojoType="dijit.form.CheckBox"
+ data-dojo-props="
+ name: 'dlqEnabled',
+ value: 'dlqEnabled',
+ title: 'Controls where a dead letter queue is automatically created',
+ checked: false"/>
+ </div>
+ </div>
- <!-- x-qpid-maximum-delivery-count -->
- <tr>
- <td valign="top"><strong>Maximum Delivery Retries: </strong></td>
- <td><input type="text" required="false" name="maximumDeliveryAttempts" id="formAddQueue.maximumDeliveryCount"
- dojoType="dijit.form.ValidationTextBox"
- trim="true"
- regexp="[0-9]+"
- invalidMessage= "Invalid value"/></td>
- </tr>
- <tr>
- <td valign="top"><strong>Create DLQ? </strong></td>
- <td><input type="checkbox" name="dlqEnabled" id="formAddQueue.dlqEnabled" value="dlqEnabled" dojoType="dijit.form.CheckBox" /></td>
- </tr>
- </table>
- <table cellpadding="0" cellspacing="2">
- <tr>
- <td valign="top">NOTE: Configuring maximum delivery retries on a queue which has no DLQ / AlternateExchange will result in messages being discarded after the limit is reached.</td>
- </tr>
- </table>
- <table cellpadding="0" cellspacing="2">
+ <div class="clear"></div>
+ <div class="infoMessage">Configuring maximum delivery retries on a queue which has no DLQ or alternate <br/>exchange will result in messages being discarded after the limit is reached.</div>
- <!-- qpid.group_header_key -->
- <tr>
- <td valign="top"><strong>Message Group Key: </strong></td>
- <td><input type="text" required="false" name="messageGroupKey" id="formAddQueue.messageGroupKey"
- dojoType="dijit.form.ValidationTextBox"
- trim="true"/></td>
- </tr>
-
- <!-- qpid.qpid.shared_msg_group -->
- <tr>
- <td valign="top"><strong>Shared Message Groups? </strong></td>
- <td><input type="checkbox" name="messageGroupSharedGroups" id="formAddQueue.messageGroupSharedGroups" value="messageGroupSharedGroups" dojoType="dijit.form.CheckBox" /></td>
- </tr>
- </table>
- </div>
+ <div class="clear">
+ <div class="formLabel-labelCell">Message Group Key:</div>
+ <div class="formLabel-controlCell">
+ <input type="text" id="formAddQueue.messageGroupKey"
+ data-dojo-type="dijit/form/ValidationTextBox"
+ data-dojo-props="
+ name: 'messageGroupKey',
+ placeHolder: 'message group key',
+ promptMessage: 'Name of the message property used for message grouping',
+ title: 'Enter the name of the message property used for message grouping',
+ trim: true"/>
+ </div>
+ </div>
+ <div class="clear">
+ <div class="formLabel-labelCell">Shared Message Groups?</div>
+ <div class="formLabel-controlCell">
+ <input type="checkbox" id="formAddQueue.messageGroupSharedGroups"
+ dojoType="dijit.form.CheckBox"
+ data-dojo-props="
+ name: 'messageGroupSharedGroups',
+ value: 'messageGroupSharedGroups',
+ checked: false,
+ title: 'Controls where a shared groups feature is enabled'"/>
+ </div>
+ </div>
+ <div class="clear"></div>
</div>
+
<div class="dijitDialogPaneActionBar">
<!-- submit buttons -->
<input type="submit" value="Create Queue" label="Create Queue" dojoType="dijit.form.Button" />
</div>
+
</form>
</div>
</div>
diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/addVirtualHostNodeAndVirtualHost.html b/qpid/java/broker-plugins/management-http/src/main/java/resources/addVirtualHostNodeAndVirtualHost.html
index d751a6c1cd..738af25332 100644
--- a/qpid/java/broker-plugins/management-http/src/main/java/resources/addVirtualHostNodeAndVirtualHost.html
+++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/addVirtualHostNodeAndVirtualHost.html
@@ -34,9 +34,9 @@
data-dojo-type="dijit/form/ValidationTextBox"
data-dojo-props="
name: 'name',
- placeHolder: 'unique node name per broker',
+ placeHolder: 'node name',
required: true,
- missingMessage: 'A node name must be supplied',
+ promptMessage: 'Name of node, must be unique',
title: 'Enter a unique node name per broker'" />
</div>
</div>
@@ -49,6 +49,7 @@
required: true,
disabled: true,
placeHolder: 'select virtual host node type',
+ promptMessage: 'Type of virtual host node',
title: 'Select virtual host node type',
searchAttr: 'name'">
</select>
@@ -75,6 +76,7 @@
required: true,
disabled: true,
placeHolder: 'select virtual host type',
+ promptMessage: 'Type of virtual host',
title: 'Select virtual host type',
searchAttr: 'name'">
</select>
diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/css/common.css b/qpid/java/broker-plugins/management-http/src/main/java/resources/css/common.css
index bfe0839cbc..f49451b5d8 100644
--- a/qpid/java/broker-plugins/management-http/src/main/java/resources/css/common.css
+++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/css/common.css
@@ -239,8 +239,28 @@ div .messages {
font-weight: bold;
margin-left: 5px;
}
+
.editNoteBanner {
font-style: italic;
margin: 0px 0px 10px 5px;
}
+/* Required to keep queue type radio buttons on one line when dialog adds scrollbar */
+#addQueue {
+ max-height: 350px;
+ overflow: auto;
+ width: 630px;
+}
+
+#authenticatedUserControls {
+ max-width: 300px;
+}
+
+.claro .dojoxCheckedMultiSelectWrapper {
+ height: auto;
+}
+
+.claro .dojoxCheckedMultiSelect .dojoxCheckedMultiSelectWrapper {
+ border: none;
+ background-color: transparent;
+}
diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/editVirtualHost.html b/qpid/java/broker-plugins/management-http/src/main/java/resources/editVirtualHost.html
index 6f4db66c7d..9b981b055e 100644
--- a/qpid/java/broker-plugins/management-http/src/main/java/resources/editVirtualHost.html
+++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/editVirtualHost.html
@@ -19,111 +19,112 @@
<div class="dijitHidden">
<div data-dojo-type="dijit/Dialog" data-dojo-props="title:'Edit Virtual Host'" id="editVirtualHostDialog">
<form id="editVirtualHostForm" method="post" data-dojo-type="dijit/form/Form">
- <div class="editNoteBanner">NOTE: All changes will only take effect after Virtual Host restart.</div>
- <div class="clear">
- <div class="formLabel-labelCell tableContainer-labelCell">Name*:</div>
- <div class="formLabel-controlCell tableContainer-valueCell">
- <input type="text" id="editVirtualHost.name"
- data-dojo-type="dijit/form/ValidationTextBox"
- data-dojo-props="
+ <div id="editVirtualHost.allFields">
+ <div class="editNoteBanner">NOTE: All changes will only take effect after Virtual Host restart.</div>
+ <div class="clear">
+ <div class="formLabel-labelCell tableContainer-labelCell">Name*:</div>
+ <div class="formLabel-controlCell tableContainer-valueCell">
+ <input type="text" id="editVirtualHost.name"
+ data-dojo-type="dijit/form/ValidationTextBox"
+ data-dojo-props="
name: 'name',
placeHolder: 'name',
required: true,
- missingMessage: 'Name must be supplied',
disabled: true,
title: 'Enter virtual host name'" />
+ </div>
</div>
- </div>
- <div id="editVirtualHost.typeFields"></div>
+ <div id="editVirtualHost.typeFields"></div>
- <div class="clear formBox">
- <fieldset>
- <legend>Store transaction settings</legend>
- <div class="clear">
- <div class="formLabel-labelCell tableContainer-labelCell">Idle Timeout Warn:</div>
- <div class="tableContainer-valueCell formLabel-controlCell">
- <input data-dojo-type="dijit/form/ValidationTextBox"
- id="editVirtualHost.storeTransactionIdleTimeoutWarn"
- name="storeTransactionIdleTimeoutWarn"
- placeHolder="idle timeout warn time in ms"
- missingMessage="An idle timeout warn time in ms must be supplied"/>
+ <div class="clear formBox">
+ <fieldset>
+ <legend>Store transaction settings</legend>
+ <div class="clear">
+ <div class="formLabel-labelCell tableContainer-labelCell">Idle Timeout Warn:</div>
+ <div class="tableContainer-valueCell formLabel-controlCell">
+ <input data-dojo-type="dijit/form/ValidationTextBox"
+ id="editVirtualHost.storeTransactionIdleTimeoutWarn"
+ name="storeTransactionIdleTimeoutWarn"
+ placeHolder="idle timeout warn time in ms"
+ promptMessage="Length of time a transaction must be idle before warnings produced"/>
+ </div>
</div>
- </div>
- <div class="clear">
- <div class="formLabel-labelCell tableContainer-labelCell">Idle Timeout Close:</div>
- <div class="tableContainer-valueCell formLabel-controlCell">
- <input data-dojo-type="dijit/form/ValidationTextBox"
- id="editVirtualHost.storeTransactionIdleTimeoutClose"
- name="storeTransactionIdleTimeoutClose"
- placeHolder="idle timeout close time in ms"
- missingMessage="An idle timeout close time in ms must be supplied"/>
+ <div class="clear">
+ <div class="formLabel-labelCell tableContainer-labelCell">Idle Timeout Close:</div>
+ <div class="tableContainer-valueCell formLabel-controlCell">
+ <input data-dojo-type="dijit/form/ValidationTextBox"
+ id="editVirtualHost.storeTransactionIdleTimeoutClose"
+ name="storeTransactionIdleTimeoutClose"
+ placeHolder="idle timeout close time in ms"
+ promptMessage="Length of time a transaction must be idle before the connection is closed"/>
+ </div>
</div>
- </div>
- <div class="clear">
- <div class="formLabel-labelCell tableContainer-labelCell">Open Timeout Warn:</div>
- <div class="tableContainer-valueCell formLabel-controlCell">
- <input data-dojo-type="dijit/form/ValidationTextBox"
- id="editVirtualHost.storeTransactionOpenTimeoutWarn"
- name="storeTransactionOpenTimeoutWarn"
- placeHolder="open timeout warn time in ms"
- missingMessage="An open timeout warn time in ms must be supplied"/>
+ <div class="clear">
+ <div class="formLabel-labelCell tableContainer-labelCell">Open Timeout Warn:</div>
+ <div class="tableContainer-valueCell formLabel-controlCell">
+ <input data-dojo-type="dijit/form/ValidationTextBox"
+ id="editVirtualHost.storeTransactionOpenTimeoutWarn"
+ name="storeTransactionOpenTimeoutWarn"
+ placeHolder="open timeout warn time in ms"
+ promptMessage="Length of time a transaction must be open before warnings produced"/>
+ </div>
</div>
- </div>
- <div class="clear">
- <div class="formLabel-labelCell tableContainer-labelCell">Open Timeout Close:</div>
- <div class="tableContainer-valueCell formLabel-controlCell">
- <input data-dojo-type="dijit/form/ValidationTextBox"
- id="editVirtualHost.storeTransactionOpenTimeoutClose"
- name="storeTransactionOpenTimeoutClose"
- placeHolder="open timeout close time in ms"
- missingMessage="An open timeout close time in ms must be supplied"/>
+ <div class="clear">
+ <div class="formLabel-labelCell tableContainer-labelCell">Open Timeout Close:</div>
+ <div class="tableContainer-valueCell formLabel-controlCell">
+ <input data-dojo-type="dijit/form/ValidationTextBox"
+ id="editVirtualHost.storeTransactionOpenTimeoutClose"
+ name="storeTransactionOpenTimeoutClose"
+ placeHolder="open timeout close time in ms"
+ promptMessage="Length of time a transaction must be open before the connection is closed"/>
+ </div>
</div>
- </div>
- </fieldset>
- </div>
+ </fieldset>
+ </div>
- <div class="clear formBox">
- <fieldset>
- <legend>House keeping settings</legend>
- <div class="clear">
- <div class="formLabel-labelCell tableContainer-labelCell">Check period (ms):</div>
- <div class="tableContainer-valueCell formLabel-controlCell">
- <input data-dojo-type="dijit/form/ValidationTextBox"
- id="editVirtualHost.housekeepingCheckPeriod"
- name="housekeepingCheckPeriod"
- placeHolder="house keeping check period in ms"
- missingMessage="A house keeping check period must be supplied"/>
+ <div class="clear formBox">
+ <fieldset>
+ <legend>House keeping settings</legend>
+ <div class="clear">
+ <div class="formLabel-labelCell tableContainer-labelCell">Check period (ms):</div>
+ <div class="tableContainer-valueCell formLabel-controlCell">
+ <input data-dojo-type="dijit/form/ValidationTextBox"
+ id="editVirtualHost.housekeepingCheckPeriod"
+ name="housekeepingCheckPeriod"
+ placeHolder="house keeping check period in ms"
+ promptMessage="Frequency with which the housekeeper runs"/>
+ </div>
</div>
- </div>
- <div class="clear">
- <div class="formLabel-labelCell tableContainer-labelCell">Thread count:</div>
- <div class="tableContainer-valueCell formLabel-controlCell">
- <input data-dojo-type="dijit/form/ValidationTextBox"
- id="editVirtualHost.housekeepingThreadCount"
- name="housekeepingThreadCount"
- placeHolder="house keeping thread count"
- missingMessage="A house keeping thread count must be supplied"/>
+ <div class="clear">
+ <div class="formLabel-labelCell tableContainer-labelCell">Thread count:</div>
+ <div class="tableContainer-valueCell formLabel-controlCell">
+ <input data-dojo-type="dijit/form/ValidationTextBox"
+ id="editVirtualHost.housekeepingThreadCount"
+ name="housekeepingThreadCount"
+ placeHolder="house keeping thread count"
+ promptMessage="Number of threads used to perform housekeeping"/>
+ </div>
</div>
- </div>
- </fieldset>
- </div>
- <div class="clear"></div>
+ </fieldset>
+ </div>
+ <div class="clear"></div>
- <div class="clear">
- <div class="formLabel-labelCell tableContainer-labelCell">Dead letter queue enabled:</div>
- <div class="tableContainer-valueCell formLabel-controlCell">
- <input type="checkbox" id="editVirtualHost.queue.deadLetterQueueEnabled"
- data-dojo-type="dijit/form/CheckBox"
- data-dojo-props="name: 'queue.deadLetterQueueEnabled'">
- </input>
+ <div class="clear">
+ <div class="formLabel-labelCell tableContainer-labelCell">Dead letter queue enabled:</div>
+ <div class="tableContainer-valueCell formLabel-controlCell">
+ <input type="checkbox" id="editVirtualHost.queue.deadLetterQueueEnabled"
+ data-dojo-type="dijit/form/CheckBox"
+ data-dojo-props="name: 'queue.deadLetterQueueEnabled'">
+ </input>
+ </div>
</div>
- </div>
- <div class="clear"></div>
+ <div class="clear"></div>
- <div class="dijitDialogPaneActionBar">
- <button data-dojo-type="dijit/form/Button" id="editVirtualHost.saveButton" data-dojo-props="label: 'Save'">Save</button>
- <button data-dojo-type="dijit/form/Button" id="editVirtualHost.cancelButton" data-dojo-props="label: 'Cancel'" ></button>
+ <div class="dijitDialogPaneActionBar">
+ <button data-dojo-type="dijit/form/Button" id="editVirtualHost.saveButton" data-dojo-props="label: 'Save'">Save</button>
+ <button data-dojo-type="dijit/form/Button" id="editVirtualHost.cancelButton" data-dojo-props="label: 'Cancel'" ></button>
+ </div>
</div>
</form>
</div>
diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/index.html b/qpid/java/broker-plugins/management-http/src/main/java/resources/index.html
index ee67e4ce21..dfbec13320 100644
--- a/qpid/java/broker-plugins/management-http/src/main/java/resources/index.html
+++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/index.html
@@ -86,7 +86,7 @@
<div id="header" class="header" style="float: left; width: 300px"></div>
<div style="float: right;">
<div id="login" class="hidden"><span id="authenticatedUser" class="hidden"></span>
- <div id="authenticatedUserControls" data-dojo-type="dijit.form.DropDownButton" data-dojo-props="iconClass: 'preferencesIcon', style:{'max-width': '100px'}">
+ <div id="authenticatedUserControls" data-dojo-type="dijit.form.DropDownButton" data-dojo-props="iconClass: 'preferencesIcon'">
<div data-dojo-type="dijit.Menu">
<div data-dojo-type="dijit.MenuItem" data-dojo-props="onClick: function(){window.location='logout';}" >Log out</div>
<div data-dojo-type="dijit.MenuItem"
diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/metadata.js b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/metadata.js
new file mode 100644
index 0000000000..19ec53744f
--- /dev/null
+++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/metadata.js
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+define(["dojo/_base/xhr",
+ "dojox/lang/functional/object",
+ "qpid/common/properties",
+ "dojo/domReady!"
+ ],
+ function (xhr, fobject, properties)
+ {
+ var metadata =
+ {
+ _init: function ()
+ {
+ var that = this;
+ xhr.get({sync: true, handleAs: "json", url: "service/metadata", load: function(metadata){that._onMetadata(metadata)}});
+ },
+ _onMetadata: function (metadata)
+ {
+ this.metadata = metadata;
+ },
+ getMetaData: function (category, type)
+ {
+ return this.metadata[category][type];
+ },
+ getDefaultValueForAttribute: function (category, type, attributeName)
+ {
+ var metaDataForInstance = this.getMetaData(category, type);
+ var attributesForType = metaDataForInstance["attributes"];
+ var attributesForName = attributesForType[attributeName];
+ return attributesForName ? attributesForName["defaultValue"] : undefined;
+ },
+ getTypesForCategory: function (category)
+ {
+ return fobject.keys(this.metadata[category]);
+ }
+ };
+
+ metadata._init();
+
+ return metadata;
+ });
diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/util.js b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/util.js
index 1a89bfb374..9e433bbb34 100644
--- a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/util.js
+++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/util.js
@@ -19,15 +19,19 @@
*
*/
define(["dojo/_base/xhr",
+ "dojo/_base/array",
"dojo/_base/event",
- "dojo/json",
"dojo/_base/lang",
+ "dojo/json",
"dojo/dom-construct",
"dojo/dom-geometry",
"dojo/window",
"dojo/query",
"dojo/parser",
+ "dojo/store/Memory",
"dojox/html/entities",
+ "qpid/common/metadata",
+ "qpid/common/widgetconfigurer",
"dijit/registry",
"dijit/TitlePane",
"dijit/Dialog",
@@ -35,13 +39,15 @@ define(["dojo/_base/xhr",
"dijit/form/Button",
"dijit/form/RadioButton",
"dijit/form/CheckBox",
+ "dijit/form/FilteringSelect",
+ "dijit/form/ValidationTextBox",
"dojox/layout/TableContainer",
"dijit/layout/ContentPane",
"dojox/validate/us",
"dojox/validate/web",
"dojo/domReady!"
],
- function (xhr, event, json, lang, dom, geometry, win, query, parser, entities, registry) {
+ function (xhr, array, event, lang, json, dom, geometry, win, query, parser, Memory, entities, metadata, widgetconfigurer, registry) {
var util = {};
if (Array.isArray) {
util.isArray = function (object) {
@@ -146,7 +152,7 @@ define(["dojo/_base/xhr",
return (type === "PlainPasswordFile" || type === "Base64MD5PasswordFile" || type === "SCRAM-SHA-1" || type === "SCRAM-SHA-256");
};
- util.showSetAttributesDialog = function(attributeWidgetFactories, data, putURL, dialogTitle, appendNameToUrl)
+ util.showSetAttributesDialog = function(attributeWidgetFactories, data, putURL, dialogTitle, category, type, appendNameToUrl)
{
var layout = new dojox.layout.TableContainer({
cols: 1,
@@ -200,7 +206,7 @@ define(["dojo/_base/xhr",
{
groupFieldContainer = new dojox.layout.TableContainer({
cols: 1,
- "labelWidth": "290",
+ "labelWidth": "300",
showLabels: true,
orientation: "horiz",
customClass: "formLabel"
@@ -220,6 +226,8 @@ define(["dojo/_base/xhr",
}
}
+ this.applyMetadataToWidgets(dialogContent, category, type);
+
// add onchange handler to set required property for dependent widget
for(var widgetName in requiredFor)
{
@@ -310,14 +318,17 @@ define(["dojo/_base/xhr",
aproximateHeight += 30;
}
}
- var viewport = win.getBox();
- var maxHeight = Math.max(Math.floor(viewport.h * 0.6), 100);
dialogContentArea.style.overflow= "auto";
- dialogContentArea.style.height = Math.min(aproximateHeight, maxHeight ) + "px";
+ dialogContentArea.style.height = "300";
setAttributesDialog.on("hide", function(e){setAttributesDialog.destroy();});
setAttributesDialog.show();
};
+ util.findAllWidgets = function(root)
+ {
+ return query("[widgetid]", root).map(registry.byNode).filter(function(w){ return w;});
+ };
+
util.xhrErrorHandler = function(error)
{
if (error)
@@ -540,6 +551,16 @@ define(["dojo/_base/xhr",
}
}
+ util.applyMetadataToWidgets = function(domRoot, category, type)
+ {
+ var widgets = util.findAllWidgets(domRoot);
+ array.forEach(widgets,
+ function (widget)
+ {
+ widgetconfigurer.config(widget, category, type);
+ });
+ }
+
util.getFormWidgetValues = function (form, initialData)
{
var values = {};
@@ -636,6 +657,16 @@ define(["dojo/_base/xhr",
}
}
+ util.makeTypeStore = function (types)
+ {
+ var typeData = [];
+ for (var i = 0; i < types.length; i++) {
+ var type = types[i];
+ typeData.push({id: type, name: type});
+ }
+ return new Memory({ data: typeData });
+ }
+
var singleContextVarRegexp = "(\\${[\\w\\.\\-]+})";
util.numericOrContextVarRegexp = function(constraints)
diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/widgetconfigurer.js b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/widgetconfigurer.js
new file mode 100644
index 0000000000..0b08dde615
--- /dev/null
+++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/widgetconfigurer.js
@@ -0,0 +1,97 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+define(["dojo/_base/xhr",
+ "dojo/string",
+ "dojo/query",
+ "dojo/dom",
+ "dojo/dom-construct",
+ "dojo/dom-attr",
+ "qpid/common/properties",
+ "qpid/common/metadata",
+ "dojo/text!strings.html",
+ "dojo/domReady!"
+ ],
+ function (xhr, string, query, dom, domConstruct, domAttr, properties, metadata, template)
+ {
+ var widgetconfigurer =
+ {
+ _init: function ()
+ {
+ var stringsTemplate = domConstruct.create("div", {innerHTML: template});
+ var promptTemplateWithDefaultNode = query("[id='promptTemplateWithDefault']", stringsTemplate)[0];
+
+ // The following will contain ${prompt} and ${default} formatted with html elements
+ this.promptTemplateWithDefault = promptTemplateWithDefaultNode.innerHTML;
+
+ domConstruct.destroy(stringsTemplate);
+ },
+ _processWidgetPrompt: function (widget, category, type)
+ {
+ var widgetName = widget.name;
+ if (widgetName && (widget instanceof dijit.form.ValidationTextBox || widget instanceof dijit.form.FilteringSelect))
+ {
+ // If not done so already, save the prompt text specified on the widget. We do this so if we
+ // config the same widget again, we can apply the default again (which may be different if the user
+ // has selected a different type within the category).
+ if (typeof widget.get("qpid.originalPromptMessage") == "undefined")
+ {
+ widget.set("qpid.originalPromptMessage", widget.get("promptMessage"));
+ }
+
+ var promptMessage = widget.get("qpid.originalPromptMessage");
+ var defaultValue = metadata.getDefaultValueForAttribute(category, type, widgetName);
+ if (defaultValue)
+ {
+ var newPromptMessage = string.substitute(this.promptTemplateWithDefault, { 'default': defaultValue, 'prompt': promptMessage });
+
+ if (promptMessage != newPromptMessage)
+ {
+ widget.set("promptMessage", newPromptMessage);
+ }
+ }
+ }
+ },
+ _processWidgetValue: function (widget, category, type)
+ {
+ var widgetName = widget.name;
+
+ if (widgetName && (widget instanceof dijit.form.FilteringSelect || widget instanceof dojox.form.CheckedMultiSelect))
+ {
+ if (!widget.get("value"))
+ {
+ var defaultValue = metadata.getDefaultValueForAttribute(category, type, widgetName);
+ if (defaultValue)
+ {
+ widget.set("value", defaultValue);
+ }
+ }
+ }
+ },
+ config: function (widget, category, type)
+ {
+ this._processWidgetPrompt(widget, category, type);
+ this._processWidgetValue(widget, category, type);
+ }
+ };
+
+ widgetconfigurer._init();
+
+ return widgetconfigurer;
+ });
diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/Broker.js b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/Broker.js
index 51a6c761f1..c52553c386 100644
--- a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/Broker.js
+++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/Broker.js
@@ -69,7 +69,8 @@ define(["dojo/_base/xhr",
regExpGen: util.nameOrContextVarRegexp,
value: brokerData.name,
label: "Name*:",
- name: "name"})
+ name: "name",
+ promptMessage: "Identifies the broker instance."})
}
}, {
name: "defaultVirtualHost",
@@ -89,7 +90,8 @@ define(["dojo/_base/xhr",
required: true, store: hostsStore,
value: brokerData.defaultVirtualHost,
label: "Default Virtual Host*:",
- name: "defaultVirtualHost"})
+ name: "defaultVirtualHost",
+ promptMessage: "Default virtual host used for clients that don't specify one when connecting."})
}
}, {
name: "statisticsReportingPeriod",
@@ -97,12 +99,12 @@ define(["dojo/_base/xhr",
return new dijit.form.ValidationTextBox({
trim: "true",
regExpGen: util.numericOrContextVarRegexp,
- invalidMessage: "Invalid value",
required: false,
value: brokerData.statisticsReportingPeriod,
placeholder: "Time in ms",
label: "Statistics reporting period (ms):",
- name: "statisticsReportingPeriod"
+ name: "statisticsReportingPeriod",
+ promptMessage: "Frequency with which statistics are reported to broker log."
});
}
}, {
@@ -123,11 +125,12 @@ define(["dojo/_base/xhr",
return new dijit.form.ValidationTextBox({
trim: "true",
regExpGen: util.numericOrContextVarRegexp,
- invalidMessage: "Invalid value",
required: false,
value: brokerData["connection.sessionCountLimit"],
+ placeholder: "Number of sessions",
label: "Maximum number of sessions:",
- name: "connection.sessionCountLimit"
+ name: "connection.sessionCountLimit",
+ promptMessage: "Maximum number of sessions per connection"
});
}
}, {
@@ -141,7 +144,8 @@ define(["dojo/_base/xhr",
value: brokerData["connection.heartBeatDelay"],
placeholder: "Time in ms",
label: "Heart beat delay (ms):",
- name: "connection.heartBeatDelay"
+ name: "connection.heartBeatDelay",
+ promptMessage: "Interval between heart beat messages exchanged between broker and clients"
});
}
} ];
@@ -235,7 +239,7 @@ define(["dojo/_base/xhr",
that.attributeWidgetFactories,
brokerData,
query,
- "Set broker attributes");
+ "Set broker attributes", "Broker", "broker");
});
}
);
diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/KeyStore.js b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/KeyStore.js
index 667c83c6ea..9f0ba9c16e 100644
--- a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/KeyStore.js
+++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/KeyStore.js
@@ -74,6 +74,7 @@ define(["dojo/dom",
xhr.get({url: that.url, sync: properties.useSyncGet, handleAs: "json", content: { actuals: true }})
.then(function(data)
{
+ // calls showKeystoreDialog
that.dialog(data[0], that.url);
});
});
diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/addAccessControlProvider.js b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/addAccessControlProvider.js
index 49a99418bf..ac0493bfa5 100644
--- a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/addAccessControlProvider.js
+++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/addAccessControlProvider.js
@@ -56,6 +56,8 @@ define(["dojo/_base/lang",
disabled: accessControlProvider.name ? true : false,
label: "Name*:",
regexp: "^[\x20-\x2e\x30-\x7F]{1,255}$",
+ promptMessage: "Name of access control provider.",
+ placeHolder: "name",
name: "name"});
}
}, {
@@ -171,6 +173,8 @@ define(["dojo/_base/lang",
accessControlProvider ? accessControlProvider : {},
"api/latest/accesscontrolprovider" + (name ? "/" + encodeURIComponent(name.name) : ""),
accessControlProvider ? "Edit access control provider - " + accessControlProvider.name : "Add access control provider",
+ "AccessControlProvider",
+ accessControlProvider && accessControlProvider.type ? accessControlProvider.type : "AclFile",
accessControlProvider ? false : true);
};
return addAccessControlProvider;
diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/addBinding.js b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/addBinding.js
index 8e70b78446..ac4937da68 100644
--- a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/addBinding.js
+++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/addBinding.js
@@ -386,7 +386,9 @@ define(["dojo/_base/connect",
that.queueChooser = new FilteringSelect({ id: "addBindingSelectQueue",
name: "queue",
store: queueStore,
- searchAttr: "name"}, input);
+ searchAttr: "name",
+ promptMessage: "Name of the queue",
+ title: "Select the name of the queue"}, input);
if(obj.queue)
{
@@ -414,7 +416,9 @@ define(["dojo/_base/connect",
that.exchangeChooser = new FilteringSelect({ id: "addBindingSelectExchange",
name: "exchange",
store: exchangeStore,
- searchAttr: "name"}, input);
+ searchAttr: "name",
+ promptMessage: "Name of the exchange",
+ title: "Select the name of the exchange"}, input);
if(obj.exchange)
{
diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/addGroupProvider.js b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/addGroupProvider.js
index 5f01b9769b..82281ad3d3 100644
--- a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/addGroupProvider.js
+++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/addGroupProvider.js
@@ -56,6 +56,8 @@ define(["dojo/_base/lang",
disabled: groupProvider.name ? true : false,
label: "Name*:",
regexp: "^[\x20-\x2e\x30-\x7F]{1,255}$",
+ promptMessage: "Name of group provider.",
+ placeHolder: "name",
name: "name"});
}
}, {
@@ -171,6 +173,8 @@ define(["dojo/_base/lang",
groupProvider ? groupProvider : {},
"api/latest/groupprovider" + (name ? "/" + encodeURIComponent(name.name) : ""),
groupProvider ? "Edit group provider - " + groupProvider.name : "Add group provider",
+ "Group",
+ groupProvider && groupProvider.type ? groupProvider.type : "Group",
groupProvider ? false : true);
};
return addGroupProvider;
diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/addKeystore.js b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/addKeystore.js
index 0ec8fb6c6c..e7e79e742d 100644
--- a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/addKeystore.js
+++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/addKeystore.js
@@ -57,6 +57,8 @@ define(["dojo/_base/lang",
disabled: keystore.name ? true : false,
label: "Name:",
regExpGen: util.nameOrContextVarRegexp,
+ promptMessage: "Name of keystore. Used to refer to the keystore from other objects within the Broker.",
+ placeHolder: "name",
name: "name"});
}
}, {
@@ -66,6 +68,8 @@ define(["dojo/_base/lang",
required: true,
value: keystore.path,
label: "Path to keystore:",
+ promptMessage: "File system location to the keystore file",
+ placeHolder: "path/to/keystore",
name: "path"});
}
}, {
@@ -75,7 +79,7 @@ define(["dojo/_base/lang",
return new dijit.form.ValidationTextBox({
required: false,
label: "Keystore password:",
- invalidMessage: "Missed keystore password",
+ promptMessage: "Password used to open the keystore",
name: "password",
placeHolder: keystore["password"] ? keystore["password"] : ""
});
@@ -96,10 +100,11 @@ define(["dojo/_base/lang",
}
fields.push({
name: "Options",
+
createWidget: function(keystore) {
var optionalFieldContainer = new dojox.layout.TableContainer({
cols: 1,
- "labelWidth": "290",
+ "labelWidth": "300",
showLabels: true,
orientation: "horiz",
customClass: "formLabel"
@@ -110,12 +115,16 @@ define(["dojo/_base/lang",
required: false,
value: keystore.certificateAlias,
label: "Keystore certificate alias:",
- name: "certificateAlias"}));
+ name: "certificateAlias",
+ placeHolder: "alias",
+ promptMessage: "Used to identify one certificate in a store that has many"}));
+
optionalFieldContainer.addChild( new dijit.form.ValidationTextBox({
required: false,
value: keystore.keyManagerFactoryAlgorithm,
label: "Key manager factory algorithm:",
- placeHolder: "Use default",
+ placeHolder: "algorithm name",
+ promptMessage: "Name of the key manager algorithm known to Java",
name: "keyManagerFactoryAlgorithm"}));
}
else
@@ -124,16 +133,20 @@ define(["dojo/_base/lang",
required: false,
value: keystore.trustManagerFactoryAlgorithm,
label: "Trust manager factory algorithm:",
- placeHolder: "Use default",
+ placeHolder: "algorithm name",
+ promptMessage: "Name of the trust manager algorithm known to Java",
name: "trustManagerFactoryAlgorithm"}));
}
optionalFieldContainer.addChild(new dijit.form.ValidationTextBox({
required: false,
value: isKeystore ? keystore.keyStoreType : keystore.trustStoreType,
label: "Key store type:",
- placeHolder: "Use default",
+ placeHolder: "store type",
+ promptMessage: "Name of the store type known to Java",
name: isKeystore ? "keyStoreType" : "trustStoreType"}));
+
var panel = new dijit.TitlePane({title: "Optional Attributes", content: optionalFieldContainer.domNode, open: false});
+
return panel;
}
});
@@ -148,6 +161,8 @@ define(["dojo/_base/lang",
keystore ? keystore : {},
keystore ? putURL : "api/latest/keystore",
keystore ? "Edit keystore - " + keystore.name : "Add keystore",
+ "KeyStore",
+ keystore && keystore.type ? keystore.type : "FileKeyStore", // GET?actuals=true doesn't get type for objects of the default type for the category
keystore ? false : true);
};
@@ -158,6 +173,8 @@ define(["dojo/_base/lang",
truststore ? truststore : {},
truststore ? putURL : "api/latest/truststore",
truststore ? "Edit truststore - " + truststore.name : "Add truststore",
+ "TrustStore",
+ truststore && truststore.type ? truststore.type : "FileTrustStore",
truststore ? false : true);
};
return addKeystore;
diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/addPort.js b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/addPort.js
index 34e2d58afb..0c8a4660fd 100644
--- a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/addPort.js
+++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/addPort.js
@@ -72,7 +72,7 @@ define(["dojo/_base/xhr",
}
for(var propName in formValues)
{
- if(formValues.hasOwnProperty(propName))
+ if(formValues.hasOwnProperty(propName) && formValues[propName])
{
if (propName == "needClientAuth" || propName == "wantClientAuth")
{
@@ -81,6 +81,12 @@ define(["dojo/_base/xhr",
else if (propName === "protocols")
{
var val = formValues[propName];
+
+ if(val === "" || (lang.isArray(val) && val.length == 0) )
+ {
+ continue;
+ }
+
if (!lang.isArray(val))
{
val = [ val ];
@@ -91,7 +97,7 @@ define(["dojo/_base/xhr",
{
var val = formValues[propName];
- if(val === "")
+ if(val === "" || (lang.isArray(val) && val.length == 0) )
{
continue;
}
@@ -170,20 +176,20 @@ define(["dojo/_base/xhr",
registry.byId("formAddPort.wantClientAuth").set("disabled", true);
}
- var transportSSLPanel = registry.byId("formAddPort:fieldsTransportSSL");
- var transportSSLPanelDisplay = transportSSLPanel.domNode.style.display;
+ var transportSSLPanelNode = dom.byId("formAddPort:fieldsTransportSSL");
+ var transportSSLPanelDisplay = transportSSLPanelNode.style.display;
if (transportType == "SSL" || (lang.isArray(transportType) && array.indexOf(transportType, "SSL")>=0))
{
- transportSSLPanel.domNode.style.display = "block";
+ transportSSLPanelNode.style.display = "block";
registry.byId("formAddPort.keyStore").set("disabled", false);
}
else
{
- transportSSLPanel.domNode.style.display = "none";
+ transportSSLPanelNode.style.display = "none";
registry.byId("formAddPort.keyStore").set("disabled", true);
}
- if (transportSSLPanel.domNode.style.display != transportSSLPanelDisplay && transportSSLPanel.domNode.style.display=="block")
+ if (transportSSLPanelNode.style.display != transportSSLPanelDisplay && transportSSLPanelNode.style.display=="block")
{
registry.byId("formAddPort.trustStores").resize();
}
@@ -216,7 +222,7 @@ define(["dojo/_base/xhr",
var store = typeWidget.store;
store.data.forEach(function(option){
registry.byId("formAddPort.protocols" + option.value).set("disabled", true);
- registry.byId("formAddPort:fields" + option.value).domNode.style.display = "none";
+ dom.byId("formAddPort:fields" + option.value).style.display = "none";
});
var isAMQP = ("AMQP" == newValue);
@@ -226,7 +232,7 @@ define(["dojo/_base/xhr",
registry.byId("formAddPort.needClientAuth").set("enabled", isAMQP || isHTTP);
registry.byId("formAddPort.wantClientAuth").set("enabled", isAMQP || isHTTP);
- registry.byId("formAddPort:fields" + newValue).domNode.style.display = "block";
+ dom.byId("formAddPort:fields" + newValue).style.display = "block";
var defaultsAMQPProtocols = registry.byId("formAddPort.protocolsDefault");
defaultsAMQPProtocols.set("disabled", "AMQP" != newValue)
var protocolsWidget = registry.byId("formAddPort.protocols" + newValue);
@@ -267,9 +273,9 @@ define(["dojo/_base/xhr",
}
transportWidget.set("disabled", disableTransportWidget);
registry.byId("formAddPort.authenticationProvider").set("disabled", isRMI);
- registry.byId("formAddPort:fieldsAuthenticationProvider").domNode.style.display = isRMI? "none" : "block";
- registry.byId("formAddPort:fieldsBindingAddress").domNode.style.display = newValue == "JMX" ? "none" : "block";
- registry.byId("formAddPort:transport").domNode.style.display = isRMI ? "none" : "block";
+ dom.byId("formAddPort:fieldsAuthenticationProvider").style.display = isRMI? "none" : "block";
+ dom.byId("formAddPort:fieldsBindingAddress").style.display = newValue == "JMX" ? "none" : "block";
+ dom.byId("formAddPort:transport").style.display = isRMI ? "none" : "block";
@@ -277,23 +283,6 @@ define(["dojo/_base/xhr",
theForm = registry.byId("formAddPort");
- var containers = ["formAddPort:fields", "formAddPort:fieldsTransportSSL", "formAddPort:fieldsAMQP",
- "formAddPort:fieldsJMX", "formAddPort:fieldsHTTP", "formAddPort:transport",
- "formAddPort:fieldsClientAuthCheckboxes", "formAddPort:fieldsAuthenticationProvider", "formAddPort:fieldsBindingAddress"];
- var labelWidthValue = "200";
- for(var i = 0; i < containers.length; i++)
- {
- var containerId = containers[i];
- var fields = new dojox.layout.TableContainer( {
- cols: 1,
- labelWidth: labelWidthValue,
- showLabels: true,
- orientation: "horiz",
- customClass: "formLabel"
- }, dom.byId(containerId));
- fields.startup();
- }
-
registry.byId("formAddPort.protocolsJMX").on("change", function(newValue){
var isRMI = newValue == "RMI";
var transportWidget = registry.byId("formAddPort.transports");
@@ -302,8 +291,8 @@ define(["dojo/_base/xhr",
transportWidget.set("value", "TCP");
}
transportWidget.set("disabled", isRMI);
- registry.byId("formAddPort:transport").domNode.style.display = isRMI ? "none" : "block";
- registry.byId("formAddPort:fieldsAuthenticationProvider").domNode.style.display = isRMI? "none" : "block";
+ dom.byId("formAddPort:transport").style.display = isRMI ? "none" : "block";
+ dom.byId("formAddPort:fieldsAuthenticationProvider").style.display = isRMI? "none" : "block";
registry.byId("formAddPort.authenticationProvider").set("disabled", isRMI);
});
@@ -365,6 +354,7 @@ define(["dojo/_base/xhr",
}
var keystoreWidget = registry.byId("formAddPort.keyStore");
+
if (keystores)
{
var data = [];
@@ -408,7 +398,7 @@ define(["dojo/_base/xhr",
var nameWidget = registry.byId("formAddPort.name");
nameWidget.set("value", port.name);
nameWidget.set("disabled", true);
- nameWidget.set("regExpGen", util.nameOrContextVarRegexp);
+
dom.byId("formAddPort.id").value=port.id;
providerWidget.set("value", port.authenticationProvider ? port.authenticationProvider : "");
keystoreWidget.set("value", port.keyStore ? port.keyStore : "");
@@ -444,7 +434,7 @@ define(["dojo/_base/xhr",
var store = typeWidget.store;
store.data.forEach(function(option){
registry.byId("formAddPort.protocols" + option.value).set("disabled", true);
- registry.byId("formAddPort:fields" + option.value).domNode.style.display = "none";
+ dom.byId("formAddPort:fields" + option.value).style.display = "none";
});
// identify the type of port using first protocol specified in protocol field if provided
@@ -487,7 +477,7 @@ define(["dojo/_base/xhr",
var addressWidget = registry.byId("formAddPort.bindingAddress");
addressWidget.set("value", port.bindingAddress)
}
- registry.byId("formAddPort:fields" + typeWidget.value).domNode.style.display = "block";
+ dom.byId("formAddPort:fields" + typeWidget.value).style.display = "block";
typeWidget.set("disabled", true);
keystoreWidget.initialValue = port.keyStore;
@@ -496,21 +486,33 @@ define(["dojo/_base/xhr",
providerWidget.initialValue = providerWidget.value;
registry.byId("addPort").show();
- });
+ util.applyMetadataToWidgets(registry.byId("addPort").domNode, "Port", typeWidget.get("value"));
+
+ });
}
else
{
+ // Creating new port
var typeWidget = registry.byId("formAddPort.type");
if (typeWidget.get("disabled"))
{
typeWidget.set("disabled", false);
}
typeWidget.set("value", "AMQP");
- var name = registry.byId("formAddPort.name");
- name.set("disabled", false);
+
+ var nameWidget = registry.byId("formAddPort.name");
+ nameWidget.set("disabled", false);
+ nameWidget.set("regExpGen", util.nameOrContextVarRegexp);
+
+ var portWidget = registry.byId("formAddPort.port");
+ portWidget.set("regExpGen", util.numericOrContextVarRegexp);
+
editWarning.style.display = "none";
registry.byId("addPort").show();
+
+ util.applyMetadataToWidgets(registry.byId("addPort").domNode, "Port", "AMQP");
}
+
};
return addPort;
diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/addQueue.js b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/addQueue.js
index 5a1ea48b3e..c66b99ee4c 100644
--- a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/addQueue.js
+++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/addQueue.js
@@ -27,6 +27,7 @@ define(["dojo/_base/xhr",
"dojo/_base/array",
"dojo/_base/event",
'dojo/_base/json',
+ 'qpid/common/util',
"dijit/form/NumberSpinner", // required by the form
/* dojox/ validate resources */
"dojox/validate/us", "dojox/validate/web",
@@ -41,7 +42,7 @@ define(["dojo/_base/xhr",
/* basic dojox classes */
"dojox/form/BusyButton", "dojox/form/CheckedMultiSelect",
"dojo/domReady!"],
- function (xhr, dom, construct, win, registry, parser, array, event, json) {
+ function (xhr, dom, construct, win, registry, parser, array, event, json, util) {
var addQueue = {};
@@ -147,6 +148,8 @@ define(["dojo/_base/xhr",
{
dijit.byId('formAddQueue.' + requiredFields[widgetValue]).required = isChecked;
}
+
+ util.applyMetadataToWidgets(obj.domNode, "Queue", widgetValue);
}
})
}
@@ -192,9 +195,12 @@ define(["dojo/_base/xhr",
addQueue.show = function(data) {
addQueue.vhost = data.virtualhost;
addQueue.vhostnode = data.virtualhostnode;
- registry.byId("formAddQueue").reset();
+ var form = registry.byId("formAddQueue");
+ form.reset();
registry.byId("addQueue").show();
- };
+ util.applyMetadataToWidgets(form.domNode, "Queue", "standard");
+
+ };
return addQueue;
});
diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/addVirtualHostNodeAndVirtualHost.js b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/addVirtualHostNodeAndVirtualHost.js
index 2eac2094e5..ede0c4bc48 100644
--- a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/addVirtualHostNodeAndVirtualHost.js
+++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/addVirtualHostNodeAndVirtualHost.js
@@ -34,6 +34,7 @@ define(["dojo/_base/xhr",
"dijit/form/FilteringSelect",
"qpid/common/properties",
"qpid/common/util",
+ "qpid/common/metadata",
"dojo/text!addVirtualHostNodeAndVirtualHost.html",
"dijit/form/Form",
"dijit/form/CheckBox",
@@ -41,7 +42,7 @@ define(["dojo/_base/xhr",
"dojox/validate/us",
"dojox/validate/web",
"dojo/domReady!"],
- function (xhr, event, lang, array, dom, domConstruct, json, parser, Memory, fobject, registry, Dialog, Button, FilteringSelect, properties, util, template)
+ function (xhr, event, lang, array, dom, domConstruct, json, parser, Memory, fobject, registry, Dialog, Button, FilteringSelect, properties, util, metadata, template)
{
var addVirtualHostNodeAndVirtualHost =
@@ -71,38 +72,26 @@ define(["dojo/_base/xhr",
this.virtualHostType = registry.byId("addVirtualHost.type");
this.virtualHostType.set("disabled", true);
- xhr.get({sync: properties.useSyncGet, handleAs: "json", url: "api/latest/broker?depth=0", load: function(data){that._onBrokerData(data[0]) }});
- },
- _makeTypeStore: function (types) {
- var typeData = [];
- for (var i = 0; i < types.length; i++) {
- var type = types[i];
- typeData.push({id: type, name: type});
- }
- return new Memory({ data: typeData });
- },
- _onBrokerData: function(brokerData)
- {
- var that=this;
- this.supportedVirtualHostNodeTypes = brokerData.supportedVirtualHostNodeTypes;
- this.supportedVirtualHostNodeTypes.sort();
- this.supportedVirtualHostTypes = brokerData.supportedVirtualHostTypes;
- this.supportedVirtualHostTypes.sort();
+ this.supportedVirtualHostNodeTypes = metadata.getTypesForCategory("VirtualHostNode");
+ this.supportedVirtualHostNodeTypes.sort();
+ this.supportedVirtualHostTypes = metadata.getTypesForCategory("VirtualHost");
+ this.supportedVirtualHostTypes.sort();
- //VH Type BDB_HA_REPLICA is not user creatable. This is only needed until we have model meta data available.
- this.supportedVirtualHostTypes = array.filter(this.supportedVirtualHostTypes, function(item){
- return item != "BDB_HA_REPLICA" && item != "BDB_HA";
- });
+ //VH Type BDB_HA_REPLICA is not user creatable. This is only needed until we have model meta data available.
+ this.supportedVirtualHostTypes = array.filter(this.supportedVirtualHostTypes, function(item){
+ return item != "BDB_HA_REPLICA" && item != "BDB_HA";
+ });
- var virtualHostNodeTypeStore = this._makeTypeStore(this.supportedVirtualHostNodeTypes);
- this.virtualHostNodeType.set("store", virtualHostNodeTypeStore);
- this.virtualHostNodeType.set("disabled", false);
- this.virtualHostNodeType.on("change", function(type){that._vhnTypeChanged(type, that.virtualHostNodeTypeFieldsContainer, "qpid/management/virtualhostnode/");});
+ var virtualHostNodeTypeStore = util.makeTypeStore(this.supportedVirtualHostNodeTypes);
+ this.virtualHostNodeType.set("store", virtualHostNodeTypeStore);
+ this.virtualHostNodeType.set("disabled", false);
+ this.virtualHostNodeType.on("change", function(type){that._vhnTypeChanged(type, that.virtualHostNodeTypeFieldsContainer, "qpid/management/virtualhostnode/");});
+
+ this.virtualHostTypeStore = util.makeTypeStore(this.supportedVirtualHostTypes);
+ this.virtualHostType.set("store", this.virtualHostTypeStore);
+ this.virtualHostType.set("disabled", false);
+ this.virtualHostType.on("change", function(type){that._vhTypeChanged(type, that.virtualHostTypeFieldsContainer, "qpid/management/virtualhost/");});
- this.virtualHostTypeStore = this._makeTypeStore(this.supportedVirtualHostTypes);
- this.virtualHostType.set("store", this.virtualHostTypeStore);
- this.virtualHostType.set("disabled", false);
- this.virtualHostType.on("change", function(type){that._vhTypeChanged(type, that.virtualHostTypeFieldsContainer, "qpid/management/virtualhost/");});
},
show: function()
{
@@ -132,13 +121,14 @@ define(["dojo/_base/xhr",
{
this._processDropDownsForBdbHa(type);
this._processDropDownsForJson(type);
- this._typeChanged(type, typeFieldsContainer, urlStem);
+
+ this._typeChanged(type, typeFieldsContainer, urlStem, "VirtualHostNode");
},
_vhTypeChanged: function (type, typeFieldsContainer, urlStem)
{
- this._typeChanged(type, typeFieldsContainer, urlStem);
+ this._typeChanged(type, typeFieldsContainer, urlStem, "VirtualHost");
},
- _typeChanged: function (type, typeFieldsContainer, urlStem)
+ _typeChanged: function (type, typeFieldsContainer, urlStem, category)
{
var widgets = registry.findWidgets(typeFieldsContainer);
array.forEach(widgets, function(item) { item.destroyRecursive();});
@@ -148,11 +138,13 @@ define(["dojo/_base/xhr",
{
var that = this;
require([urlStem + type.toLowerCase() + "/add"],
- function(TypeUI)
+ function(typeUI)
{
try
{
- TypeUI.show({containerNode:typeFieldsContainer, parent: that});
+ typeUI.show({containerNode:typeFieldsContainer, parent: that});
+
+ util.applyMetadataToWidgets(typeFieldsContainer,category, type);
}
catch(e)
{
diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/editVirtualHost.js b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/editVirtualHost.js
index 1a24e5e770..a959586655 100644
--- a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/editVirtualHost.js
+++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/editVirtualHost.js
@@ -56,6 +56,7 @@ define(["dojo/_base/xhr",
var that=this;
this.containerNode = domConstruct.create("div", {innerHTML: template});
parser.parse(this.containerNode);
+ this.allFieldsContainer = dom.byId("editVirtualHost.allFields");
this.typeFieldsContainer = dom.byId("editVirtualHost.typeFields");
this.dialog = registry.byId("editVirtualHostDialog");
this.saveButton = registry.byId("editVirtualHost.saveButton");
@@ -176,6 +177,8 @@ define(["dojo/_base/xhr",
{
TypeUI.show({containerNode:that.typeFieldsContainer, parent: that, data: virtualHostData});
that.form.connectChildren();
+
+ util.applyMetadataToWidgets(that.allFieldsContainer, "VirtualHost", virtualHostData.type);
}
catch(e)
{
diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/editVirtualHostNode.js b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/editVirtualHostNode.js
index 704063ae16..3c78eaa29c 100644
--- a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/editVirtualHostNode.js
+++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/editVirtualHostNode.js
@@ -147,6 +147,8 @@ define(["dojo/_base/xhr",
{
TypeUI.show({containerNode:that.typeFieldsContainer, parent: that, data: nodeData});
that.form.connectChildren();
+
+ util.applyMetadataToWidgets(that.allFieldsContainer, "VirtualHostNode", nodeData.type);
}
catch(e)
{
diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/plugin/managementhttp.js b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/plugin/managementhttp.js
index 07c5c25171..69f520bf42 100644
--- a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/plugin/managementhttp.js
+++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/plugin/managementhttp.js
@@ -139,7 +139,9 @@ define(["dojo/_base/xhr",
widgetFactories,
data,
"api/latest/plugin/" + encodeURIComponent(data.name),
- "Edit plugin - " + data.name);
+ "Edit plugin - " + data.name,
+ "Plugin",
+ "MANAGEMENT-HTTP");
};
function ManagementHttpUpdater(node, pluginObject, controller)
diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/plugin/managementjmx.js b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/plugin/managementjmx.js
index 78d06da51f..3579d258e9 100644
--- a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/plugin/managementjmx.js
+++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/plugin/managementjmx.js
@@ -86,7 +86,9 @@ define(["dojo/_base/xhr",
widgetFactories,
data,
"api/latest/plugin/" + encodeURIComponent(data.name),
- "Edit plugin - " + data.name);
+ "Edit plugin - " + data.name,
+ "Plugin",
+ "MANAGEMENT-JMX");
};
function ManagementJmxUpdater(node, pluginObject, controller)
diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/strings.html b/qpid/java/broker-plugins/management-http/src/main/java/resources/strings.html
new file mode 100644
index 0000000000..d29ef5c21c
--- /dev/null
+++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/strings.html
@@ -0,0 +1,21 @@
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you under the Apache License, Version 2.0 (the
+ ~ "License"); you may not use this file except in compliance
+ ~ with the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing,
+ ~ software distributed under the License is distributed on an
+ ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ ~ KIND, either express or implied. See the License for the
+ ~ specific language governing permissions and limitations
+ ~ under the License.
+ -->
+<div>
+ <div id="promptTemplateWithDefault"><i>Optional:</i> ${prompt}.<br/>Defaults to <code>${default}</code></div>
+</div>
diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/virtualhost/providedstore/add.html b/qpid/java/broker-plugins/management-http/src/main/java/resources/virtualhost/providedstore/add.html
index 320f056cef..c0cd3f5653 100644
--- a/qpid/java/broker-plugins/management-http/src/main/java/resources/virtualhost/providedstore/add.html
+++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/virtualhost/providedstore/add.html
@@ -28,7 +28,8 @@
name: 'storeOverfullSize',
placeHolder: 'size in bytes',
required: false,
- title: 'Enter ceiling (in bytes) at which store will begin to throttle sessions producing messages'" />
+ title: 'Enter ceiling (in bytes) at which store will begin to throttle sessions producing messages',
+ promptMessage: 'Ceiling (in bytes) at which store will begin to throttle sessions producing messages'" />
</div>
</div>
<div class="clear">
@@ -40,7 +41,8 @@
name: 'storeUnderfullSize',
placeHolder: 'size in bytes',
required: false,
- title: 'Enter floor (in bytes) at which store will cease to throttle sessions producing messages'" />
+ title: 'Enter floor (in bytes) at which store will cease to throttle sessions producing messages',
+ promptMessage: 'Floor (in bytes) at which store will cease to throttle sessions producing messages'" />
</div>
</div>
</div>
diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/virtualhost/providedstore/edit.html b/qpid/java/broker-plugins/management-http/src/main/java/resources/virtualhost/providedstore/edit.html
index ec02c67ff4..427a1bab86 100644
--- a/qpid/java/broker-plugins/management-http/src/main/java/resources/virtualhost/providedstore/edit.html
+++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/virtualhost/providedstore/edit.html
@@ -28,7 +28,8 @@
name: 'storeOverfullSize',
placeHolder: 'size in bytes',
required: false,
- title: 'Enter ceiling (in bytes) at which store will begin to throttle sessions producing messages'"
+ title: 'Enter ceiling (in bytes) at which store will begin to throttle sessions producing messages',
+ promptMessage: 'Ceiling (in bytes) at which store will begin to throttle sessions producing messages'"
/>
</div>
</div>
@@ -41,7 +42,8 @@
name: 'storeUnderfullSize',
placeHolder: 'size in bytes',
required: false,
- title: 'Enter floor (in bytes) at which store will cease to throttle sessions producing messages'"
+ title: 'Enter floor (in bytes) at which store will cease to throttle sessions producing messages',
+ promptMessage: 'Floor (in bytes) at which store will cease to throttle sessions producing messages'"
/>
</div>
</div>
diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/virtualhost/sizemonitoring/add.html b/qpid/java/broker-plugins/management-http/src/main/java/resources/virtualhost/sizemonitoring/add.html
index 88ca0b3807..484a85b965 100644
--- a/qpid/java/broker-plugins/management-http/src/main/java/resources/virtualhost/sizemonitoring/add.html
+++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/virtualhost/sizemonitoring/add.html
@@ -26,7 +26,8 @@
data-dojo-props="
name: 'storePath',
placeHolder: 'path/to/store',
- title: 'Enter message store path'" />
+ title: 'Enter message store path',
+ promptMessage: 'File system location for the message store'" />
</div>
</div>
<div class="clear">
@@ -38,7 +39,8 @@
name: 'storeOverfullSize',
placeHolder: 'size in bytes',
required: false,
- title: 'Enter ceiling (in bytes) at which store will begin to throttle sessions producing messages'" />
+ title: 'Enter ceiling (in bytes) at which store will begin to throttle sessions producing messages',
+ promptMessage: 'Ceiling (in bytes) at which store will begin to throttle sessions producing messages'" />
</div>
</div>
<div class="clear">
@@ -50,7 +52,8 @@
name: 'storeUnderfullSize',
placeHolder: 'size in bytes',
required: false,
- title: 'Enter floor (in bytes) at which store will cease to throttle sessions producing messages'" />
+ title: 'Enter floor (in bytes) at which store will cease to throttle sessions producing messages',
+ promptMessage: 'Floor (in bytes) at which store will cease to throttle sessions producing messages'" />
</div>
</div>
<div class="clear"></div>
diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/virtualhost/sizemonitoring/edit.html b/qpid/java/broker-plugins/management-http/src/main/java/resources/virtualhost/sizemonitoring/edit.html
index 60b8faef56..2486cdcf42 100644
--- a/qpid/java/broker-plugins/management-http/src/main/java/resources/virtualhost/sizemonitoring/edit.html
+++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/virtualhost/sizemonitoring/edit.html
@@ -26,7 +26,6 @@
data-dojo-type="dijit/form/ValidationTextBox"
data-dojo-props="
name: 'storePath',
- placeHolder: 'path/to/store',
disabled: true,
title: 'Enter message store path'" />
</div>
@@ -41,7 +40,8 @@
name: 'storeOverfullSize',
placeHolder: 'size in bytes',
required: false,
- title: 'Enter ceiling (in bytes) at which store will begin to throttle sessions producing messages'"
+ title: 'Enter ceiling (in bytes) at which store will begin to throttle sessions producing messages',
+ promptMessage: 'Ceiling (in bytes) at which store will begin to throttle sessions producing messages'"
/>
</div>
</div>
@@ -54,7 +54,8 @@
name: 'storeUnderfullSize',
placeHolder: 'size in bytes',
required: false,
- title: 'Enter floor (in bytes) at which store will cease to throttle sessions producing messages'"
+ title: 'Enter floor (in bytes) at which store will cease to throttle sessions producing messages',
+ promptMessage: 'Floor (in bytes) at which store will cease to throttle sessions producing messages'"
/>
</div>
</div>
diff --git a/qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagementPluginImpl.java b/qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagementPluginImpl.java
index 10f56cef58..61061e6209 100644
--- a/qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagementPluginImpl.java
+++ b/qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagementPluginImpl.java
@@ -32,6 +32,7 @@ import java.util.Set;
import javax.management.JMException;
import org.apache.log4j.Logger;
+
import org.apache.qpid.server.configuration.IllegalConfigurationException;
import org.apache.qpid.server.jmx.mbeans.LoggingManagementMBean;
import org.apache.qpid.server.jmx.mbeans.ServerInformationMBean;
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnection.java b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnection.java
index 7d9dfcd600..b64d355f80 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnection.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnection.java
@@ -20,6 +20,39 @@
*/
package org.apache.qpid.client;
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.net.ConnectException;
+import java.net.SocketAddress;
+import java.net.UnknownHostException;
+import java.nio.channels.UnresolvedAddressException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicLong;
+
+import javax.jms.ConnectionConsumer;
+import javax.jms.ConnectionMetaData;
+import javax.jms.Destination;
+import javax.jms.ExceptionListener;
+import javax.jms.IllegalStateException;
+import javax.jms.JMSException;
+import javax.jms.Queue;
+import javax.jms.QueueConnection;
+import javax.jms.QueueSession;
+import javax.jms.ServerSessionPool;
+import javax.jms.Topic;
+import javax.jms.TopicConnection;
+import javax.jms.TopicSession;
+import javax.naming.NamingException;
+import javax.naming.Reference;
+import javax.naming.Referenceable;
+import javax.naming.StringRefAddr;
+
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -49,38 +82,6 @@ import org.apache.qpid.jms.FailoverPolicy;
import org.apache.qpid.protocol.AMQConstant;
import org.apache.qpid.url.URLSyntaxException;
-import javax.jms.ConnectionConsumer;
-import javax.jms.ConnectionMetaData;
-import javax.jms.Destination;
-import javax.jms.ExceptionListener;
-import javax.jms.IllegalStateException;
-import javax.jms.JMSException;
-import javax.jms.Queue;
-import javax.jms.QueueConnection;
-import javax.jms.QueueSession;
-import javax.jms.ServerSessionPool;
-import javax.jms.Topic;
-import javax.jms.TopicConnection;
-import javax.jms.TopicSession;
-import javax.naming.NamingException;
-import javax.naming.Reference;
-import javax.naming.Referenceable;
-import javax.naming.StringRefAddr;
-import java.io.IOException;
-import java.lang.reflect.InvocationTargetException;
-import java.net.ConnectException;
-import java.net.SocketAddress;
-import java.net.UnknownHostException;
-import java.nio.channels.UnresolvedAddressException;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicLong;
-
public class AMQConnection extends Closeable implements Connection, QueueConnection, TopicConnection, Referenceable
{
private static final Logger _logger = LoggerFactory.getLogger(AMQConnection.class);
@@ -191,6 +192,9 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
//Address resolution purposes
private volatile long _lastFailoverTime = 0;
+ private boolean _compressMessages;
+ private int _messageCompressionThresholdSize;
+
/**
* @param broker brokerdetails
* @param username username
@@ -325,6 +329,31 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
Boolean.parseBoolean(System.getProperty(ClientProperties.VERIFY_QUEUE_ON_SEND, "false"));
}
+ if(connectionURL.getOption(ConnectionURL.OPTIONS_COMPRESS_MESSAGES) != null)
+ {
+ _compressMessages = Boolean.parseBoolean(connectionURL.getOption(ConnectionURL.OPTIONS_COMPRESS_MESSAGES));
+ }
+ else
+ {
+ _compressMessages =
+ Boolean.parseBoolean(System.getProperty(ClientProperties.CONNECTION_OPTION_COMPRESS_MESSAGES,
+ String.valueOf(ClientProperties.DEFAULT_CONNECTION_OPTION_COMPRESS_MESSAGES)));
+ }
+
+
+ if(connectionURL.getOption(ConnectionURL.OPTIONS_MESSAGES_COMPRESSION_THRESHOLD_SIZE) != null)
+ {
+ _messageCompressionThresholdSize = Integer.valueOf(connectionURL.getOption(ConnectionURL.OPTIONS_MESSAGES_COMPRESSION_THRESHOLD_SIZE));
+ }
+ else
+ {
+ _messageCompressionThresholdSize = Integer.getInteger(ClientProperties.CONNECTION_OPTION_MESSAGE_COMPRESSION_THRESHOLD_SIZE,
+ ClientProperties.DEFAULT_MESSAGE_COMPRESSION_THRESHOLD_SIZE);
+ }
+ if(_messageCompressionThresholdSize <= 0)
+ {
+ _messageCompressionThresholdSize = Integer.MAX_VALUE;
+ }
String amqpVersion = System.getProperty((ClientProperties.AMQP_VERSION), "0-10");
if (_logger.isDebugEnabled())
@@ -449,16 +478,13 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
}
}
- if ((message == null) || message.equals(""))
+ if (message == null)
{
- if (message == null)
- {
- message = "Unable to Connect";
- }
- else // can only be "" if getMessage() returned it therfore lastException != null
- {
- message = "Unable to Connect:" + connectionException.getClass();
- }
+ message = "Unable to Connect";
+ }
+ else if("".equals(message))
+ {
+ message = "Unable to Connect:" + connectionException.getClass();
}
for (Throwable th = connectionException; th != null; th = th.getCause())
@@ -1543,6 +1569,11 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
return _syncPublish;
}
+ public boolean isMessageCompressionDesired()
+ {
+ return _compressMessages;
+ }
+
public int getNextChannelID()
{
return _sessions.getNextChannelId();
@@ -1615,4 +1646,9 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
{
return super.setClosed();
}
+
+ public int getMessageCompressionThresholdSize()
+ {
+ return _messageCompressionThresholdSize;
+ }
}
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate.java b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate.java
index 0329deee03..74ca1ed74f 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate.java
@@ -20,6 +20,11 @@
*/
package org.apache.qpid.client;
+import java.io.IOException;
+
+import javax.jms.JMSException;
+import javax.jms.XASession;
+
import org.apache.qpid.AMQException;
import org.apache.qpid.client.failover.FailoverException;
import org.apache.qpid.client.failover.FailoverProtectedOperation;
@@ -27,10 +32,6 @@ import org.apache.qpid.framing.ProtocolVersion;
import org.apache.qpid.jms.BrokerDetails;
import org.apache.qpid.jms.Session;
-import javax.jms.JMSException;
-import javax.jms.XASession;
-import java.io.IOException;
-
public interface AMQConnectionDelegate
{
ProtocolVersion makeBrokerConnection(BrokerDetails brokerDetail) throws IOException, AMQException;
@@ -82,4 +83,6 @@ public interface AMQConnectionDelegate
void setHeartbeatListener(HeartbeatListener listener);
boolean supportsIsBound();
+
+ boolean isMessageCompressionSupported();
}
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate_0_10.java b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate_0_10.java
index 95b1178407..4e9164c3b0 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate_0_10.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate_0_10.java
@@ -21,6 +21,17 @@
package org.apache.qpid.client;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.CountDownLatch;
+
+import javax.jms.ExceptionListener;
+import javax.jms.JMSException;
+import javax.jms.XASession;
+
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -29,7 +40,6 @@ import org.apache.qpid.client.failover.FailoverException;
import org.apache.qpid.client.failover.FailoverProtectedOperation;
import org.apache.qpid.client.transport.ClientConnectionDelegate;
import org.apache.qpid.common.ServerPropertyNames;
-
import org.apache.qpid.framing.ProtocolVersion;
import org.apache.qpid.jms.BrokerDetails;
import org.apache.qpid.jms.ChannelLimitReachedException;
@@ -48,16 +58,6 @@ import org.apache.qpid.transport.SessionDetachCode;
import org.apache.qpid.transport.SessionException;
import org.apache.qpid.transport.TransportException;
-import javax.jms.ExceptionListener;
-import javax.jms.JMSException;
-import javax.jms.XASession;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.CountDownLatch;
-
public class AMQConnectionDelegate_0_10 implements AMQConnectionDelegate, ConnectionListener
{
/**
@@ -441,7 +441,11 @@ public class AMQConnectionDelegate_0_10 implements AMQConnectionDelegate, Connec
try
{
clientProps.put(ConnectionStartProperties.CLIENT_ID_0_10, _conn.getClientID());
- conSettings.setClientProperties(clientProps);
+ if(_conn.isMessageCompressionDesired())
+ {
+ clientProps.put(ConnectionStartProperties.QPID_MESSAGE_COMPRESSION_SUPPORTED, Boolean.TRUE.toString());
+ }
+ conSettings.setClientProperties(clientProps);
}
catch (JMSException e)
{
@@ -504,4 +508,10 @@ public class AMQConnectionDelegate_0_10 implements AMQConnectionDelegate, Connec
//0-10 supports the isBound method
return true;
}
+
+ @Override
+ public boolean isMessageCompressionSupported()
+ {
+ return _qpidConnection.isMessageCompressionSupported();
+ }
}
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate_8_0.java b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate_8_0.java
index dfbf7ec60a..5242629a91 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate_8_0.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate_8_0.java
@@ -20,8 +20,21 @@
*/
package org.apache.qpid.client;
+import java.io.IOException;
+import java.net.ConnectException;
+import java.nio.channels.UnresolvedAddressException;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.EnumSet;
+import java.util.Iterator;
+import java.util.Set;
+
+import javax.jms.JMSException;
+import javax.jms.XASession;
+
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+
import org.apache.qpid.AMQException;
import org.apache.qpid.client.failover.FailoverException;
import org.apache.qpid.client.failover.FailoverProtectedOperation;
@@ -49,22 +62,11 @@ import org.apache.qpid.transport.network.Transport;
import org.apache.qpid.transport.network.security.SecurityLayer;
import org.apache.qpid.transport.network.security.SecurityLayerFactory;
-import javax.jms.JMSException;
-import javax.jms.XASession;
-
-import java.io.IOException;
-import java.net.ConnectException;
-import java.nio.channels.UnresolvedAddressException;
-import java.text.MessageFormat;
-import java.util.ArrayList;
-import java.util.EnumSet;
-import java.util.Iterator;
-import java.util.Set;
-
public class AMQConnectionDelegate_8_0 implements AMQConnectionDelegate
{
private static final Logger _logger = LoggerFactory.getLogger(AMQConnectionDelegate_8_0.class);
private final AMQConnection _conn;
+ private boolean _messageCompressionSupported;
public void closeConnection(long timeout) throws JMSException, AMQException
{
@@ -139,6 +141,7 @@ public class AMQConnectionDelegate_8_0 implements AMQConnectionDelegate
_conn.getFailoverPolicy().attainedConnection();
_conn.setConnected(true);
_conn.logConnected(network.getLocalAddress(), network.getRemoteAddress());
+ _messageCompressionSupported = checkMessageCompressionSupported();
return null;
}
else
@@ -413,4 +416,17 @@ public class AMQConnectionDelegate_8_0 implements AMQConnectionDelegate
return connectedToQpid;
}
+
+ private boolean checkMessageCompressionSupported()
+ {
+ FieldTable serverProperties = _conn.getProtocolHandler().getProtocolSession().getConnectionStartServerProperties();
+ return serverProperties != null
+ && Boolean.parseBoolean(serverProperties.getString(ConnectionStartProperties.QPID_MESSAGE_COMPRESSION_SUPPORTED));
+
+ }
+
+ public boolean isMessageCompressionSupported()
+ {
+ return _messageCompressionSupported;
+ }
}
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageProducer_0_10.java b/qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageProducer_0_10.java
index 9efc670e99..eb8104b02c 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageProducer_0_10.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageProducer_0_10.java
@@ -17,6 +17,19 @@
*/
package org.apache.qpid.client;
+import static org.apache.qpid.transport.Option.NONE;
+import static org.apache.qpid.transport.Option.SYNC;
+import static org.apache.qpid.transport.Option.UNRELIABLE;
+
+import java.nio.ByteBuffer;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+import javax.jms.DeliveryMode;
+import javax.jms.JMSException;
+import javax.jms.Message;
+
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -36,25 +49,15 @@ import org.apache.qpid.transport.MessageDeliveryPriority;
import org.apache.qpid.transport.MessageProperties;
import org.apache.qpid.transport.Option;
import org.apache.qpid.transport.TransportException;
+import org.apache.qpid.util.GZIPUtils;
import org.apache.qpid.util.Strings;
-import static org.apache.qpid.transport.Option.NONE;
-import static org.apache.qpid.transport.Option.SYNC;
-import static org.apache.qpid.transport.Option.UNRELIABLE;
-
-import javax.jms.DeliveryMode;
-import javax.jms.JMSException;
-import javax.jms.Message;
-import java.nio.ByteBuffer;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.UUID;
-
/**
* This is a 0_10 message producer.
*/
public class BasicMessageProducer_0_10 extends BasicMessageProducer
{
+
private static final Logger _logger = LoggerFactory.getLogger(BasicMessageProducer_0_10.class);
private byte[] userIDBytes;
@@ -204,6 +207,22 @@ public class BasicMessageProducer_0_10 extends BasicMessageProducer
}
ByteBuffer data = message.getData();
+
+ if(data != null
+ && data.remaining() > getConnection().getMessageCompressionThresholdSize()
+ && getConnection().getDelegate().isMessageCompressionSupported()
+ && getConnection().isMessageCompressionDesired()
+ && messageProps.getContentEncoding() == null)
+ {
+ byte[] compressed = GZIPUtils.compressBufferToArray(data);
+ if(compressed != null)
+ {
+ messageProps.setContentEncoding(GZIPUtils.GZIP_CONTENT_ENCODING);
+ data = ByteBuffer.wrap(compressed);
+ }
+ }
+
+
messageProps.setContentLength(data == null ? 0 : data.remaining());
// send the message
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageProducer_0_8.java b/qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageProducer_0_8.java
index b9bb03444f..355c456249 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageProducer_0_8.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageProducer_0_8.java
@@ -44,6 +44,7 @@ import org.apache.qpid.framing.ContentBody;
import org.apache.qpid.framing.ContentHeaderBody;
import org.apache.qpid.framing.ExchangeDeclareBody;
import org.apache.qpid.framing.MethodRegistry;
+import org.apache.qpid.util.GZIPUtils;
public class BasicMessageProducer_0_8 extends BasicMessageProducer
{
@@ -147,7 +148,20 @@ public class BasicMessageProducer_0_8 extends BasicMessageProducer
contentHeaderProperties.setDeliveryMode((byte) deliveryMode);
contentHeaderProperties.setPriority((byte) priority);
- final int size = (payload != null) ? payload.limit() : 0;
+ int size = (payload != null) ? payload.remaining() : 0;
+
+ byte[] compressed;
+ if(size > getConnection().getMessageCompressionThresholdSize()
+ && getConnection().getDelegate().isMessageCompressionSupported()
+ && getConnection().isMessageCompressionDesired()
+ && contentHeaderProperties.getEncoding() == null
+ && (compressed = GZIPUtils.compressBufferToArray(payload)) != null)
+ {
+ contentHeaderProperties.setEncoding("gzip");
+ payload = ByteBuffer.wrap(compressed);
+ size = compressed.length;
+
+ }
final int contentBodyFrameCount = calculateContentBodyFrameCount(payload);
final AMQFrame[] frames = new AMQFrame[2 + contentBodyFrameCount];
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/handler/CloseWhenNoRouteSettingsHelper.java b/qpid/java/client/src/main/java/org/apache/qpid/client/handler/CloseWhenNoRouteSettingsHelper.java
index baae072167..e8343fda0a 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/handler/CloseWhenNoRouteSettingsHelper.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/handler/CloseWhenNoRouteSettingsHelper.java
@@ -18,11 +18,12 @@
*/
package org.apache.qpid.client.handler;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
import org.apache.qpid.framing.FieldTable;
import org.apache.qpid.jms.ConnectionURL;
import org.apache.qpid.properties.ConnectionStartProperties;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
/**
* Used during connection establishment to optionally set the "close when no route" client property
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionStartMethodHandler.java b/qpid/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionStartMethodHandler.java
index b0c30f82fa..2e817f2966 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionStartMethodHandler.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionStartMethodHandler.java
@@ -20,6 +20,13 @@
*/
package org.apache.qpid.client.handler;
+import java.io.UnsupportedEncodingException;
+import java.util.StringTokenizer;
+
+import javax.security.sasl.Sasl;
+import javax.security.sasl.SaslClient;
+import javax.security.sasl.SaslException;
+
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -40,12 +47,6 @@ import org.apache.qpid.framing.ProtocolVersion;
import org.apache.qpid.jms.ConnectionURL;
import org.apache.qpid.properties.ConnectionStartProperties;
-import javax.security.sasl.Sasl;
-import javax.security.sasl.SaslClient;
-import javax.security.sasl.SaslException;
-import java.io.UnsupportedEncodingException;
-import java.util.StringTokenizer;
-
public class ConnectionStartMethodHandler implements StateAwareMethodListener<ConnectionStartBody>
{
private static final Logger _log = LoggerFactory.getLogger(ConnectionStartMethodHandler.class);
@@ -173,6 +174,9 @@ public class ConnectionStartMethodHandler implements StateAwareMethodListener<Co
ConnectionURL url = getConnectionURL(session);
_closeWhenNoRouteHelper.setClientProperties(clientProperties, url, serverProperties);
+ clientProperties.setString(ConnectionStartProperties.QPID_MESSAGE_COMPRESSION_SUPPORTED,
+ String.valueOf(session.getAMQConnection().isMessageCompressionDesired()));
+
ConnectionStartOkBody connectionStartOkBody = session.getMethodRegistry().createConnectionStartOkBody(clientProperties,new AMQShortString(mechanism),saslResponse,new AMQShortString(locales));
// AMQP version change: Hardwire the version to 0-8 (major=8, minor=0)
// TODO: Connect this to the session version obtained from ProtocolInitiation for this session.
@@ -188,7 +192,7 @@ public class ConnectionStartMethodHandler implements StateAwareMethodListener<Co
else
{
_log.error("Broker requested Protocol [" + body.getVersionMajor() + "-" + body.getVersionMinor()
- + "] which is not supported by this version of the client library");
+ + "] which is not supported by this version of the client library");
session.closeProtocolSession();
}
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/message/AbstractJMSMessageFactory.java b/qpid/java/client/src/main/java/org/apache/qpid/client/message/AbstractJMSMessageFactory.java
index e52ff9acb2..71d07b1fa0 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/message/AbstractJMSMessageFactory.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/message/AbstractJMSMessageFactory.java
@@ -20,6 +20,17 @@
*/
package org.apache.qpid.client.message;
+import java.io.ByteArrayOutputStream;
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.ByteBuffer;
+import java.util.Iterator;
+import java.util.List;
+import java.util.zip.GZIPInputStream;
+
+import javax.jms.JMSException;
+
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -28,16 +39,11 @@ import org.apache.qpid.client.AMQQueue;
import org.apache.qpid.client.AMQSession_0_8;
import org.apache.qpid.client.AMQTopic;
import org.apache.qpid.framing.AMQShortString;
-import org.apache.qpid.framing.BasicContentHeaderProperties;
import org.apache.qpid.framing.ContentBody;
import org.apache.qpid.framing.ContentHeaderBody;
import org.apache.qpid.transport.DeliveryProperties;
import org.apache.qpid.transport.MessageProperties;
-
-import javax.jms.JMSException;
-import java.nio.ByteBuffer;
-import java.util.Iterator;
-import java.util.List;
+import org.apache.qpid.util.GZIPUtils;
public abstract class AbstractJMSMessageFactory implements MessageFactory
{
@@ -52,46 +58,57 @@ public abstract class AbstractJMSMessageFactory implements MessageFactory
ByteBuffer data;
final boolean debug = _logger.isDebugEnabled();
- // we optimise the non-fragmented case to avoid copying
- if ((bodies != null) && (bodies.size() == 1))
- {
- if (debug)
- {
- _logger.debug("Non-fragmented message body (bodySize=" + contentHeader.getBodySize() + ")");
- }
+ byte[] uncompressed;
- data = ByteBuffer.wrap(((ContentBody) bodies.get(0)).getPayload());
+ if(GZIPUtils.GZIP_CONTENT_ENCODING.equals(contentHeader.getProperties().getEncodingAsString())
+ && (uncompressed = GZIPUtils.uncompressStreamToArray(new BodyInputStream(bodies))) != null )
+ {
+ contentHeader.getProperties().setEncoding((String)null);
+ data = ByteBuffer.wrap(uncompressed);
}
- else if (bodies != null)
+ else
{
- if (debug)
+ // we optimise the non-fragmented case to avoid copying
+ if ((bodies != null) && (bodies.size() == 1))
{
- _logger.debug("Fragmented message body (" + bodies
- .size() + " frames, bodySize=" + contentHeader.getBodySize() + ")");
- }
+ if (debug)
+ {
+ _logger.debug("Non-fragmented message body (bodySize=" + contentHeader.getBodySize() + ")");
+ }
- data = ByteBuffer.allocate((int) contentHeader.getBodySize()); // XXX: Is cast a problem?
- final Iterator it = bodies.iterator();
- while (it.hasNext())
+ data = ByteBuffer.wrap(((ContentBody) bodies.get(0)).getPayload());
+ }
+ else if (bodies != null)
{
- ContentBody cb = (ContentBody) it.next();
- final ByteBuffer payload = ByteBuffer.wrap(cb.getPayload());
- if(payload.isDirect() || payload.isReadOnly())
+ if (debug)
{
- data.put(payload);
+ _logger.debug("Fragmented message body (" + bodies
+ .size() + " frames, bodySize=" + contentHeader.getBodySize() + ")");
}
- else
+
+ data = ByteBuffer.allocate((int) contentHeader.getBodySize()); // XXX: Is cast a problem?
+ final Iterator it = bodies.iterator();
+ while (it.hasNext())
{
- data.put(payload.array(), payload.arrayOffset(), payload.limit());
+ ContentBody cb = (ContentBody) it.next();
+ final ByteBuffer payload = ByteBuffer.wrap(cb.getPayload());
+ if (payload.isDirect() || payload.isReadOnly())
+ {
+ data.put(payload);
+ }
+ else
+ {
+ data.put(payload.array(), payload.arrayOffset(), payload.limit());
+ }
+
}
+ data.flip();
+ }
+ else // bodies == null
+ {
+ data = ByteBuffer.allocate(0);
}
-
- data.flip();
- }
- else // bodies == null
- {
- data = ByteBuffer.allocate(0);
}
if (debug)
@@ -132,22 +149,42 @@ public abstract class AbstractJMSMessageFactory implements MessageFactory
_logger.debug("Creating message from buffer with position=" + data.position() + " and remaining=" + data
.remaining());
}
+ if(GZIPUtils.GZIP_CONTENT_ENCODING.equals(msgProps.getContentEncoding()))
+ {
+ byte[] uncompressed = GZIPUtils.uncompressBufferToArray(data);
+ if(uncompressed != null)
+ {
+ msgProps.setContentEncoding(null);
+ data = ByteBuffer.wrap(uncompressed);
+ }
+ }
AMQMessageDelegate delegate = new AMQMessageDelegate_0_10(msgProps, deliveryProps, messageNbr);
AbstractJMSMessage message = createMessage(delegate, data);
return message;
}
- private static final String asString(byte[] bytes)
+ private ByteBuffer uncompressBody(final InputStream bodyInputStream) throws AMQException
{
- if (bytes == null)
+ final ByteBuffer data;
+ try(GZIPInputStream gzipInputStream = new GZIPInputStream(bodyInputStream))
{
- return null;
+ ByteArrayOutputStream uncompressedBuffer = new ByteArrayOutputStream();
+ int read;
+ byte[] buf = new byte[4096];
+ while((read = gzipInputStream.read(buf))!=-1)
+ {
+ uncompressedBuffer.write(buf,0,read);
+ }
+ byte[] uncompressedBytes = uncompressedBuffer.toByteArray();
+ data = ByteBuffer.wrap(uncompressedBytes);
}
- else
+ catch (IOException e)
{
- return new String(bytes);
+ // TODO - shouldn't happen
+ throw new AMQException("Error uncompressing gzipped message data", e);
}
+ return data;
}
@@ -174,4 +211,57 @@ public abstract class AbstractJMSMessageFactory implements MessageFactory
return msg;
}
+ private class BodyInputStream extends InputStream
+ {
+ private final Iterator<ContentBody> _bodiesIter;
+ private byte[] _currentBuffer;
+ private int _currentPos;
+ public BodyInputStream(final List<ContentBody> bodies)
+ {
+ _bodiesIter = bodies.iterator();
+ _currentBuffer = _bodiesIter.next().getPayload();
+ _currentPos = 0;
+ }
+
+ @Override
+ public int read() throws IOException
+ {
+ byte[] buf = new byte[1];
+ int size = read(buf);
+ if(size == -1)
+ {
+ throw new EOFException();
+ }
+ else
+ {
+ return ((int)buf[0])&0xff;
+ }
+ }
+
+ @Override
+ public int read(final byte[] dst, final int off, final int len)
+ {
+ while(_currentPos == _currentBuffer.length)
+ {
+ if(!_bodiesIter.hasNext())
+ {
+ return -1;
+ }
+ else
+ {
+ _currentBuffer = _bodiesIter.next().getPayload();
+ _currentPos = 0;
+ }
+ }
+ int size = Math.min(len, _currentBuffer.length - _currentPos);
+ System.arraycopy(_currentBuffer,_currentPos, dst,off,size);
+ _currentPos+=size;
+ return size;
+ }
+
+ @Override
+ public void close()
+ {
+ }
+ }
}
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/jms/ConnectionURL.java b/qpid/java/client/src/main/java/org/apache/qpid/jms/ConnectionURL.java
index 2901a5f983..754b90c372 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/jms/ConnectionURL.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/jms/ConnectionURL.java
@@ -70,6 +70,11 @@ public interface ConnectionURL
*/
public static final String OPTIONS_CLOSE_WHEN_NO_ROUTE = "closeWhenNoRoute";
+
+ public static final String OPTIONS_COMPRESS_MESSAGES = "compressMessages";
+ public static final String OPTIONS_MESSAGES_COMPRESSION_THRESHOLD_SIZE = "messageCompressionThresholdSize";
+
+
public static final String OPTIONS_DEFAULT_TOPIC_EXCHANGE = "defaultTopicExchange";
public static final String OPTIONS_DEFAULT_QUEUE_EXCHANGE = "defaultQueueExchange";
public static final String OPTIONS_TEMPORARY_TOPIC_EXCHANGE = "temporaryTopicExchange";
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/configuration/ClientProperties.java b/qpid/java/common/src/main/java/org/apache/qpid/configuration/ClientProperties.java
index f10961c092..24ec496cc9 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/configuration/ClientProperties.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/configuration/ClientProperties.java
@@ -254,6 +254,19 @@ public class ClientProperties
public static final String CONNECTION_OPTION_SSL_VERIFY_HOST_NAME = "qpid.connection_ssl_verify_hostname";
public static final boolean DEFAULT_CONNECTION_OPTION_SSL_VERIFY_HOST_NAME = true;
+ /**
+ * System property to set a default value for a connection option 'compress_messages'
+ */
+ public static final String CONNECTION_OPTION_COMPRESS_MESSAGES = "qpid.connection_compress_messages";
+ public static final boolean DEFAULT_CONNECTION_OPTION_COMPRESS_MESSAGES = false;
+
+
+ /**
+ * System property to set a default value for a connection option 'message_compression_threshold_size'
+ */
+ public static final String CONNECTION_OPTION_MESSAGE_COMPRESSION_THRESHOLD_SIZE = "qpid.message_compression_threshold_size";
+ public static final int DEFAULT_MESSAGE_COMPRESSION_THRESHOLD_SIZE = 102400;
+
private ClientProperties()
{
//No instances
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/framing/BasicContentHeaderProperties.java b/qpid/java/common/src/main/java/org/apache/qpid/framing/BasicContentHeaderProperties.java
index fe8c94cee1..b490aee898 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/framing/BasicContentHeaderProperties.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/framing/BasicContentHeaderProperties.java
@@ -20,13 +20,13 @@
*/
package org.apache.qpid.framing;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
public class BasicContentHeaderProperties
{
//persistent & non-persistent constants, values as per JMS DeliveryMode
@@ -83,8 +83,48 @@ public class BasicContentHeaderProperties
private byte[] _encodedForm;
+ public BasicContentHeaderProperties(BasicContentHeaderProperties other)
+ {
+ if(other._headers != null)
+ {
+ byte[] encodedHeaders = other._headers.getDataAsBytes();
+
+ _headers = new FieldTable(encodedHeaders,0,encodedHeaders.length);
+
+ }
+
+ _contentType = other._contentType;
+
+ _encoding = other._encoding;
+
+ _deliveryMode = other._deliveryMode;
+
+ _priority = other._priority;
+
+ _correlationId = other._correlationId;
+
+ _replyTo = other._replyTo;
+
+ _expiration = other._expiration;
+
+ _messageId = other._messageId;
+
+ _timestamp = other._timestamp;
+
+ _type = other._type;
+
+ _userId = other._userId;
+
+ _appId = other._appId;
+
+ _clusterId = other._clusterId;
+
+ _propertyFlags = other._propertyFlags;
+ }
+
public BasicContentHeaderProperties()
- { }
+ {
+ }
public int getPropertyListSize()
{
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/framing/FieldTable.java b/qpid/java/common/src/main/java/org/apache/qpid/framing/FieldTable.java
index c4220894a8..9a455ce868 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/framing/FieldTable.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/framing/FieldTable.java
@@ -84,7 +84,7 @@ public class FieldTable
_encodedSize = length;
}
- public FieldTable(byte[] encodedForm, int offset, int length) throws IOException
+ public FieldTable(byte[] encodedForm, int offset, int length)
{
this();
_encodedForm = encodedForm;
@@ -858,7 +858,17 @@ public class FieldTable
}
}
- return _encodedForm.clone();
+ else if(_encodedFormOffset == 0 && _encodedSize == _encodedForm.length)
+ {
+ return _encodedForm.clone();
+ }
+ else
+ {
+ byte[] encodedCopy = new byte[(int) _encodedSize];
+ System.arraycopy(_encodedForm,_encodedFormOffset,encodedCopy,0,(int)_encodedSize);
+ return encodedCopy;
+ }
+
}
public long getEncodedSize()
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/properties/ConnectionStartProperties.java b/qpid/java/common/src/main/java/org/apache/qpid/properties/ConnectionStartProperties.java
index b2bcc1836e..8f1a1d0be0 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/properties/ConnectionStartProperties.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/properties/ConnectionStartProperties.java
@@ -41,6 +41,9 @@ public class ConnectionStartProperties
*/
public static final String QPID_CLOSE_WHEN_NO_ROUTE = "qpid.close_when_no_route";
+ public static final String QPID_MESSAGE_COMPRESSION_SUPPORTED = "qpid.message_compression_supported";
+
+
public static final String CLIENT_ID_0_10 = "clientName";
public static final String CLIENT_ID_0_8 = "instance";
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/Connection.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/Connection.java
index 44cb30e735..99fc02c959 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/transport/Connection.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/transport/Connection.java
@@ -41,6 +41,7 @@ import javax.security.sasl.SaslClient;
import javax.security.sasl.SaslServer;
import org.apache.qpid.framing.ProtocolVersion;
+import org.apache.qpid.properties.ConnectionStartProperties;
import org.apache.qpid.transport.network.Assembler;
import org.apache.qpid.transport.network.Disassembler;
import org.apache.qpid.transport.network.InputHandler;
@@ -78,6 +79,7 @@ public class Connection extends ConnectionInvoker
private long _lastReadTime;
private NetworkConnection _networkConnection;
private FrameSizeObserver _frameSizeObserver;
+ private boolean _messageCompressionSupported;
public enum State { NEW, CLOSED, OPENING, OPEN, CLOSING, CLOSE_RCVD, RESUMING }
@@ -699,6 +701,7 @@ public class Connection extends ConnectionInvoker
public void setServerProperties(final Map<String, Object> serverProperties)
{
_serverProperties = serverProperties == null ? Collections.<String, Object>emptyMap() : serverProperties;
+ _messageCompressionSupported = Boolean.parseBoolean(String.valueOf(_serverProperties.get(ConnectionStartProperties.QPID_MESSAGE_COMPRESSION_SUPPORTED)));
}
public Map<String, Object> getServerProperties()
@@ -848,4 +851,9 @@ public class Connection extends ConnectionInvoker
};
}
}
+
+ public boolean isMessageCompressionSupported()
+ {
+ return _messageCompressionSupported;
+ }
}
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/util/ByteBufferInputStream.java b/qpid/java/common/src/main/java/org/apache/qpid/util/ByteBufferInputStream.java
index b72b342187..14b804f8c0 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/util/ByteBufferInputStream.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/util/ByteBufferInputStream.java
@@ -92,4 +92,9 @@ public class ByteBufferInputStream extends InputStream
{
return _buffer.remaining();
}
+
+ @Override
+ public void close()
+ {
+ }
}
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/util/GZIPUtils.java b/qpid/java/common/src/main/java/org/apache/qpid/util/GZIPUtils.java
new file mode 100644
index 0000000000..b5ba0b29af
--- /dev/null
+++ b/qpid/java/common/src/main/java/org/apache/qpid/util/GZIPUtils.java
@@ -0,0 +1,119 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.util;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.ByteBuffer;
+import java.util.zip.GZIPInputStream;
+import java.util.zip.GZIPOutputStream;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class GZIPUtils
+{
+ private static final Logger LOGGER = LoggerFactory.getLogger(GZIPUtils.class);
+
+ public static final String GZIP_CONTENT_ENCODING = "gzip";
+
+
+ /**
+ * Return a new byte array with the compressed contents of the input buffer
+ *
+ * @param input byte buffer to compress
+ * @return a byte array containing the compressed data, or null if the input was null or there was an unexpected
+ * IOException while compressing
+ */
+ public static byte[] compressBufferToArray(ByteBuffer input)
+ {
+ if(input != null)
+ {
+ try (ByteArrayOutputStream compressedBuffer = new ByteArrayOutputStream())
+ {
+ try (GZIPOutputStream gzipOutputStream = new GZIPOutputStream(compressedBuffer))
+ {
+ if (input.hasArray())
+ {
+ gzipOutputStream.write(input.array(),
+ input.arrayOffset() + input.position(),
+ input.remaining());
+ }
+ else
+ {
+
+ byte[] data = new byte[input.remaining()];
+
+ input.duplicate().get(data);
+
+ gzipOutputStream.write(data);
+ }
+ }
+ return compressedBuffer.toByteArray();
+ }
+ catch (IOException e)
+ {
+ LOGGER.warn("Unexpected IOException when attempting to compress with gzip", e);
+ }
+ }
+ return null;
+ }
+
+ public static byte[] uncompressBufferToArray(ByteBuffer contentBuffer)
+ {
+ if(contentBuffer != null)
+ {
+ try (ByteBufferInputStream input = new ByteBufferInputStream(contentBuffer))
+ {
+ return uncompressStreamToArray(input);
+ }
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ public static byte[] uncompressStreamToArray(InputStream stream)
+ {
+ if(stream != null)
+ {
+ try (GZIPInputStream gzipInputStream = new GZIPInputStream(stream))
+ {
+ ByteArrayOutputStream inflatedContent = new ByteArrayOutputStream();
+ int read;
+ byte[] buf = new byte[4096];
+ while ((read = gzipInputStream.read(buf)) != -1)
+ {
+ inflatedContent.write(buf, 0, read);
+ }
+ return inflatedContent.toByteArray();
+ }
+ catch (IOException e)
+ {
+
+ LOGGER.warn("Unexpected IOException when attempting to uncompress with gzip", e);
+ }
+ }
+ return null;
+ }
+}
diff --git a/qpid/java/common/src/test/java/org/apache/qpid/util/GZIPUtilsTest.java b/qpid/java/common/src/test/java/org/apache/qpid/util/GZIPUtilsTest.java
new file mode 100644
index 0000000000..60e80da15f
--- /dev/null
+++ b/qpid/java/common/src/test/java/org/apache/qpid/util/GZIPUtilsTest.java
@@ -0,0 +1,102 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.util;
+
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+
+import junit.framework.TestCase;
+
+public class GZIPUtilsTest extends TestCase
+{
+ public void testCompressUncompress() throws Exception
+ {
+ byte[] data = new byte[1024];
+ Arrays.fill(data, (byte)'a');
+ byte[] compressed = GZIPUtils.compressBufferToArray(ByteBuffer.wrap(data));
+ assertTrue("Compression didn't compress", compressed.length < data.length);
+ byte[] uncompressed = GZIPUtils.uncompressBufferToArray(ByteBuffer.wrap(compressed));
+ assertTrue("Compression not reversible", Arrays.equals(data,uncompressed));
+ }
+
+ public void testUncompressNonZipReturnsNull() throws Exception
+ {
+ byte[] data = new byte[1024];
+ Arrays.fill(data, (byte)'a');
+ assertNull("Non zipped data should not uncompress", GZIPUtils.uncompressBufferToArray(ByteBuffer.wrap(data)));
+ }
+
+ public void testUncompressStreamWithErrorReturnsNull() throws Exception
+ {
+ InputStream is = new InputStream()
+ {
+ @Override
+ public int read() throws IOException
+ {
+ throw new IOException();
+ }
+ };
+ assertNull("Stream error should return null", GZIPUtils.uncompressStreamToArray(is));
+ }
+
+
+ public void testUncompressNullStreamReturnsNull() throws Exception
+ {
+ assertNull("Null Stream should return null", GZIPUtils.uncompressStreamToArray(null));
+ }
+ public void testUncompressNullBufferReturnsNull() throws Exception
+ {
+ assertNull("Null buffer should return null", GZIPUtils.uncompressBufferToArray(null));
+ }
+
+ public void testCompressNullArrayReturnsNull()
+ {
+ assertNull(GZIPUtils.compressBufferToArray(null));
+ }
+
+ public void testNonHeapBuffers() throws Exception
+ {
+
+ byte[] data = new byte[1024];
+ Arrays.fill(data, (byte)'a');
+ ByteBuffer directBuffer = ByteBuffer.allocateDirect(1024);
+ directBuffer.put(data);
+ directBuffer.flip();
+
+ byte[] compressed = GZIPUtils.compressBufferToArray(directBuffer);
+
+ assertTrue("Compression didn't compress", compressed.length < data.length);
+
+ directBuffer.clear();
+ directBuffer.position(1);
+ directBuffer = directBuffer.slice();
+ directBuffer.put(compressed);
+ directBuffer.flip();
+
+ byte[] uncompressed = GZIPUtils.uncompressBufferToArray(directBuffer);
+
+ assertTrue("Compression not reversible", Arrays.equals(data,uncompressed));
+
+ }
+}
diff --git a/qpid/java/pom.xml b/qpid/java/pom.xml
index b30472ce88..1be2ce0f95 100644
--- a/qpid/java/pom.xml
+++ b/qpid/java/pom.xml
@@ -54,6 +54,7 @@
<qpid.home.qbtc.output>${qpid.home}${file.separator}target${file.separator}qbtc-output</qpid.home.qbtc.output> <!-- override for broker tests -->
<qpid.work>${project.build.directory}${file.separator}QPID_WORK</qpid.work>
+ <argLine />
<profile>java-mms.0-10</profile>
<profile.broker.language>java</profile.broker.language>
<profile.broker.type>internal</profile.broker.type>
diff --git a/qpid/java/systests/src/test/java/org/apache/qpid/systest/MessageCompressionTest.java b/qpid/java/systests/src/test/java/org/apache/qpid/systest/MessageCompressionTest.java
new file mode 100644
index 0000000000..e1fca306ce
--- /dev/null
+++ b/qpid/java/systests/src/test/java/org/apache/qpid/systest/MessageCompressionTest.java
@@ -0,0 +1,236 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.systest;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import javax.jms.Connection;
+import javax.jms.JMSException;
+import javax.jms.MessageConsumer;
+import javax.jms.MessageProducer;
+import javax.jms.Session;
+import javax.jms.TextMessage;
+import javax.naming.NamingException;
+
+import org.apache.qpid.client.AMQConnectionURL;
+import org.apache.qpid.client.AMQSession;
+import org.apache.qpid.jms.ConnectionURL;
+import org.apache.qpid.server.management.plugin.HttpManagement;
+import org.apache.qpid.server.model.AuthenticationProvider;
+import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.model.Plugin;
+import org.apache.qpid.server.model.Port;
+import org.apache.qpid.systest.rest.RestTestHelper;
+import org.apache.qpid.test.utils.QpidBrokerTestCase;
+import org.apache.qpid.test.utils.TestBrokerConfiguration;
+import org.apache.qpid.url.URLSyntaxException;
+
+public class MessageCompressionTest extends QpidBrokerTestCase
+{
+ private RestTestHelper _restTestHelper = new RestTestHelper(findFreePort());
+
+ @Override
+ public void setUp() throws Exception
+ {
+ // do nothing - only call setup after props set
+ }
+
+ public void doActualSetUp() throws Exception
+ {
+ // use webadmin account to perform tests
+ _restTestHelper.setUsernameAndPassword("webadmin", "webadmin");
+
+ TestBrokerConfiguration config = getBrokerConfiguration();
+ config.addHttpManagementConfiguration();
+ config.setObjectAttribute(Port.class,
+ TestBrokerConfiguration.ENTRY_NAME_HTTP_PORT,
+ Port.PORT,
+ _restTestHelper.getHttpPort());
+
+ config.setObjectAttribute(AuthenticationProvider.class, TestBrokerConfiguration.ENTRY_NAME_AUTHENTICATION_PROVIDER,
+ "secureOnlyMechanisms",
+ "{}");
+
+ // set password authentication provider on http port for the tests
+ config.setObjectAttribute(Port.class, TestBrokerConfiguration.ENTRY_NAME_HTTP_PORT, Port.AUTHENTICATION_PROVIDER,
+ TestBrokerConfiguration.ENTRY_NAME_AUTHENTICATION_PROVIDER);
+ config.setObjectAttribute(Plugin.class, TestBrokerConfiguration.ENTRY_NAME_HTTP_MANAGEMENT, HttpManagement.HTTP_BASIC_AUTHENTICATION_ENABLED, true);
+
+ super.setUp();
+ }
+
+ @Override
+ protected void tearDown() throws Exception
+ {
+ try
+ {
+ super.tearDown();
+ }
+ finally
+ {
+ _restTestHelper.tearDown();
+ }
+ }
+
+ public void testSenderCompressesReceiverUncompresses() throws Exception
+ {
+ doTestCompression(true, true, true);
+ }
+
+ public void testSenderCompressesOnly() throws Exception
+ {
+ doTestCompression(true, false, true);
+
+ }
+
+ public void testReceiverUncompressesOnly() throws Exception
+ {
+ doTestCompression(false, true, true);
+
+ }
+
+ public void testNoCompression() throws Exception
+ {
+ doTestCompression(false, false, true);
+
+ }
+
+
+ public void testDisablingCompressionAtBroker() throws Exception
+ {
+ doTestCompression(true, true, false);
+ }
+
+
+ private void doTestCompression(final boolean senderCompresses,
+ final boolean receiverUncompresses,
+ final boolean brokerCompressionEnabled) throws Exception
+ {
+
+ setTestSystemProperty(Broker.BROKER_MESSAGE_COMPRESSION_ENABLED, String.valueOf(brokerCompressionEnabled));
+
+ doActualSetUp();
+
+ String messageText = createMessageText();
+ Connection senderConnection = getConnection(senderCompresses);
+ String virtualPath = getConnectionFactory().getVirtualPath();
+ String testQueueName = getTestQueueName();
+
+ // create the queue using REST and bind it
+ assertEquals(201,
+ _restTestHelper.submitRequest("/api/latest/queue"
+ + virtualPath
+ + virtualPath
+ + "/"
+ + testQueueName, "PUT", Collections.<String, Object>emptyMap()));
+ assertEquals(201,
+ _restTestHelper.submitRequest("/api/latest/binding"
+ + virtualPath
+ + virtualPath
+ + "/amq.direct/"
+ + testQueueName
+ + "/"
+ + testQueueName, "PUT", Collections.<String, Object>emptyMap()));
+
+ Session session = senderConnection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ // send a large message
+ MessageProducer producer = session.createProducer(getTestQueue());
+ TextMessage sentMessage = session.createTextMessage(messageText);
+ sentMessage.setStringProperty("bar", "foo");
+
+ producer.send(sentMessage);
+ ((AMQSession)session).sync();
+
+ // get the number of bytes received at the broker on the connection
+ List<Map<String, Object>> connectionRestOutput = _restTestHelper.getJsonAsList("/api/latest/connection");
+ assertEquals(1, connectionRestOutput.size());
+ Map statistics = (Map) connectionRestOutput.get(0).get("statistics");
+ int bytesIn = (Integer) statistics.get("bytesIn");
+
+ // if sending compressed then the bytesIn statistic for the connection should reflect the compressed size of the
+ // message
+ if(senderCompresses && brokerCompressionEnabled)
+ {
+ assertTrue("Message was not sent compressed", bytesIn < messageText.length());
+ }
+ else
+ {
+ assertFalse("Message was incorrectly sent compressed", bytesIn < messageText.length());
+ }
+ senderConnection.close();
+
+ // receive the message
+ Connection consumerConnection = getConnection(receiverUncompresses);
+ session = consumerConnection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ MessageConsumer consumer = session.createConsumer(getTestQueue());
+ consumerConnection.start();
+
+ TextMessage message = (TextMessage) consumer.receive(500l);
+ assertNotNull("Message was not received", message);
+ assertEquals("Message was corrupted", messageText, message.getText());
+ assertEquals("Header was corrupted", "foo", message.getStringProperty("bar"));
+
+ // get the number of bytes sent by the broker
+ connectionRestOutput = _restTestHelper.getJsonAsList("/api/latest/connection");
+ assertEquals(1, connectionRestOutput.size());
+ statistics = (Map) connectionRestOutput.get(0).get("statistics");
+ int bytesOut = (Integer) statistics.get("bytesOut");
+
+ // if receiving compressed the bytes out statistic from the connection should reflect the compressed size of the
+ // message
+ if(receiverUncompresses && brokerCompressionEnabled)
+ {
+ assertTrue("Message was not received compressed", bytesOut < messageText.length());
+ }
+ else
+ {
+ assertFalse("Message was incorrectly received compressed", bytesOut < messageText.length());
+ }
+
+ consumerConnection.close();
+ }
+
+ private String createMessageText()
+ {
+ StringBuilder stringBuilder = new StringBuilder();
+ while(stringBuilder.length() < 2048*1024)
+ {
+ stringBuilder.append("This should compress easily. ");
+ }
+ return stringBuilder.toString();
+ }
+
+ private Connection getConnection(final boolean compress) throws URLSyntaxException, NamingException, JMSException
+ {
+ AMQConnectionURL url = new AMQConnectionURL(getConnectionFactory().getConnectionURLString());
+
+ url.setOption(ConnectionURL.OPTIONS_COMPRESS_MESSAGES,String.valueOf(compress));
+ url = new AMQConnectionURL(url.toString());
+ url.setUsername(GUEST_USERNAME);
+ url.setPassword(GUEST_PASSWORD);
+ url.setOption(ConnectionURL.OPTIONS_COMPRESS_MESSAGES,String.valueOf(compress));
+ return getConnection(url);
+ }
+
+}