summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Godfrey <rgodfrey@apache.org>2013-04-23 19:12:27 +0000
committerRobert Godfrey <rgodfrey@apache.org>2013-04-23 19:12:27 +0000
commit917a1f26f8f26730528dd538ab817a340cdd8715 (patch)
tree7e2ceb5cf2c31cf232d616fb7c96ea9489cd9fbc
parent8eaa6f007e3cf2d287067b993ccf8058d0c66690 (diff)
downloadqpid-python-917a1f26f8f26730528dd538ab817a340cdd8715.tar.gz
Merged up to r1465457
git-svn-id: https://svn.apache.org/repos/asf/qpid/branches/QPID-4659@1471100 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--qpid/java/broker-plugins/management-http/src/main/java/resources/addAuthenticationProvider.html2
-rw-r--r--qpid/java/broker-plugins/management-http/src/main/java/resources/addExchange.html2
-rw-r--r--qpid/java/broker-plugins/management-http/src/main/java/resources/addPort.html8
-rw-r--r--qpid/java/broker-plugins/management-http/src/main/java/resources/addQueue.html2
-rw-r--r--qpid/java/broker-plugins/management-http/src/main/java/resources/addVirtualHost.html2
-rw-r--r--qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/util.js38
-rw-r--r--qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/Broker.js117
-rw-r--r--qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/Connection.js2
-rw-r--r--qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/VirtualHost.js1
-rw-r--r--qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/addPort.js88
-rw-r--r--qpid/java/broker-plugins/management-http/src/main/java/resources/showBroker.html44
-rw-r--r--qpid/java/broker-plugins/management-http/src/main/java/resources/showConnection.html2
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/Main.java3
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/store/JsonConfigurationEntryStore.java4
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/store/MemoryConfigurationEntryStore.java8
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/model/Broker.java17
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/model/Model.java6
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/model/VirtualHost.java9
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AbstractAdapter.java24
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AuthenticationProviderAdapter.java3
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java46
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/GroupProviderAdapter.java2
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/PortAdapter.java68
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/PortFactory.java11
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/VirtualHostAdapter.java2
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/SubjectCreator.java31
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationManager.java7
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationManagerFactory.java16
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationProviderAttributeDescriptions.properties19
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationManager.java9
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/external/ExternalSaslServer.java89
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/group/GroupPrincipalAccessor.java52
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/model/adapter/PortFactoryTest.java2
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/security/SubjectCreatorTest.java43
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationManagerTest.java123
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/security/group/GroupPrincipalAccessorTest.java80
-rw-r--r--qpid/java/build.deps2
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/AMQTopic.java19
-rw-r--r--qpid/java/client/src/test/java/org/apache/qpid/client/AMQDestinationTest.java22
-rw-r--r--qpid/java/ivy.retrieve.xml2
-rw-r--r--qpid/java/lib/poms/je-5.0.73.xml (renamed from qpid/java/lib/poms/je-5.0.58.xml)2
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationTest.java76
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/systest/rest/AuthenticationProviderRestTest.java17
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/systest/rest/PortRestTest.java136
44 files changed, 891 insertions, 367 deletions
diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/addAuthenticationProvider.html b/qpid/java/broker-plugins/management-http/src/main/java/resources/addAuthenticationProvider.html
index f164ece082..90dd1f1090 100644
--- a/qpid/java/broker-plugins/management-http/src/main/java/resources/addAuthenticationProvider.html
+++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/addAuthenticationProvider.html
@@ -25,7 +25,7 @@
<tr>
<td class="tableContainer-labelCell" style="width: 300px;">Name*:</td>
<td class="tableContainer-valueCell"><input type="text" required="true" name="name"
- id="formAddAuthenticationProvider.name" placeholder="Name"
+ id="formAddAuthenticationProvider.name" placeholder="Name" regexp="^[\x20-\x2e\x30-\x7F]{1,255}$"
dojoType="dijit.form.ValidationTextBox" missingMessage="A name must be supplied" /></div></td>
</tr>
</table>
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 10ac5388ff..4a59cd2cbc 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
@@ -26,7 +26,7 @@
<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\>\>).*$', invalidMessage:'Reserved exchange name!'"/></td>
+ 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>
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 2f49ab1448..c37b879bd5 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
@@ -21,10 +21,11 @@
<div class="dijitHidden">
<div data-dojo-type="dijit.Dialog" style="width:600px;" data-dojo-props="title:'Port'" id="addPort">
<form id="formAddPort" method="post" dojoType="dijit.form.Form">
+ <div class="dijitDialogPaneContentArea">
<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" />
+ missingMessage="A name must be supplied" regexp="^[\x20-\x2e\x30-\x7F]{1,255}$"/>
<input data-dojo-type="dijit.form.NumberSpinner" id="formAddPort.port" required="true" data-dojo-props="label: 'Port Number*:'"
name="port" smallDelta="1" constraints="{min:1,max:65535,places:0, pattern: '#####'}"
missingMessage="A port number must be supplied" />
@@ -53,7 +54,7 @@
<div id="formAddPort:fieldsAMQP">
<input id="formAddPort.bindingAddress" type="text" name="bindingAddress" placeholder="*"
dojoType="dijit.form.TextBox" data-dojo-props="label: 'Binding address:'"/>
- <input id="formAddPort.protocolsDefault" type="checkbox" name="protocolsDefault" checked="checked"
+ <input id="formAddPort.protocolsDefault" type="checkbox" checked="checked"
dojoType="dijit.form.CheckBox" data-dojo-props="label: 'Support broker default AMQP versions:'"/>
<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:'"
@@ -80,8 +81,11 @@
</select>
</div>
<input type="hidden" id="formAddPort.id" name="id"/>
+ </div>
+ <div class="dijitDialogPaneActionBar">
<!-- submit buttons -->
<input type="submit" value="Save Port" label="Save Port" dojoType="dijit.form.Button" />
+ </div>
</form>
</div>
</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 d396f28877..950809d5fc 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
@@ -25,7 +25,7 @@
<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" /></td>
+ 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>
diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/addVirtualHost.html b/qpid/java/broker-plugins/management-http/src/main/java/resources/addVirtualHost.html
index d66e0e1b03..9b492ef26d 100644
--- a/qpid/java/broker-plugins/management-http/src/main/java/resources/addVirtualHost.html
+++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/addVirtualHost.html
@@ -27,7 +27,7 @@
<td class="tableContainer-valueCell">
<input type="text" required="true" name="name" id="formAddVirtualHost.name"
placeholder="Virtual Host Name" dojoType="dijit.form.ValidationTextBox"
- missingMessage="A name must be supplied" />
+ missingMessage="A name must be supplied" regexp="^[\x20-\x2e\x30-\x7F]{1,255}$"/>
</td>
</tr>
</table>
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 fea67d5942..5ff208d43f 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
@@ -26,6 +26,7 @@ define(["dojo/_base/xhr",
"dojo/dom-construct",
"dojo/dom-geometry",
"dojo/window",
+ "dijit/TitlePane",
"dijit/Dialog",
"dijit/form/Form",
"dijit/form/Button",
@@ -163,6 +164,7 @@ define(["dojo/_base/xhr",
var widgets = {};
var requiredFor ={};
+ var groups = {};
for(var i in attributeWidgetFactories)
{
var attributeWidgetFactory = attributeWidgetFactories[i];
@@ -170,8 +172,38 @@ define(["dojo/_base/xhr",
var name = attributeWidgetFactory.name ? attributeWidgetFactory.name : widget.name;
widgets[name] = widget;
widget.initialValue = widget.value;
- layout.addChild(widget);
- if (attributeWidgetFactory.hasOwnProperty("requiredFor"))
+ var dotPos = name.indexOf(".");
+ if (dotPos == -1)
+ {
+ layout.addChild(widget);
+ }
+ else
+ {
+ var groupName = name.substring(0, dotPos);
+ var groupFieldContainer = null;
+ if (groups.hasOwnProperty(groupName))
+ {
+ groupFieldContainer = groups[groupName];
+ }
+ else
+ {
+ groupFieldContainer = new dojox.layout.TableContainer({
+ cols: 1,
+ "labelWidth": "290",
+ showLabels: true,
+ orientation: "horiz",
+ customClass: "formLabel"
+ });
+ groups[groupName] = groupFieldContainer;
+ var groupTitle = attributeWidgetFactory.groupName ? attributeWidgetFactory.groupName :
+ groupName.charAt(0).toUpperCase() + groupName.slice(1);
+ var panel = new dijit.TitlePane({title: groupTitle, toggleable: false, content: groupFieldContainer.domNode});
+ dialogContentArea.appendChild(dom.create("br"));
+ dialogContentArea.appendChild(panel.domNode);
+ }
+ groupFieldContainer.addChild(widget);
+ }
+ if (attributeWidgetFactory.hasOwnProperty("requiredFor") && !data[name])
{
requiredFor[attributeWidgetFactory.requiredFor] = widget;
}
@@ -249,7 +281,7 @@ define(["dojo/_base/xhr",
form.connectChildren(true);
setAttributesDialog.startup();
setAttributesDialog.on("show", function(){
- var data = geometry.position(layout.domNode);
+ var data = geometry.position(dialogContentArea);
var maxHeight = win.getBox().h * 0.6;
if (data.h > maxHeight)
{
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 f5e40025c2..04ac80784a 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
@@ -125,23 +125,25 @@ define(["dojo/_base/xhr",
name: "keyStorePath"});
}
}, {
- name: "keyStoreCertAlias",
+ name: "keyStorePassword",
+ requiredFor: "keyStorePath",
createWidget: function(brokerData) {
return new dijit.form.ValidationTextBox({
required: false,
- value: brokerData.keyStoreCertAlias,
- label: "Keystore certificate alias:",
- name: "keyStoreCertAlias"});
+ label: "Keystore password:",
+ invalidMessage: "Missed keystore password",
+ name: "keyStorePassword",
+ placeholder: brokerData["keyStorePassword"] ? brokerData["keyStorePassword"] : ""
+ });
}
}, {
- name: "keyStorePassword",
- requiredFor: "keyStorePath",
+ name: "keyStoreCertAlias",
createWidget: function(brokerData) {
return new dijit.form.ValidationTextBox({
required: false,
- label: "Keystore password:",
- invalidMessage: "Missed keystore password",
- name: "keyStorePassword"});
+ value: brokerData.keyStoreCertAlias,
+ label: "Keystore certificate alias:",
+ name: "keyStoreCertAlias"});
}
}, {
name: "trustStorePath",
@@ -161,7 +163,9 @@ define(["dojo/_base/xhr",
required: false,
label: "Truststore password:",
invalidMessage: "Missed trustore password",
- name: "trustStorePassword"});
+ name: "trustStorePassword",
+ placeholder: brokerData["trustStorePassword"] ? brokerData["trustStorePassword"] : ""
+ });
}
}, {
name: "peerStorePath",
@@ -180,10 +184,37 @@ define(["dojo/_base/xhr",
required: false,
label: "Peerstore password:",
invalidMessage: "Missed peerstore password",
- name: "peerStorePassword"});
+ name: "peerStorePassword",
+ placeholder: brokerData["peerStorePassword"] ? brokerData["peerStorePassword"] : ""
+ });
+ }
+ }, {
+ name: "statisticsReportingPeriod",
+ createWidget: function(brokerData) {
+ return new dijit.form.ValidationTextBox({
+ trim: "true",
+ regexp: "[0-9]+",
+ invalidMessage: "Invalid value",
+ required: false,
+ value: brokerData.statisticsReportingPeriod,
+ placeholder: "Time in ms",
+ label: "Statistics reporting period (ms):",
+ name: "statisticsReportingPeriod"
+ });
+ }
+ }, {
+ name: "statisticsReportingResetEnabled",
+ createWidget: function(brokerData)
+ {
+ return new dijit.form.CheckBox({
+ required: false, checked: brokerData.statisticsReportingResetEnabled, value: "true",
+ label: "Statistics reporting period enabled:",
+ name: "statisticsReportingResetEnabled"
+ });
}
}, {
name: "queue.alertThresholdQueueDepthMessages",
+ groupName: "Global Queue Defaults",
createWidget: function(brokerData) {
return new dijit.form.ValidationTextBox({
trim: "true",
@@ -191,8 +222,8 @@ define(["dojo/_base/xhr",
invalidMessage: "Invalid value",
required: false,
value: brokerData["queue.alertThresholdQueueDepthMessages"],
- placeholder: "Count of messages",
- label: "Queue depth messages alert threshold:",
+ placeholder: "Number of messages",
+ label: "Depth alert threshold (messages):",
name: "queue.alertThresholdQueueDepthMessages"
});
}
@@ -206,7 +237,7 @@ define(["dojo/_base/xhr",
required: false,
value: brokerData["queue.alertThresholdQueueDepthBytes"],
placeholder: "Number of bytes",
- label: "Queue depth bytes alert threshold:",
+ label: "Depth alert threshold (bytes):",
name: "queue.alertThresholdQueueDepthBytes"
});
}
@@ -220,7 +251,7 @@ define(["dojo/_base/xhr",
required: false,
value: brokerData["queue.alertThresholdMessageAge"],
placeholder: "Time in ms",
- label: "Queue message age alert threshold:",
+ label: "Message age alert threshold (ms):",
name: "queue.alertThresholdMessageAge"
});
}
@@ -234,7 +265,7 @@ define(["dojo/_base/xhr",
required: false,
value: brokerData["queue.alertThresholdMessageSize"],
placeholder: "Size in bytes",
- label: "Queue message size alert threshold:",
+ label: "Message size alert threshold (bytes):",
name: "queue.alertThresholdMessageSize"
});
}
@@ -248,7 +279,7 @@ define(["dojo/_base/xhr",
required: false,
value: brokerData["queue.alertRepeatGap"],
placeholder: "Time in ms",
- label: "Queue alert repeat gap:",
+ label: "Alert repeat gap (ms):",
name: "queue.alertRepeatGap"
});
}
@@ -261,8 +292,8 @@ define(["dojo/_base/xhr",
invalidMessage: "Invalid value",
required: false,
value: brokerData["queue.maximumDeliveryAttempts"],
- placeholder: "Count of messages",
- label: "Queue maximum delivery retries:",
+ placeholder: "Number of messages",
+ label: "Maximum delivery retries (messages):",
name: "queue.maximumDeliveryAttempts"
});
}
@@ -287,7 +318,7 @@ define(["dojo/_base/xhr",
required: false,
value: brokerData["queue.flowControlSizeBytes"],
placeholder: "Size in bytes",
- label: "Queue flow capacity:",
+ label: "Flow control threshold (bytes):",
name: "queue.flowControlSizeBytes",
});
}
@@ -301,12 +332,13 @@ define(["dojo/_base/xhr",
required: false,
value: brokerData["queue.flowResumeSizeBytes"],
placeholder: "Size in bytes",
- label: "Queue flow resume capacity:",
+ label: "Flow resume threshold (bytes):",
name: "queue.flowResumeSizeBytes",
});
}
}, {
name: "connection.sessionCountLimit",
+ groupName: "Global Connection Defaults",
createWidget: function(brokerData)
{
return new dijit.form.NumberSpinner({
@@ -315,7 +347,7 @@ define(["dojo/_base/xhr",
value: brokerData["connection.sessionCountLimit"],
smallDelta: 1,
constraints: {min:1,max:65535,places:0, pattern: "#####"},
- label: "Connection session limit:",
+ label: "Maximum number of sessions:",
name: "connection.sessionCountLimit"
});
}
@@ -329,36 +361,13 @@ define(["dojo/_base/xhr",
required: false,
value: brokerData["connection.heartBeatDelay"],
placeholder: "Time in ms",
- label: "Heart beat delay:",
+ label: "Heart beat delay (ms):",
name: "connection.heartBeatDelay"
});
}
}, {
- name: "statisticsReportingPeriod",
- createWidget: function(brokerData) {
- return new dijit.form.ValidationTextBox({
- trim: "true",
- regexp: "[0-9]+",
- invalidMessage: "Invalid value",
- required: false,
- value: brokerData.statisticsReportingPeriod,
- placeholder: "Time in ms",
- label: "Statistics reporting period:",
- name: "statisticsReportingPeriod"
- });
- }
- }, {
- name: "statisticsReportingResetEnabled",
- createWidget: function(brokerData)
- {
- return new dijit.form.CheckBox({
- required: false, checked: brokerData.statisticsReportingResetEnabled, value: "true",
- label: "Statistics reporting period enabled:",
- name: "statisticsReportingResetEnabled"
- });
- }
- }, {
name: "virtualhost.housekeepingCheckPeriod",
+ groupName: "Global Virtual Host defaults",
createWidget: function(brokerData) {
return new dijit.form.ValidationTextBox({
trim: "true",
@@ -367,7 +376,7 @@ define(["dojo/_base/xhr",
required: false,
value: brokerData["virtualhost.housekeepingCheckPeriod"],
placeholder: "Time in ms",
- label: "House keeping check period:",
+ label: "House keeping check period (ms):",
name: "virtualhost.housekeepingCheckPeriod"
});
}
@@ -381,7 +390,7 @@ define(["dojo/_base/xhr",
required: false,
value: brokerData["virtualhost.storeTransactionIdleTimeoutClose"],
placeholder: "Time in ms",
- label: "Idle store transaction close timeout:",
+ label: "Idle store transaction close timeout (ms):",
name: "virtualhost.storeTransactionIdleTimeoutClose"
});
}
@@ -395,7 +404,7 @@ define(["dojo/_base/xhr",
required: false,
value: brokerData["virtualhost.storeTransactionIdleTimeoutWarn"],
placeholder: "Time in ms",
- label: "Idle store transaction warn timeout:",
+ label: "Idle store transaction warn timeout (ms):",
name: "virtualhost.storeTransactionIdleTimeoutWarn"
});
}
@@ -409,7 +418,7 @@ define(["dojo/_base/xhr",
required: false,
value: brokerData["virtualhost.storeTransactionOpenTimeoutClose"],
placeholder: "Time in ms",
- label: "Open store transaction close timeout:",
+ label: "Open store transaction close timeout (ms):",
name: "virtualhost.storeTransactionOpenTimeoutClose"
});
}
@@ -423,7 +432,7 @@ define(["dojo/_base/xhr",
required: false,
value: brokerData["virtualhost.storeTransactionOpenTimeoutWarn"],
placeholder: "Time in ms",
- label: "Open store transaction warn timeout:",
+ label: "Open store transaction warn timeout (ms):",
name: "virtualhost.storeTransactionOpenTimeoutWarn"
});
}
@@ -524,7 +533,6 @@ define(["dojo/_base/xhr",
util.flattenStatistics( that.brokerData);
- that.showReadOnlyAttributes();
that.updateHeader();
var gridProperties = {
@@ -649,6 +657,7 @@ define(["dojo/_base/xhr",
BrokerUpdater.prototype.updateHeader = function()
{
+ this.showReadOnlyAttributes();
var brokerData = this.brokerData;
for(var i in this.attributes)
{
@@ -709,7 +718,7 @@ define(["dojo/_base/xhr",
dojo.byId("brokerAttribute.operatingSystem").innerHTML = brokerData.operatingSystem;
dojo.byId("brokerAttribute.platform").innerHTML = brokerData.platform;
dojo.byId("brokerAttribute.productVersion").innerHTML = brokerData.productVersion;
- dojo.byId("brokerAttribute.managementVersion").innerHTML = brokerData.managementVersion;
+ dojo.byId("brokerAttribute.modelVersion").innerHTML = brokerData.managementVersion;
dojo.byId("brokerAttribute.storeType").innerHTML = brokerData.storeType;
dojo.byId("brokerAttribute.storeVersion").innerHTML = brokerData.storeVersion;
dojo.byId("brokerAttribute.storePath").innerHTML = brokerData.storePath;
diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/Connection.js b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/Connection.js
index 01f9a325c5..91dc52d6cf 100644
--- a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/Connection.js
+++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/Connection.js
@@ -85,6 +85,7 @@ define(["dojo/_base/xhr",
storeNodes(["name",
"state",
"durable",
+ "principal",
"lifetimePolicy",
"msgInRate",
"bytesInRate",
@@ -123,6 +124,7 @@ define(["dojo/_base/xhr",
this.name.innerHTML = this.connectionData[ "name" ];
this.state.innerHTML = this.connectionData[ "state" ];
this.durable.innerHTML = this.connectionData[ "durable" ];
+ this.principal.innerHTML = this.connectionData[ "principal" ];
this.lifetimePolicy.innerHTML = this.connectionData[ "lifetimePolicy" ];
};
diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/VirtualHost.js b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/VirtualHost.js
index db24951921..23c164f052 100644
--- a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/VirtualHost.js
+++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/VirtualHost.js
@@ -209,6 +209,7 @@ define(["dojo/_base/xhr",
findNode("connections"),
[ { name: "Name", field: "name", width: "150px"},
{ name: "Sessions", field: "sessionCount", width: "70px"},
+ { name: "User", field: "principal", width: "120px"},
{ name: "Msgs In", field: "msgInRate",
width: "80px"},
{ name: "Bytes In", field: "bytesInRate",
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 4d1e268d4d..0c1a188cbf 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
@@ -71,7 +71,7 @@ define(["dojo/_base/xhr",
{
if(formValues.hasOwnProperty(propName))
{
- if (propName === "type" || propName === "protocolsDefault")
+ if (propName == "needClientAuth" || propName == "wantClientAuth")
{
continue;
}
@@ -107,18 +107,37 @@ define(["dojo/_base/xhr",
}
}
- var needClientAuth = dijit.byId("formAddPort.needClientAuth");
- var wantClientAuth = dijit.byId("formAddPort.wantClientAuth");
- if(!needClientAuth.disabled)
+ var type = dijit.byId("formAddPort.type").value;
+ if (type == "AMQP")
{
- newPort.needClientAuth = needClientAuth.checked;
+ var needClientAuth = dijit.byId("formAddPort.needClientAuth");
+ var wantClientAuth = dijit.byId("formAddPort.wantClientAuth");
+ newPort.needClientAuth = needClientAuth.disabled ? false : needClientAuth.checked;
+ newPort.wantClientAuth = wantClientAuth.disabled ? false : wantClientAuth.checked
}
- if(!wantClientAuth.disabled)
+ return newPort;
+ };
+
+ var toggleCertificateWidgets = function toggleCertificateWidgets(protocolType, transportType)
+ {
+ var clientAuthPanel = registry.byId("formAddPort:fieldsClientAuth");
+ var display = clientAuthPanel.domNode.style.display;
+ if (transportType == "SSL" && protocolType == "AMQP")
{
- newPort.wantClientAuth = wantClientAuth.checked;
+ clientAuthPanel.domNode.style.display = "block";
+ registry.byId("formAddPort.needClientAuth").set("disabled", false);
+ registry.byId("formAddPort.wantClientAuth").set("disabled", false);
+ }
+ else
+ {
+ clientAuthPanel.domNode.style.display = "none";
+ registry.byId("formAddPort.needClientAuth").set("disabled", true);
+ registry.byId("formAddPort.wantClientAuth").set("disabled", true);
+ }
+ if (clientAuthPanel.domNode.style.display != display)
+ {
+ clientAuthPanel.resize();
}
-
- return newPort;
};
@@ -134,6 +153,11 @@ define(["dojo/_base/xhr",
dijit.byId("formAddPort.protocolsAMQP").set("disabled", isChecked);
});
+ registry.byId("formAddPort.transports").on("change", function(newValue){
+ var protocolType = registry.byId("formAddPort.type").value;
+ toggleCertificateWidgets(protocolType, newValue);
+ });
+
registry.byId("formAddPort.type").on("change", function(newValue) {
var typeWidget = registry.byId("formAddPort.type");
var store = typeWidget.store;
@@ -142,20 +166,8 @@ define(["dojo/_base/xhr",
registry.byId("formAddPort:fields" + option.value).domNode.style.display = "none";
});
- if ("AMQP" == newValue)
- {
- registry.byId("formAddPort:fieldsClientAuth").domNode.style.display = "block";
- registry.byId("formAddPort.needClientAuth").set("disabled", false);
- registry.byId("formAddPort.wantClientAuth").set("disabled", false);
- }
- else
- {
- registry.byId("formAddPort:fieldsClientAuth").domNode.style.display = "none";
- registry.byId("formAddPort.needClientAuth").set("checked", false);
- registry.byId("formAddPort.wantClientAuth").set("checked", false);
- registry.byId("formAddPort.needClientAuth").set("disabled", true);
- registry.byId("formAddPort.wantClientAuth").set("disabled", true);
- }
+ registry.byId("formAddPort.needClientAuth").set("enabled", ("AMQP" == newValue));
+ registry.byId("formAddPort.wantClientAuth").set("enabled", ("AMQP" == newValue));
registry.byId("formAddPort:fields" + newValue).domNode.style.display = "block";
var defaultsAMQPProtocols = registry.byId("formAddPort.protocolsDefault");
@@ -163,20 +175,10 @@ define(["dojo/_base/xhr",
var protocolsWidget = registry.byId("formAddPort.protocols" + newValue);
if (protocolsWidget)
{
- if ("AMQP" == newValue && defaultsAMQPProtocols.checked)
- {
- protocolsWidget.set("disabled", true);
- }
- else
- {
- protocolsWidget.set("disabled", false);
- }
- }
- var transportsWidget = registry.byId("formAddPort.transports");
- if (transportsWidget)
- {
- transportsWidget.startup();
+ protocolsWidget.set("disabled", ("AMQP" == newValue && defaultsAMQPProtocols.checked));
}
+ var transport = registry.byId("formAddPort.transports").value;
+ toggleCertificateWidgets(newValue, transport);
});
theForm = registry.byId("formAddPort");
@@ -289,7 +291,8 @@ define(["dojo/_base/xhr",
nameField.set("disabled", true);
dom.byId("formAddPort.id").value=port.id;
providerWidget.set("value", port.authenticationProvider ? port.authenticationProvider : "");
- registry.byId("formAddPort.transports").set("value", port.transports ? port.transports[0] : "");
+ var transportWidget = registry.byId("formAddPort.transports");
+ transportWidget.set("value", port.transports ? port.transports[0] : "");
registry.byId("formAddPort.port").set("value", port.port);
var protocols = port.protocols;
var typeWidget = registry.byId("formAddPort.type");
@@ -299,12 +302,6 @@ define(["dojo/_base/xhr",
registry.byId("formAddPort:fields" + option.value).domNode.style.display = "none";
});
- registry.byId("formAddPort.needClientAuth").set("checked", false);
- registry.byId("formAddPort.wantClientAuth").set("checked", false);
- registry.byId("formAddPort.needClientAuth").set("disabled", true);
- registry.byId("formAddPort.wantClientAuth").set("disabled", true);
- registry.byId("formAddPort:fieldsClientAuth").domNode.style.display = "none";
-
// identify the type of port using first protocol specified in protocol field if provided
if ( !protocols || protocols.length == 0 || protocols[0].indexOf("AMQP") == 0)
{
@@ -326,11 +323,8 @@ define(["dojo/_base/xhr",
amqpProtocolsWidget.set("disabled", true)
}
- registry.byId("formAddPort.needClientAuth").set("disabled", false);
- registry.byId("formAddPort.wantClientAuth").set("disabled", false);
registry.byId("formAddPort.needClientAuth").set("checked", port.needClientAuth);
registry.byId("formAddPort.wantClientAuth").set("checked", port.wantClientAuth);
- registry.byId("formAddPort:fieldsClientAuth").domNode.style.display = "block";
}
else if (protocols[0].indexOf("RMI") != -1)
{
@@ -348,6 +342,8 @@ define(["dojo/_base/xhr",
}
registry.byId("formAddPort:fields" + typeWidget.value).domNode.style.display = "block";
typeWidget.set("disabled", true);
+
+ toggleCertificateWidgets(typeWidget.value, transportWidget.value);
registry.byId("addPort").show();
});
}
diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/showBroker.html b/qpid/java/broker-plugins/management-http/src/main/java/resources/showBroker.html
index 0cac138cb1..887ca4e736 100644
--- a/qpid/java/broker-plugins/management-http/src/main/java/resources/showBroker.html
+++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/showBroker.html
@@ -37,9 +37,9 @@
<div class="formLabel-labelCell" style="float:left; width: 250px;">Broker version:</div>
<div id="brokerAttribute.productVersion" style="float:left;"></div>
</div>
- <div id="brokerAttribute.managementVersion.container" style="clear:both">
- <div class="formLabel-labelCell" style="float:left; width: 250px;">Broker management version:</div>
- <div id="brokerAttribute.managementVersion" style="float:left;"></div>
+ <div id="brokerAttribute.modelVersion.container" style="clear:both">
+ <div class="formLabel-labelCell" style="float:left; width: 250px;">Broker model version:</div>
+ <div id="brokerAttribute.modelVersion" style="float:left;"></div>
</div>
<div id="brokerAttribute.storeType.container" style="clear:both">
<div class="formLabel-labelCell" style="float:left; width: 250px;">Broker store type:</div>
@@ -72,7 +72,7 @@
<div id="brokerAttribute.keyStorePath.container" style="display: none; clear:both">
<div class="formLabel-labelCell" style="float:left; width: 250px;">Path to keystore:</div>
<div id="brokerAttribute.keyStorePath" style="float:left;"></div><br/>
- <div class="formLabel-labelCell" style="float:left; width: 250px;">Keystore alias:</div>
+ <div class="formLabel-labelCell" style="float:left; width: 250px;">Keystore certificate alias:</div>
<div id="brokerAttribute.keyStoreCertAlias" style="float:left;"></div>
</div>
<div id="brokerAttribute.trustStorePath.container" style="display: none; clear:both">
@@ -95,75 +95,75 @@
<br/>
<div data-dojo-type="dijit.TitlePane" data-dojo-props="title: 'Global Queue Defaults', open: true">
<div id="brokerAttribute.queue.alertThresholdQueueDepthMessages.container" style="clear:both">
- <div class="formLabel-labelCell" style="float:left; width: 250px;">Queue depth messages alert threshold:</div>
+ <div class="formLabel-labelCell" style="float:left; width: 240px;">Depth messages alert threshold:</div>
<div id="brokerAttribute.queue.alertThresholdQueueDepthMessages" style="float:left;"></div>
</div>
<div id="brokerAttribute.queue.alertThresholdQueueDepthBytes.container" style="clear:both">
- <div class="formLabel-labelCell" style="float:left; width: 250px;">Queue depth bytes alert threshold:</div>
+ <div class="formLabel-labelCell" style="float:left; width: 240px;">Depth bytes alert threshold:</div>
<div id="brokerAttribute.queue.alertThresholdQueueDepthBytes" style="float:left;"></div> bytes
</div>
<div id="brokerAttribute.queue.alertThresholdMessageAge.container" style="clear:both">
- <div class="formLabel-labelCell" style="float:left; width: 250px;">Queue message age alert threshold:</div>
+ <div class="formLabel-labelCell" style="float:left; width: 240px;">Message age alert threshold:</div>
<div id="brokerAttribute.queue.alertThresholdMessageAge" style="float:left;"></div> ms
</div>
<div id="brokerAttribute.queue.alertThresholdMessageSize.container" style="clear:both">
- <div class="formLabel-labelCell" style="float:left; width: 250px;">Queue message size alert threshold:</div>
+ <div class="formLabel-labelCell" style="float:left; width: 240px;">Message size alert threshold:</div>
<div id="brokerAttribute.queue.alertThresholdMessageSize" style="float:left;"></div> bytes
</div>
<div id="brokerAttribute.queue.alertRepeatGap.container" style="clear:both">
- <div class="formLabel-labelCell" style="float:left; width: 250px;">Queue alert repeat gap:</div>
+ <div class="formLabel-labelCell" style="float:left; width: 240px;">Alert repeat gap:</div>
<div id="brokerAttribute.queue.alertRepeatGap" style="float:left;"></div> ms
</div>
<div id="brokerAttribute.queue.maximumDeliveryAttempts.container" style="clear:both">
- <div class="formLabel-labelCell" style="float:left; width: 250px;">Queue maximum delivery retries:</div>
+ <div class="formLabel-labelCell" style="float:left; width: 250px;">Maximum delivery retries:</div>
<div id="brokerAttribute.queue.maximumDeliveryAttempts" style="float:left;"></div>
</div>
<div id="brokerAttribute.queue.deadLetterQueueEnabled.container" style="clear:both">
- <div class="formLabel-labelCell" style="float:left; width: 250px;">Dead letter queue enabled:</div>
+ <div class="formLabel-labelCell" style="float:left; width: 240px;">Dead letter queue enabled:</div>
<div id="brokerAttribute.queue.deadLetterQueueEnabled" style="float:left;"></div>
</div>
<div id="brokerAttribute.queue.flowControlSizeBytes.container" style="clear:both">
- <div class="formLabel-labelCell" style="float:left; width: 250px;">Queue flow capacity:</div>
+ <div class="formLabel-labelCell" style="float:left; width: 240px;">Flow control threshold:</div>
<div id="brokerAttribute.queue.flowControlSizeBytes" style="float:left;"></div> bytes
</div>
<div id="brokerAttribute.queue.flowResumeSizeBytes.container" style="clear:both">
- <div class="formLabel-labelCell" style="float:left; width: 250px;">Queue flow resume capacity:</div>
+ <div class="formLabel-labelCell" style="float:left; width: 240px;">Flow resume threshold:</div>
<div id="brokerAttribute.queue.flowResumeSizeBytes" style="float:left;"></div> bytes
</div>
<div style="clear:both"></div>
</div>
<br/>
- <div data-dojo-type="dijit.TitlePane" data-dojo-props="title: 'Global connection defaults', open: true">
+ <div data-dojo-type="dijit.TitlePane" data-dojo-props="title: 'Global Connection Defaults', open: true">
<div id="brokerAttribute.connection.sessionCountLimit.container" style="clear:both">
- <div class="formLabel-labelCell" style="float:left; width: 250px;">Connection session limit:</div>
+ <div class="formLabel-labelCell" style="float:left; width: 240px;">Maximum number of sessions:</div>
<div id="brokerAttribute.connection.sessionCountLimit" style="float:left;"></div>
</div>
<div id="brokerAttribute.connection.heartBeatDelay.container" style="clear:both">
- <div class="formLabel-labelCell" style="float:left; width: 250px;">Heart beat delay:</div>
+ <div class="formLabel-labelCell" style="float:left; width: 240px;">Heart beat delay:</div>
<div id="brokerAttribute.connection.heartBeatDelay" style="float:left;"></div> ms
</div>
<div style="clear:both"></div>
</div>
<br/>
- <div data-dojo-type="dijit.TitlePane" data-dojo-props="title: 'Global virtual host defaults', open: true">
+ <div data-dojo-type="dijit.TitlePane" data-dojo-props="title: 'Global Virtual Host Defaults', open: true">
<div id="brokerAttribute.virtualhost.housekeepingCheckPeriod.container" style="clear:both">
- <div class="formLabel-labelCell" style="float:left; width: 250px;">House keeping check period:</div>
+ <div class="formLabel-labelCell" style="float:left; width: 240px;">House keeping check period:</div>
<div id="brokerAttribute.virtualhost.housekeepingCheckPeriod" style="float:left;"></div>ms
</div>
<div id="brokerAttribute.virtualhost.storeTransactionIdleTimeoutClose.container" style="clear:both">
- <div class="formLabel-labelCell" style="float:left; width: 250px;">Idle store transaction close timeout:</div>
+ <div class="formLabel-labelCell" style="float:left; width: 240px;">Idle store transaction close timeout:</div>
<div id="brokerAttribute.virtualhost.storeTransactionIdleTimeoutClose" style="float:left;"></div>ms
</div>
<div id="brokerAttribute.virtualhost.storeTransactionIdleTimeoutWarn.container" style="clear:both">
- <div class="formLabel-labelCell" style="float:left; width: 250px;">Idle store transaction warn timeout:</div>
+ <div class="formLabel-labelCell" style="float:left; width: 240px;">Idle store transaction warn timeout:</div>
<div id="brokerAttribute.virtualhost.storeTransactionIdleTimeoutWarn" style="float:left;"></div>ms
</div>
<div id="brokerAttribute.virtualhost.storeTransactionOpenTimeoutClose.container" style="clear:both">
- <div class="formLabel-labelCell" style="float:left; width: 250px;">Open store transaction close timeout:</div>
+ <div class="formLabel-labelCell" style="float:left; width: 240px;">Open store transaction close timeout:</div>
<div id="brokerAttribute.virtualhost.storeTransactionOpenTimeoutClose" style="float:left;"></div>ms
</div>
<div id="brokerAttribute.virtualhost.storeTransactionOpenTimeoutWarn.container" style="clear:both">
- <div class="formLabel-labelCell" style="float:left; width: 250px;">Open store transaction warn timeout:</div>
+ <div class="formLabel-labelCell" style="float:left; width: 240px;">Open store transaction warn timeout:</div>
<div id="brokerAttribute.virtualhost.storeTransactionOpenTimeoutWarn" style="float:left;"></div>ms
</div>
<div style="clear:both"></div>
diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/showConnection.html b/qpid/java/broker-plugins/management-http/src/main/java/resources/showConnection.html
index 84854daf47..82869004a8 100644
--- a/qpid/java/broker-plugins/management-http/src/main/java/resources/showConnection.html
+++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/showConnection.html
@@ -38,6 +38,8 @@
<span class="bytesOutRate" style="position:absolute; right: 3.3em"></span>
<span class="bytesOutRateUnits" style="position:absolute; right: 0em; width: 3em"></span>
<br/>
+ <span style="">User:</span><span style="position:absolute; left:6em" class="principal"></span>
+ <br/>
<br/>
<div data-dojo-type="dijit.TitlePane" data-dojo-props="title: 'Sessions'">
<div class="sessions"></div>
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/Main.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/Main.java
index ddda137bcc..dcae3a0eaf 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/Main.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/Main.java
@@ -215,6 +215,9 @@ public class Main
{
options.setManagementModeHttpPort(Integer.parseInt(httpPort));
}
+
+ boolean quiesceVhosts = _commandLine.hasOption(OPTION_MM_QUIESCE_VHOST.getOpt());
+ options.setManagementModeQuiesceVirtualHosts(quiesceVhosts);
}
setExceptionHandler();
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/store/JsonConfigurationEntryStore.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/store/JsonConfigurationEntryStore.java
index 413e9d2563..7a1db3d46d 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/store/JsonConfigurationEntryStore.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/store/JsonConfigurationEntryStore.java
@@ -28,6 +28,10 @@ public class JsonConfigurationEntryStore extends MemoryConfigurationEntryStore
initialiseStore(_storeFile, initialStore);
}
load(fileToURL(_storeFile));
+ if(isGeneratedObjectIdDuringLoad())
+ {
+ saveAsTree(_storeFile);
+ }
}
@Override
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/store/MemoryConfigurationEntryStore.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/store/MemoryConfigurationEntryStore.java
index 5944adaa99..6931e22d63 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/store/MemoryConfigurationEntryStore.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/store/MemoryConfigurationEntryStore.java
@@ -75,6 +75,8 @@ public class MemoryConfigurationEntryStore implements ConfigurationEntryStore
private String _storeLocation;
private UUID _rootId;
+ private boolean _generatedObjectIdDuringLoad;
+
protected MemoryConfigurationEntryStore()
{
_objectMapper = new ObjectMapper();
@@ -592,6 +594,8 @@ public class MemoryConfigurationEntryStore implements ConfigurationEntryStore
{
id = UUIDGenerator.generateBrokerChildUUID(type, name);
}
+
+ _generatedObjectIdDuringLoad = true;
}
else
{
@@ -683,4 +687,8 @@ public class MemoryConfigurationEntryStore implements ConfigurationEntryStore
return array;
}
+ protected boolean isGeneratedObjectIdDuringLoad()
+ {
+ return _generatedObjectIdDuringLoad;
+ }
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/Broker.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/Broker.java
index 8f64cab2ec..ad0e68cee6 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/Broker.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/Broker.java
@@ -55,6 +55,12 @@ public interface Broker extends ConfiguredObject
String UPDATED = "updated";
String DEFAULT_AUTHENTICATION_PROVIDER = "defaultAuthenticationProvider";
String DEFAULT_VIRTUAL_HOST = "defaultVirtualHost";
+ String STATISTICS_REPORTING_PERIOD = "statisticsReportingPeriod";
+ String STATISTICS_REPORTING_RESET_ENABLED = "statisticsReportingResetEnabled";
+ String STORE_TYPE = "storeType";
+ String STORE_VERSION = "storeVersion";
+ String STORE_PATH = "storePath";
+ String MODEL_VERSION = "modelVersion";
String QUEUE_ALERT_THRESHOLD_MESSAGE_AGE = "queue.alertThresholdMessageAge";
String QUEUE_ALERT_THRESHOLD_QUEUE_DEPTH_MESSAGES = "queue.alertThresholdQueueDepthMessages";
@@ -65,21 +71,16 @@ public interface Broker extends ConfiguredObject
String QUEUE_FLOW_CONTROL_RESUME_SIZE_BYTES = "queue.flowResumeSizeBytes";
String QUEUE_MAXIMUM_DELIVERY_ATTEMPTS = "queue.maximumDeliveryAttempts";
String QUEUE_DEAD_LETTER_QUEUE_ENABLED = "queue.deadLetterQueueEnabled";
- String VIRTUALHOST_HOUSEKEEPING_CHECK_PERIOD = "virtualhost.housekeepingCheckPeriod";
String CONNECTION_SESSION_COUNT_LIMIT = "connection.sessionCountLimit";
String CONNECTION_HEART_BEAT_DELAY = "connection.heartBeatDelay";
- String STATISTICS_REPORTING_PERIOD = "statisticsReportingPeriod";
- String STATISTICS_REPORTING_RESET_ENABLED = "statisticsReportingResetEnabled";
- String STORE_TYPE = "storeType";
- String STORE_VERSION = "storeVersion";
- String STORE_PATH = "storePath";
- String MANAGEMENT_VERSION = "managementVersion";
+ String VIRTUALHOST_HOUSEKEEPING_CHECK_PERIOD = "virtualhost.housekeepingCheckPeriod";
String VIRTUALHOST_STORE_TRANSACTION_IDLE_TIMEOUT_CLOSE = "virtualhost.storeTransactionIdleTimeoutClose";
String VIRTUALHOST_STORE_TRANSACTION_IDLE_TIMEOUT_WARN = "virtualhost.storeTransactionIdleTimeoutWarn";
String VIRTUALHOST_STORE_TRANSACTION_OPEN_TIMEOUT_CLOSE = "virtualhost.storeTransactionOpenTimeoutClose";
String VIRTUALHOST_STORE_TRANSACTION_OPEN_TIMEOUT_WARN = "virtualhost.storeTransactionOpenTimeoutWarn";
+
/*
* A temporary attribute to pass the path to ACL file.
* TODO: It should be a part of AuthorizationProvider.
@@ -142,7 +143,7 @@ public interface Broker extends ConfiguredObject
STORE_TYPE,
STORE_VERSION,
STORE_PATH,
- MANAGEMENT_VERSION,
+ MODEL_VERSION,
VIRTUALHOST_STORE_TRANSACTION_IDLE_TIMEOUT_CLOSE,
VIRTUALHOST_STORE_TRANSACTION_IDLE_TIMEOUT_WARN,
VIRTUALHOST_STORE_TRANSACTION_OPEN_TIMEOUT_CLOSE,
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/Model.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/Model.java
index 3244d55fe2..bf4c40815a 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/Model.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/Model.java
@@ -30,10 +30,10 @@ import java.util.Map;
public class Model
{
/*
- * API version for the broker management interfaces
+ * API version for the broker model
*/
- public static final int MANAGEMENT_API_MAJOR_VERSION = 1;
- public static final int MANAGEMENT_API_MINOR_VERSION = 0;
+ public static final int MODEL_MAJOR_VERSION = 1;
+ public static final int MODEL_MINOR_VERSION = 0;
private static final Model MODEL_INSTANCE = new Model();
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/VirtualHost.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/VirtualHost.java
index d3d55f1880..424ba825d7 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/VirtualHost.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/VirtualHost.java
@@ -63,10 +63,11 @@ public interface VirtualHost extends ConfiguredObject
String QUEUE_ALERT_THRESHOLD_QUEUE_DEPTH_BYTES = "queue.alertThresholdQueueDepthBytes";
String QUEUE_ALERT_THRESHOLD_QUEUE_DEPTH_MESSAGES = "queue.alertThresholdQueueDepthMessages";
String QUEUE_DEAD_LETTER_QUEUE_ENABLED = "queue.deadLetterQueueEnabled";
+ String QUEUE_MAXIMUM_DELIVERY_ATTEMPTS = "queue.maximumDeliveryAttempts";
+ String QUEUE_FLOW_CONTROL_SIZE_BYTES = "queue.flowControlSizeBytes";
+ String QUEUE_FLOW_RESUME_SIZE_BYTES = "queue.flowResumeSizeBytes";
+
String HOUSEKEEPING_CHECK_PERIOD = "housekeepingCheckPeriod";
- String MAXIMUM_DELIVERY_ATTEMPTS = "queue.maximumDeliveryAttempts";
- String QUEUE_FLOW_CONTROL_SIZE_BYTES = "queue.flowControlSizeBytes";
- String QUEUE_FLOW_RESUME_SIZE_BYTES = "queue.flowResumeSizeBytes";
String STORE_TRANSACTION_IDLE_TIMEOUT_CLOSE = "storeTransactionIdleTimeoutClose";
String STORE_TRANSACTION_IDLE_TIMEOUT_WARN = "storeTransactionIdleTimeoutWarn";
String STORE_TRANSACTION_OPEN_TIMEOUT_CLOSE = "storeTransactionOpenTimeoutClose";
@@ -101,7 +102,7 @@ public interface VirtualHost extends ConfiguredObject
SUPPORTED_QUEUE_TYPES,
QUEUE_DEAD_LETTER_QUEUE_ENABLED,
HOUSEKEEPING_CHECK_PERIOD,
- MAXIMUM_DELIVERY_ATTEMPTS,
+ QUEUE_MAXIMUM_DELIVERY_ATTEMPTS,
QUEUE_FLOW_CONTROL_SIZE_BYTES,
QUEUE_FLOW_RESUME_SIZE_BYTES,
STORE_TYPE,
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AbstractAdapter.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AbstractAdapter.java
index 8ff0b6d9e1..20929a337a 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AbstractAdapter.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AbstractAdapter.java
@@ -32,6 +32,7 @@ import org.apache.qpid.server.model.ConfigurationChangeListener;
import org.apache.qpid.server.model.ConfiguredObject;
import org.apache.qpid.server.model.IllegalStateTransitionException;
import org.apache.qpid.server.model.State;
+import org.apache.qpid.server.configuration.IllegalConfigurationException;
import org.apache.qpid.server.configuration.updater.ChangeAttributesTask;
import org.apache.qpid.server.configuration.updater.ChangeStateTask;
import org.apache.qpid.server.configuration.updater.CreateChildTask;
@@ -40,6 +41,7 @@ import org.apache.qpid.server.configuration.updater.TaskExecutor;
abstract class AbstractAdapter implements ConfiguredObject
{
+ private static final Object ID = "id";
private final Map<String,Object> _attributes = new HashMap<String, Object>();
private final Map<Class<? extends ConfiguredObject>, ConfiguredObject> _parents =
new HashMap<Class<? extends ConfiguredObject>, ConfiguredObject>();
@@ -90,9 +92,9 @@ abstract class AbstractAdapter implements ConfiguredObject
public final State setDesiredState(final State currentState, final State desiredState)
throws IllegalStateTransitionException, AccessControlException
{
- authoriseSetDesiredState(currentState, desiredState);
if (_taskExecutor.isTaskExecutorThread())
{
+ authoriseSetDesiredState(currentState, desiredState);
if (setState(currentState, desiredState))
{
notifyStateChanged(currentState, desiredState);
@@ -225,9 +227,9 @@ abstract class AbstractAdapter implements ConfiguredObject
public Object setAttribute(final String name, final Object expected, final Object desired)
throws IllegalStateException, AccessControlException, IllegalArgumentException
{
- authoriseSetAttribute(name, expected, desired);
if (_taskExecutor.isTaskExecutorThread())
{
+ authoriseSetAttribute(name, expected, desired);
if (changeAttribute(name, expected, desired))
{
attributeSet(name, expected, desired);
@@ -304,9 +306,9 @@ abstract class AbstractAdapter implements ConfiguredObject
@Override
public <C extends ConfiguredObject> C createChild(Class<C> childClass, Map<String, Object> attributes, ConfiguredObject... otherParents)
{
- authoriseCreateChild(childClass, attributes, otherParents);
if (_taskExecutor.isTaskExecutorThread())
{
+ authoriseCreateChild(childClass, attributes, otherParents);
C child = addChild(childClass, attributes, otherParents);
if (child != null)
{
@@ -334,9 +336,9 @@ abstract class AbstractAdapter implements ConfiguredObject
@Override
public void setAttributes(final Map<String, Object> attributes) throws IllegalStateException, AccessControlException, IllegalArgumentException
{
- authoriseSetAttributes(attributes);
if (getTaskExecutor().isTaskExecutorThread())
{
+ authoriseSetAttributes(attributes);
changeAttributes(attributes);
}
else
@@ -347,6 +349,15 @@ abstract class AbstractAdapter implements ConfiguredObject
protected void changeAttributes(final Map<String, Object> attributes)
{
+ if (attributes.containsKey(ID))
+ {
+ UUID id = getId();
+ Object idAttributeValue = attributes.get(ID);
+ if (idAttributeValue != null && !idAttributeValue.equals(id))
+ {
+ throw new IllegalConfigurationException("Cannot change existing configured object id");
+ }
+ }
Collection<String> names = getAttributeNames();
for (String name : names)
{
@@ -381,4 +392,9 @@ abstract class AbstractAdapter implements ConfiguredObject
{
// allowed by default
}
+
+ protected Map<String, Object> getDefaultAttributes()
+ {
+ return _defaultAttributes;
+ }
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AuthenticationProviderAdapter.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AuthenticationProviderAdapter.java
index 594ef7520a..f788923b3a 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AuthenticationProviderAdapter.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AuthenticationProviderAdapter.java
@@ -57,7 +57,6 @@ import org.apache.qpid.server.security.auth.UsernamePrincipal;
import org.apache.qpid.server.security.auth.database.PrincipalDatabase;
import org.apache.qpid.server.security.auth.manager.AuthenticationManager;
import org.apache.qpid.server.security.auth.manager.PrincipalDatabaseAuthenticationManager;
-import org.apache.qpid.server.security.group.GroupPrincipalAccessor;
import org.apache.qpid.server.security.SecurityManager;
public abstract class AuthenticationProviderAdapter<T extends AuthenticationManager> extends AbstractAdapter implements AuthenticationProvider
@@ -252,7 +251,7 @@ public abstract class AuthenticationProviderAdapter<T extends AuthenticationMana
@Override
public SubjectCreator getSubjectCreator()
{
- return new SubjectCreator(_authManager, new GroupPrincipalAccessor(_broker.getGroupProviders()));
+ return new SubjectCreator(_authManager, _broker.getGroupProviders());
}
@Override
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java
index 9759718ddd..e968d91e79 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java
@@ -135,7 +135,7 @@ public class BrokerAdapter extends AbstractAdapter implements Broker, Configurat
public static final long DEFAULT_STORE_TRANSACTION_OPEN_TIMEOUT_WARN = 0l;
private static final String DEFAULT_KEY_STORE_NAME = "defaultKeyStore";
private static final String DEFAULT_TRUST_STORE_NAME = "defaultTrustStore";
- private static final String DEFAULT_GROUP_PROFIDER_NAME = "defaultGroupProvider";
+ private static final String DEFAULT_GROUP_PROVIDER_NAME = "defaultGroupProvider";
private static final String DEFAULT_PEER_STORE_NAME = "defaultPeerStore";
private static final String DUMMY_PASSWORD_MASK = "********";
@@ -238,13 +238,13 @@ public class BrokerAdapter extends AbstractAdapter implements Broker, Configurat
{
GroupManager groupManager = new FileGroupManager(groupFile);
UUID groupProviderId = UUIDGenerator.generateBrokerChildUUID(GroupProvider.class.getSimpleName(),
- DEFAULT_GROUP_PROFIDER_NAME);
+ DEFAULT_GROUP_PROVIDER_NAME);
GroupProviderAdapter groupProviderAdapter = new GroupProviderAdapter(groupProviderId, groupManager, this);
- _groupProviders.put(DEFAULT_GROUP_PROFIDER_NAME, groupProviderAdapter);
+ _groupProviders.put(DEFAULT_GROUP_PROVIDER_NAME, groupProviderAdapter);
}
else
{
- _groupProviders.remove(DEFAULT_GROUP_PROFIDER_NAME);
+ _groupProviders.remove(DEFAULT_GROUP_PROVIDER_NAME);
}
}
@@ -734,9 +734,9 @@ public class BrokerAdapter extends AbstractAdapter implements Broker, Configurat
}
return null;
}
- else if (MANAGEMENT_VERSION.equals(name))
+ else if (MODEL_VERSION.equals(name))
{
- return Model.MANAGEMENT_API_MAJOR_VERSION + "." + Model.MANAGEMENT_API_MINOR_VERSION;
+ return Model.MODEL_MAJOR_VERSION + "." + Model.MODEL_MINOR_VERSION;
}
else if (STORE_VERSION.equals(name))
{
@@ -1097,12 +1097,6 @@ public class BrokerAdapter extends AbstractAdapter implements Broker, Configurat
}
}
}
-
- // the calls below are not thread safe but they should be fine in a management mode
- // as there will be no user connected
- // The new keystore/trustore/peerstore will be only used with new ports
- // At the moment we cannot restart ports with new keystore/trustore/peerstore
-
if (keyStoreChanged)
{
createKeyStore();
@@ -1155,16 +1149,20 @@ public class BrokerAdapter extends AbstractAdapter implements Broker, Configurat
}
}
Long queueFlowControlSize = (Long) convertedAttributes.get(QUEUE_FLOW_CONTROL_SIZE_BYTES);
- if (queueFlowControlSize != null && queueFlowControlSize > 0)
+ Long queueFlowControlResumeSize = (Long) convertedAttributes.get(QUEUE_FLOW_CONTROL_RESUME_SIZE_BYTES);
+ if (queueFlowControlSize != null || queueFlowControlResumeSize != null )
{
- Long queueFlowControlResumeSize = (Long) convertedAttributes.get(QUEUE_FLOW_CONTROL_RESUME_SIZE_BYTES);
+ if (queueFlowControlSize == null)
+ {
+ queueFlowControlSize = (Long)getAttribute(QUEUE_FLOW_CONTROL_SIZE_BYTES);
+ }
if (queueFlowControlResumeSize == null)
{
- throw new IllegalConfigurationException("Flow control resume size attribute is not specified with flow control size attribute");
+ queueFlowControlResumeSize = (Long)getAttribute(QUEUE_FLOW_CONTROL_RESUME_SIZE_BYTES);
}
- if (queueFlowControlResumeSize >= queueFlowControlSize)
+ if (queueFlowControlResumeSize > queueFlowControlSize)
{
- throw new IllegalConfigurationException("Flow control resume size should be less then flow control size");
+ throw new IllegalConfigurationException("Flow resume size can't be greater than flow control size");
}
}
for (String attributeName : POSITIVE_NUMERIC_ATTRIBUTES)
@@ -1182,9 +1180,14 @@ public class BrokerAdapter extends AbstractAdapter implements Broker, Configurat
String passwordAttribute, String aliasAttribute)
{
String keyStoreFile = (String) convertedAttributes.get(pathAttribute);
- if (keyStoreFile != null)
+ String password = (String) convertedAttributes.get(passwordAttribute);
+ String alias = aliasAttribute!= null? (String) convertedAttributes.get(aliasAttribute) : null;
+ if (keyStoreFile != null || password != null || alias != null)
{
- String password = (String) convertedAttributes.get(passwordAttribute);
+ if (keyStoreFile == null)
+ {
+ keyStoreFile = (String) getActualAttributes().get(pathAttribute);
+ }
if (password == null)
{
password = (String) getActualAttributes().get(passwordAttribute);
@@ -1200,7 +1203,10 @@ public class BrokerAdapter extends AbstractAdapter implements Broker, Configurat
}
if (aliasAttribute != null)
{
- String alias = (String) convertedAttributes.get(aliasAttribute);
+ if (alias == null)
+ {
+ alias = (String) getActualAttributes().get(aliasAttribute);
+ }
if (alias != null)
{
Certificate cert = null;
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/GroupProviderAdapter.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/GroupProviderAdapter.java
index 0fa834bc28..9ad58f9670 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/GroupProviderAdapter.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/GroupProviderAdapter.java
@@ -538,8 +538,6 @@ public class GroupProviderAdapter extends AbstractAdapter implements
return true;
}
// TODO: DELETE state is ignored for now
- // in case if we need to delete group provider, then we need AuthenticationProvider to be a change listener of it
- // in order to remove deleted group provider from its group provider list
return false;
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/PortAdapter.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/PortAdapter.java
index ba10816a35..4250de17a7 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/PortAdapter.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/PortAdapter.java
@@ -48,6 +48,7 @@ import org.apache.qpid.server.model.VirtualHostAlias;
import org.apache.qpid.server.security.access.Operation;
import org.apache.qpid.server.util.MapValueConverter;
import org.apache.qpid.server.util.ParameterizedTypeImpl;
+import org.apache.qpid.server.configuration.IllegalConfigurationException;
import org.apache.qpid.server.configuration.updater.TaskExecutor;
public class PortAdapter extends AbstractAdapter implements Port
@@ -72,11 +73,6 @@ public class PortAdapter extends AbstractAdapter implements Port
private AuthenticationProvider _authenticationProvider;
private AtomicReference<State> _state;
- /*
- * TODO register PortAceptor as a listener. For supporting multiple
- * protocols on the same port we need to introduce a special entity like
- * PortAceptor which will be responsible for port binding/unbinding
- */
public PortAdapter(UUID id, Broker broker, Map<String, Object> attributes, Map<String, Object> defaults, TaskExecutor taskExecutor)
{
super(id, defaults, MapValueConverter.convert(attributes, ATTRIBUTE_TYPES), taskExecutor);
@@ -362,7 +358,67 @@ public class PortAdapter extends AbstractAdapter implements Port
{
throw new IllegalStateException("Cannot change attributes for an active port outside of Management Mode");
}
- super.changeAttributes(MapValueConverter.convert(attributes, ATTRIBUTE_TYPES));
+ Map<String, Object> converted = MapValueConverter.convert(attributes, ATTRIBUTE_TYPES);
+
+ Map<String, Object> merged = new HashMap<String, Object>(getDefaultAttributes());
+ merged.putAll(getActualAttributes());
+ merged.putAll(converted);
+
+ @SuppressWarnings("unchecked")
+ Collection<Transport> transports = (Collection<Transport>)merged.get(TRANSPORTS);
+ @SuppressWarnings("unchecked")
+ Collection<Protocol> protocols = (Collection<Protocol>)merged.get(PROTOCOLS);
+ Boolean needClientCertificate = (Boolean)merged.get(NEED_CLIENT_AUTH);
+ Boolean wantClientCertificate = (Boolean)merged.get(WANT_CLIENT_AUTH);
+ boolean requiresCertificate = (needClientCertificate != null && needClientCertificate.booleanValue())
+ || (wantClientCertificate != null && wantClientCertificate.booleanValue());
+
+ if (transports != null && transports.contains(Transport.SSL))
+ {
+ if (_broker.getKeyStores().isEmpty())
+ {
+ throw new IllegalConfigurationException("Can't create port which requires SSL as the broker has no keystore configured.");
+ }
+
+ if (_broker.getTrustStores().isEmpty() && requiresCertificate)
+ {
+ throw new IllegalConfigurationException("Can't create port which requests SSL client certificates as the broker has no trust/peer stores configured.");
+ }
+ }
+ else
+ {
+ if (requiresCertificate)
+ {
+ throw new IllegalConfigurationException("Can't create port which requests SSL client certificates but doesn't use SSL transport.");
+ }
+ }
+
+ if (protocols != null && protocols.contains(Protocol.HTTPS) && _broker.getKeyStores().isEmpty())
+ {
+ throw new IllegalConfigurationException("Can't create port which requires SSL as the broker has no keystore configured.");
+ }
+
+ String authenticationProviderName = (String)merged.get(AUTHENTICATION_PROVIDER);
+ if (authenticationProviderName != null)
+ {
+ Collection<AuthenticationProvider> providers = _broker.getAuthenticationProviders();
+ AuthenticationProvider provider = null;
+ for (AuthenticationProvider p : providers)
+ {
+ if (p.getName().equals(authenticationProviderName))
+ {
+ provider = p;
+ break;
+ }
+ }
+
+ if (provider == null)
+ {
+ throw new IllegalConfigurationException("Cannot find authentication provider with name '"
+ + authenticationProviderName + "'");
+ }
+ }
+ super.changeAttributes(converted);
}
@Override
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/PortFactory.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/PortFactory.java
index 50bb2e2fcb..ffbd24997a 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/PortFactory.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/PortFactory.java
@@ -108,13 +108,12 @@ public class PortFactory
boolean useClientAuth = (Boolean) port.getAttribute(Port.NEED_CLIENT_AUTH) || (Boolean) port.getAttribute(Port.WANT_CLIENT_AUTH);
if(useClientAuth && broker.getTrustStores().isEmpty())
{
- throw new IllegalConfigurationException("Cant create port which requests SSL client certificates as the broker has no trust/peer stores configured.");
+ throw new IllegalConfigurationException("Can't create port which requests SSL client certificates as the broker has no trust/peer stores configured.");
}
- boolean doesntUseSSL = port.getTransports().isEmpty() || !port.getTransports().contains(Transport.SSL);
- if(useClientAuth && doesntUseSSL)
+ if(useClientAuth && !port.getTransports().contains(Transport.SSL))
{
- throw new IllegalConfigurationException("Cant create port which requests SSL client certificates but doesnt use SSL transport.");
+ throw new IllegalConfigurationException("Can't create port which requests SSL client certificates but doesn't use SSL transport.");
}
}
else
@@ -136,7 +135,7 @@ public class PortFactory
Collection<Protocol> portProtocols = existingPort.getProtocols();
if (portProtocols != null && portProtocols.contains(protocol))
{
- throw new IllegalConfigurationException("Port for protocol " + protocol + " already exist. Only one management port per protocol can be created");
+ throw new IllegalConfigurationException("Port for protocol " + protocol + " already exists. Only one management port per protocol can be created.");
}
}
}
@@ -149,7 +148,7 @@ public class PortFactory
{
if(broker.getKeyStores().isEmpty())
{
- throw new IllegalConfigurationException("Cant create port which requires SSL as the broker has no keystore configured.");
+ throw new IllegalConfigurationException("Can't create port which requires SSL as the broker has no keystore configured.");
}
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/VirtualHostAdapter.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/VirtualHostAdapter.java
index 09fc3a446f..2a66763272 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/VirtualHostAdapter.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/VirtualHostAdapter.java
@@ -835,7 +835,7 @@ public final class VirtualHostAdapter extends AbstractAdapter implements Virtual
{
return _virtualHost.getConfiguration().getHousekeepingCheckPeriod();
}
- else if(MAXIMUM_DELIVERY_ATTEMPTS.equals(name))
+ else if(QUEUE_MAXIMUM_DELIVERY_ATTEMPTS.equals(name))
{
return _virtualHost.getConfiguration().getMaxDeliveryCount();
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/SubjectCreator.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/SubjectCreator.java
index 8138745486..213f19dc5c 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/SubjectCreator.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/SubjectCreator.java
@@ -21,17 +21,21 @@
package org.apache.qpid.server.security;
import java.security.Principal;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
import javax.security.auth.Subject;
import javax.security.sasl.SaslException;
import javax.security.sasl.SaslServer;
+import org.apache.qpid.server.model.GroupProvider;
import org.apache.qpid.server.security.auth.AuthenticatedPrincipal;
import org.apache.qpid.server.security.auth.AuthenticationResult;
import org.apache.qpid.server.security.auth.AuthenticationResult.AuthenticationStatus;
import org.apache.qpid.server.security.auth.SubjectAuthenticationResult;
import org.apache.qpid.server.security.auth.manager.AuthenticationManager;
-import org.apache.qpid.server.security.group.GroupPrincipalAccessor;
/**
* Creates a {@link Subject} formed by the {@link Principal}'s returned from:
@@ -48,12 +52,12 @@ import org.apache.qpid.server.security.group.GroupPrincipalAccessor;
public class SubjectCreator
{
private AuthenticationManager _authenticationManager;
- private GroupPrincipalAccessor _groupAccessor;
+ private Collection<GroupProvider> _groupProviders;
- public SubjectCreator(AuthenticationManager authenticationManager, GroupPrincipalAccessor groupAccessor)
+ public SubjectCreator(AuthenticationManager authenticationManager, Collection<GroupProvider> groupProviders)
{
_authenticationManager = authenticationManager;
- _groupAccessor = groupAccessor;
+ _groupProviders = groupProviders;
}
/**
@@ -112,7 +116,7 @@ public class SubjectCreator
final Subject authenticationSubject = new Subject();
authenticationSubject.getPrincipals().addAll(authenticationResult.getPrincipals());
- authenticationSubject.getPrincipals().addAll(_groupAccessor.getGroupPrincipals(username));
+ authenticationSubject.getPrincipals().addAll(getGroupPrincipals(username));
authenticationSubject.setReadOnly();
@@ -129,9 +133,24 @@ public class SubjectCreator
Subject authenticationSubject = new Subject();
authenticationSubject.getPrincipals().add(new AuthenticatedPrincipal(username));
- authenticationSubject.getPrincipals().addAll(_groupAccessor.getGroupPrincipals(username));
+ authenticationSubject.getPrincipals().addAll(getGroupPrincipals(username));
authenticationSubject.setReadOnly();
return authenticationSubject;
}
+
+ public Set<Principal> getGroupPrincipals(String username)
+ {
+ Set<Principal> principals = new HashSet<Principal>();
+ for (GroupProvider groupProvider : _groupProviders)
+ {
+ Set<Principal> groups = groupProvider.getGroupPrincipalsForUser(username);
+ if (groups != null)
+ {
+ principals.addAll(groups);
+ }
+ }
+
+ return Collections.unmodifiableSet(principals);
+ }
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationManager.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationManager.java
index 43e0a9f64f..c503549bf2 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationManager.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationManager.java
@@ -31,8 +31,11 @@ public class ExternalAuthenticationManager implements AuthenticationManager
{
private static final String EXTERNAL = "EXTERNAL";
- ExternalAuthenticationManager()
+ private boolean _useFullDN = false;
+
+ ExternalAuthenticationManager(boolean useFullDN)
{
+ _useFullDN = useFullDN;
}
@Override
@@ -52,7 +55,7 @@ public class ExternalAuthenticationManager implements AuthenticationManager
{
if(EXTERNAL.equals(mechanism))
{
- return new ExternalSaslServer(externalPrincipal);
+ return new ExternalSaslServer(externalPrincipal, _useFullDN);
}
else
{
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationManagerFactory.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationManagerFactory.java
index 64acfafc4a..6029674cd3 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationManagerFactory.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationManagerFactory.java
@@ -19,22 +19,32 @@
*/
package org.apache.qpid.server.security.auth.manager;
+import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import org.apache.qpid.server.plugin.AuthenticationManagerFactory;
+import org.apache.qpid.server.util.ResourceBundleLoader;
public class ExternalAuthenticationManagerFactory implements AuthenticationManagerFactory
{
+ public static final String RESOURCE_BUNDLE = "org.apache.qpid.server.security.auth.manager.ExternalAuthenticationProviderAttributeDescriptions";
public static final String PROVIDER_TYPE = "External";
+ public static final String ATTRIBUTE_USE_FULL_DN = "useFullDN";
+
+ public static final Collection<String> ATTRIBUTES = Collections.<String> unmodifiableList(Arrays.asList(
+ ATTRIBUTE_TYPE,
+ ATTRIBUTE_USE_FULL_DN));
@Override
public AuthenticationManager createInstance(Map<String, Object> attributes)
{
if (attributes != null && PROVIDER_TYPE.equals(attributes.get(ATTRIBUTE_TYPE)))
{
- return new ExternalAuthenticationManager();
+ boolean useFullDN = Boolean.valueOf(String.valueOf(attributes.get(ATTRIBUTE_USE_FULL_DN)));
+
+ return new ExternalAuthenticationManager(useFullDN);
}
return null;
}
@@ -42,7 +52,7 @@ public class ExternalAuthenticationManagerFactory implements AuthenticationManag
@Override
public Collection<String> getAttributeNames()
{
- return Collections.<String>singletonList(ATTRIBUTE_TYPE);
+ return ATTRIBUTES;
}
@Override
@@ -54,7 +64,7 @@ public class ExternalAuthenticationManagerFactory implements AuthenticationManag
@Override
public Map<String, String> getAttributeDescriptions()
{
- return null;
+ return ResourceBundleLoader.getResources(RESOURCE_BUNDLE);
}
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationProviderAttributeDescriptions.properties b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationProviderAttributeDescriptions.properties
new file mode 100644
index 0000000000..263254e9fe
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationProviderAttributeDescriptions.properties
@@ -0,0 +1,19 @@
+#
+# 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.
+
+useFullDN=Use the full DN as the Username \ No newline at end of file
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationManager.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationManager.java
index ee00e9850d..61cdf190b8 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationManager.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationManager.java
@@ -21,7 +21,6 @@ package org.apache.qpid.server.security.auth.manager;
import java.io.IOException;
import java.security.Principal;
-import java.util.HashMap;
import java.util.Hashtable;
import javax.naming.AuthenticationException;
@@ -37,7 +36,6 @@ import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.UnsupportedCallbackException;
import javax.security.sasl.AuthorizeCallback;
-import javax.security.sasl.Sasl;
import javax.security.sasl.SaslException;
import javax.security.sasl.SaslServer;
import org.apache.log4j.Logger;
@@ -45,6 +43,7 @@ import org.apache.qpid.server.security.auth.AuthenticationResult;
import org.apache.qpid.server.security.auth.AuthenticationResult.AuthenticationStatus;
import org.apache.qpid.server.security.auth.UsernamePrincipal;
import org.apache.qpid.server.security.auth.sasl.plain.PlainPasswordCallback;
+import org.apache.qpid.server.security.auth.sasl.plain.PlainSaslServer;
public class SimpleLDAPAuthenticationManager implements AuthenticationManager
{
@@ -83,9 +82,7 @@ public class SimpleLDAPAuthenticationManager implements AuthenticationManager
{
if(PLAIN_MECHANISM.equals(mechanism))
{
- return Sasl.createSaslServer(PLAIN_MECHANISM, "AMQP", localFQDN,
- new HashMap<String, Object>(), new PlainCallbackHandler());
-
+ return new PlainSaslServer(new SimpleLDAPPlainCallbackHandler());
}
else
{
@@ -214,7 +211,7 @@ public class SimpleLDAPAuthenticationManager implements AuthenticationManager
}
}
- private class PlainCallbackHandler implements CallbackHandler
+ private class SimpleLDAPPlainCallbackHandler implements CallbackHandler
{
@Override
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/external/ExternalSaslServer.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/external/ExternalSaslServer.java
index 9c2bca2d0b..509442b14b 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/external/ExternalSaslServer.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/external/ExternalSaslServer.java
@@ -19,19 +19,27 @@
package org.apache.qpid.server.security.auth.sasl.external;
import java.security.Principal;
+
+import javax.security.auth.x500.X500Principal;
import javax.security.sasl.SaslException;
import javax.security.sasl.SaslServer;
+import org.apache.log4j.Logger;
+import org.apache.qpid.server.security.auth.UsernamePrincipal;
public class ExternalSaslServer implements SaslServer
{
+ private static final Logger LOGGER = Logger.getLogger(ExternalSaslServer.class);
+
public static final String MECHANISM = "EXTERNAL";
private boolean _complete = false;
private final Principal _externalPrincipal;
+ private boolean _useFullDN = false;
- public ExternalSaslServer(Principal externalPrincipal)
+ public ExternalSaslServer(Principal externalPrincipal, boolean useFullDN)
{
+ _useFullDN = useFullDN;
_externalPrincipal = externalPrincipal;
}
@@ -77,6 +85,83 @@ public class ExternalSaslServer implements SaslServer
public Principal getAuthenticatedPrincipal()
{
- return _externalPrincipal;
+ if (_externalPrincipal instanceof X500Principal && !_useFullDN)
+ {
+ // Construct username as <CN>@<DC1>.<DC2>.<DC3>....<DCN>
+
+ String username;
+ String dn = ((X500Principal) _externalPrincipal).getName(X500Principal.RFC2253);
+
+ if(LOGGER.isDebugEnabled())
+ {
+ LOGGER.debug("Parsing username from Principal DN: " + dn);
+ }
+
+ if (dn.contains("CN="))
+ {
+ username = dn.substring(dn.indexOf("CN=") + 3, (dn.indexOf(",", dn.indexOf("CN=")) != -1) ? dn.indexOf(",", dn.indexOf("CN=")) : dn.length());
+
+ if (username.isEmpty())
+ {
+ // CN is empty => Cannot construct username => Authentication failed => return null
+ if(LOGGER.isDebugEnabled())
+ {
+ LOGGER.debug("CN value was empty in Principal name, unable to construct username");
+ }
+ return null;
+ }
+ else
+ {
+ if (dn.contains("DC="))
+ {
+ int start = 0;
+ String dc = "";
+
+ while (dn.indexOf("DC=", start) != -1)
+ {
+ int dcStart = dn.indexOf("DC=", start) + 3;
+ int dcEnd = (dn.indexOf(",", dn.indexOf("DC=", start)) != -1) ? dn.indexOf(",", dn.indexOf("DC=", start)) : dn.length();
+
+ if (dc.isEmpty())
+ {
+ dc = dn.substring(dcStart, dcEnd);
+ }
+ else
+ {
+ dc = dc.concat(".").concat(dn.substring(dcStart, dcEnd));
+ }
+
+ start = dn.indexOf("DC=", start) + 1;
+ }
+
+ username = username.concat("@").concat(dc);
+ }
+ }
+
+ if(LOGGER.isDebugEnabled())
+ {
+ LOGGER.debug("Constructing Principal with username: " + username);
+ }
+ return new UsernamePrincipal(username);
+ }
+ else
+ {
+ // No CN => Cannot construct username => Authentication failed => return null
+ if(LOGGER.isDebugEnabled())
+ {
+ LOGGER.debug("No CN= present in DN, unable to construct username");
+ }
+ return null;
+ }
+ }
+ else
+ {
+ if(LOGGER.isDebugEnabled())
+ {
+ LOGGER.debug("Using external Principal: " + _externalPrincipal);
+ }
+
+ return _externalPrincipal;
+ }
}
} \ No newline at end of file
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/group/GroupPrincipalAccessor.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/group/GroupPrincipalAccessor.java
deleted file mode 100644
index 1b8cdc91bc..0000000000
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/group/GroupPrincipalAccessor.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.qpid.server.security.group;
-
-import java.security.Principal;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Set;
-
-import org.apache.qpid.server.model.GroupProvider;
-
-public class GroupPrincipalAccessor
-{
- private final Collection<GroupProvider> _groupProviders;
-
- public GroupPrincipalAccessor(Collection<GroupProvider> groupProviders)
- {
- _groupProviders = groupProviders;
- }
-
- public Set<Principal> getGroupPrincipals(String username)
- {
- Set<Principal> principals = new HashSet<Principal>();
- for (GroupProvider groupProvider : _groupProviders)
- {
- Set<Principal> groups = groupProvider.getGroupPrincipalsForUser(username);
- if (groups != null)
- {
- principals.addAll(groups);
- }
- }
-
- return Collections.unmodifiableSet(principals);
- }
-}
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/model/adapter/PortFactoryTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/model/adapter/PortFactoryTest.java
index 5d9cfea709..a9303c264e 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/model/adapter/PortFactoryTest.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/model/adapter/PortFactoryTest.java
@@ -151,7 +151,7 @@ public class PortFactoryTest extends QpidTestCase
}
}
- public void testCreateAmqpPortUsingSsslSucceedsWithKeyStore()
+ public void testCreateAmqpPortUsingSslSucceedsWithKeyStore()
{
when(_broker.getKeyStores()).thenReturn(Collections.singleton(_keyStore));
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/security/SubjectCreatorTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/security/SubjectCreatorTest.java
index b1bc9bea68..9edd345360 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/security/SubjectCreatorTest.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/security/SubjectCreatorTest.java
@@ -23,19 +23,21 @@ import static org.mockito.Mockito.when;
import java.security.Principal;
import java.util.Arrays;
+import java.util.Collections;
import java.util.HashSet;
+import java.util.Set;
import javax.security.auth.Subject;
import javax.security.sasl.SaslServer;
import junit.framework.TestCase;
+import org.apache.qpid.server.model.GroupProvider;
import org.apache.qpid.server.security.auth.AuthenticatedPrincipal;
import org.apache.qpid.server.security.auth.AuthenticationResult;
import org.apache.qpid.server.security.auth.AuthenticationResult.AuthenticationStatus;
import org.apache.qpid.server.security.auth.SubjectAuthenticationResult;
import org.apache.qpid.server.security.auth.manager.AuthenticationManager;
-import org.apache.qpid.server.security.group.GroupPrincipalAccessor;
public class SubjectCreatorTest extends TestCase
{
@@ -43,13 +45,15 @@ public class SubjectCreatorTest extends TestCase
private static final String PASSWORD = "password";
private AuthenticationManager _authenticationManager = mock(AuthenticationManager.class);
- private GroupPrincipalAccessor _groupPrincipalAccessor = mock(GroupPrincipalAccessor.class);
- private SubjectCreator _subjectCreator = new SubjectCreator(_authenticationManager, _groupPrincipalAccessor);
+
+ private GroupProvider _groupManager1 = mock(GroupProvider.class);
+ private GroupProvider _groupManager2 = mock(GroupProvider.class);
private Principal _userPrincipal = mock(Principal.class);
private Principal _group1 = mock(Principal.class);
private Principal _group2 = mock(Principal.class);
+ private SubjectCreator _subjectCreator;
private AuthenticationResult _authenticationResult;
private SaslServer _testSaslServer = mock(SaslServer.class);
private byte[] _saslResponseBytes = PASSWORD.getBytes();
@@ -57,11 +61,12 @@ public class SubjectCreatorTest extends TestCase
@Override
public void setUp()
{
+ when(_groupManager1.getGroupPrincipalsForUser(USERNAME)).thenReturn(Collections.singleton(_group1));
+ when(_groupManager2.getGroupPrincipalsForUser(USERNAME)).thenReturn(Collections.singleton(_group2));
+
+ _subjectCreator = new SubjectCreator(_authenticationManager, new HashSet<GroupProvider>(Arrays.asList(_groupManager1, _groupManager2)));
_authenticationResult = new AuthenticationResult(_userPrincipal);
when(_authenticationManager.authenticate(USERNAME, PASSWORD)).thenReturn(_authenticationResult);
-
- when(_groupPrincipalAccessor.getGroupPrincipals(USERNAME))
- .thenReturn(new HashSet<Principal>(Arrays.asList(_group1, _group2)));
}
public void testAuthenticateUsernameAndPasswordReturnsSubjectWithUserAndGroupPrincipals()
@@ -135,4 +140,30 @@ public class SubjectCreatorTest extends TestCase
assertSame(expectedStatus, subjectAuthenticationResult.getStatus());
assertNull(subjectAuthenticationResult.getSubject());
}
+
+ public void testGetGroupPrincipals()
+ {
+ getAndAssertGroupPrincipals(_group1, _group2);
+ }
+
+ public void testGetGroupPrincipalsWhenAGroupManagerReturnsNull()
+ {
+ when(_groupManager1.getGroupPrincipalsForUser(USERNAME)).thenReturn(null);
+
+ getAndAssertGroupPrincipals(_group2);
+ }
+
+ public void testGetGroupPrincipalsWhenAGroupManagerReturnsEmptySet()
+ {
+ when(_groupManager2.getGroupPrincipalsForUser(USERNAME)).thenReturn(new HashSet<Principal>());
+
+ getAndAssertGroupPrincipals(_group1);
+ }
+
+ private void getAndAssertGroupPrincipals(Principal... expectedGroups)
+ {
+ Set<Principal> actualGroupPrincipals = _subjectCreator.getGroupPrincipals(USERNAME);
+ Set<Principal> expectedGroupPrincipals = new HashSet<Principal>(Arrays.asList(expectedGroups));
+ assertEquals(expectedGroupPrincipals, actualGroupPrincipals);
+ }
}
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationManagerTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationManagerTest.java
index a66d73c47d..a5d087593a 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationManagerTest.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationManagerTest.java
@@ -25,11 +25,13 @@ import javax.security.sasl.SaslException;
import javax.security.sasl.SaslServer;
import org.apache.qpid.server.security.auth.AuthenticationResult;
+import org.apache.qpid.server.security.auth.UsernamePrincipal;
import org.apache.qpid.test.utils.QpidTestCase;
public class ExternalAuthenticationManagerTest extends QpidTestCase
{
- private AuthenticationManager _manager = new ExternalAuthenticationManager();
+ private AuthenticationManager _manager = new ExternalAuthenticationManager(false);
+ private AuthenticationManager _managerUsingFullDN = new ExternalAuthenticationManager(true);
public void testGetMechanisms() throws Exception
{
@@ -38,13 +40,23 @@ public class ExternalAuthenticationManagerTest extends QpidTestCase
public void testCreateSaslServer() throws Exception
{
- SaslServer server = _manager.createSaslServer("EXTERNAL", "example.example.com", null);
+ createSaslServerTestImpl(_manager);
+ }
+
+ public void testCreateSaslServerUsingFullDN() throws Exception
+ {
+ createSaslServerTestImpl(_managerUsingFullDN);
+ }
+
+ public void createSaslServerTestImpl(AuthenticationManager manager) throws Exception
+ {
+ SaslServer server = manager.createSaslServer("EXTERNAL", "example.example.com", null);
assertEquals("Sasl Server mechanism name is not as expected", "EXTERNAL", server.getMechanismName());
try
{
- server = _manager.createSaslServer("PLAIN", "example.example.com", null);
+ server = manager.createSaslServer("PLAIN", "example.example.com", null);
fail("Expected creating SaslServer with incorrect mechanism to throw an exception");
}
catch (SaslException e)
@@ -53,12 +65,16 @@ public class ExternalAuthenticationManagerTest extends QpidTestCase
}
}
- public void testAuthenticate() throws Exception
+ /**
+ * Test behaviour of the authentication when the useFullDN attribute is set true
+ * and the username is taken directly as the externally supplied Principal
+ */
+ public void testAuthenticateWithFullDN() throws Exception
{
X500Principal principal = new X500Principal("CN=person, DC=example, DC=com");
- SaslServer saslServer = _manager.createSaslServer("EXTERNAL", "example.example.com", principal);
+ SaslServer saslServer = _managerUsingFullDN.createSaslServer("EXTERNAL", "example.example.com", principal);
- AuthenticationResult result = _manager.authenticate(saslServer, new byte[0]);
+ AuthenticationResult result = _managerUsingFullDN.authenticate(saslServer, new byte[0]);
assertNotNull(result);
assertEquals("Expected authentication to be successful",
AuthenticationResult.AuthenticationStatus.SUCCESS,
@@ -66,15 +82,102 @@ public class ExternalAuthenticationManagerTest extends QpidTestCase
assertOnlyContainsWrapped(principal, result.getPrincipals());
+ saslServer = _managerUsingFullDN.createSaslServer("EXTERNAL", "example.example.com", null);
+ result = _managerUsingFullDN.authenticate(saslServer, new byte[0]);
+
+ assertNotNull(result);
+ assertEquals("Expected authentication to be unsuccessful",
+ AuthenticationResult.AuthenticationStatus.ERROR,
+ result.getStatus());
+ }
+
+ /**
+ * Test behaviour of the authentication when parsing the username from
+ * the Principals DN as <CN>@<DC1>.<DC2>.<DC3>....<DCN>
+ */
+ public void testAuthenticateWithUsernameBasedOnCNAndDC() throws Exception
+ {
+ X500Principal principal;
+ SaslServer saslServer;
+ AuthenticationResult result;
+ UsernamePrincipal expectedPrincipal;
+
+ // DN contains only CN
+ principal = new X500Principal("CN=person");
+ expectedPrincipal = new UsernamePrincipal("person");
+ saslServer = _manager.createSaslServer("EXTERNAL", "example.example.com", principal);
+
+ result = _manager.authenticate(saslServer, new byte[0]);
+ assertNotNull(result);
+ assertEquals("Expected authentication to be successful",
+ AuthenticationResult.AuthenticationStatus.SUCCESS,
+ result.getStatus());
+ assertOnlyContainsWrapped(expectedPrincipal, result.getPrincipals());
+
+ // Null princial
saslServer = _manager.createSaslServer("EXTERNAL", "example.example.com", null);
result = _manager.authenticate(saslServer, new byte[0]);
assertNotNull(result);
- assertEquals("Expected authentication to be unsuccessful",
- AuthenticationResult.AuthenticationStatus.ERROR,
- result.getStatus());
+ assertEquals("Expected authentication to be unsuccessful",
+ AuthenticationResult.AuthenticationStatus.ERROR,
+ result.getStatus());
- }
+ // DN doesn't contain CN
+ principal = new X500Principal("DC=example, DC=com, O=My Company Ltd, L=Newbury, ST=Berkshire, C=GB");
+ saslServer = _manager.createSaslServer("EXTERNAL", "example.example.com", principal);
+ result = _manager.authenticate(saslServer, new byte[0]);
+ assertNotNull(result);
+ assertEquals("Expected authentication to be unsuccessful",
+ AuthenticationResult.AuthenticationStatus.ERROR,
+ result.getStatus());
+
+ // DN contains empty CN
+ principal = new X500Principal("CN=, DC=example, DC=com, O=My Company Ltd, L=Newbury, ST=Berkshire, C=GB");
+ saslServer = _manager.createSaslServer("EXTERNAL", "example.example.com", principal);
+ result = _manager.authenticate(saslServer, new byte[0]);
+
+ assertNotNull(result);
+ assertEquals("Expected authentication to be unsuccessful",
+ AuthenticationResult.AuthenticationStatus.ERROR,
+ result.getStatus());
+
+ // DN contains CN and DC
+ principal = new X500Principal("CN=person, DC=example, DC=com");
+ expectedPrincipal = new UsernamePrincipal("person@example.com");
+ saslServer = _manager.createSaslServer("EXTERNAL", "example.example.com", principal);
+
+ result = _manager.authenticate(saslServer, new byte[0]);
+ assertNotNull(result);
+ assertEquals("Expected authentication to be successful",
+ AuthenticationResult.AuthenticationStatus.SUCCESS,
+ result.getStatus());
+ assertOnlyContainsWrapped(expectedPrincipal, result.getPrincipals());
+
+ // DN contains CN and DC and other components
+ principal = new X500Principal("CN=person, DC=example, DC=com, O=My Company Ltd, L=Newbury, ST=Berkshire, C=GB");
+ expectedPrincipal = new UsernamePrincipal("person@example.com");
+ saslServer = _manager.createSaslServer("EXTERNAL", "example.example.com", principal);
+
+ result = _manager.authenticate(saslServer, new byte[0]);
+ assertNotNull(result);
+ assertEquals("Expected authentication to be successful",
+ AuthenticationResult.AuthenticationStatus.SUCCESS,
+ result.getStatus());
+ assertOnlyContainsWrapped(expectedPrincipal, result.getPrincipals());
+
+ // DN contains CN and DC and other components
+ principal = new X500Principal("CN=person, O=My Company Ltd, L=Newbury, ST=Berkshire, C=GB");
+ expectedPrincipal = new UsernamePrincipal("person");
+ saslServer = _manager.createSaslServer("EXTERNAL", "example.example.com", principal);
+
+ result = _manager.authenticate(saslServer, new byte[0]);
+ assertNotNull(result);
+ assertEquals("Expected authentication to be successful",
+ AuthenticationResult.AuthenticationStatus.SUCCESS,
+ result.getStatus());
+ assertOnlyContainsWrapped(expectedPrincipal, result.getPrincipals());
+ }
}
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/security/group/GroupPrincipalAccessorTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/security/group/GroupPrincipalAccessorTest.java
deleted file mode 100644
index e58a1a01f8..0000000000
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/security/group/GroupPrincipalAccessorTest.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.qpid.server.security.group;
-
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-import java.security.Principal;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Set;
-
-import junit.framework.TestCase;
-
-import org.apache.qpid.server.model.GroupProvider;
-
-public class GroupPrincipalAccessorTest extends TestCase
-{
- private static final String USERNAME = "username";
-
- private GroupProvider _groupManager1 = mock(GroupProvider.class);
- private GroupProvider _groupManager2 = mock(GroupProvider.class);
-
- private Principal _group1 = mock(Principal.class);
- private Principal _group2 = mock(Principal.class);
-
- @Override
- public void setUp()
- {
- when(_groupManager1.getGroupPrincipalsForUser(USERNAME)).thenReturn(Collections.singleton(_group1));
- when(_groupManager2.getGroupPrincipalsForUser(USERNAME)).thenReturn(Collections.singleton(_group2));
- }
-
- public void testGetGroupPrincipals()
- {
- getAndAssertGroupPrincipals(_group1, _group2);
- }
-
- public void testGetGroupPrincipalsWhenAGroupManagerReturnsNull()
- {
- when(_groupManager1.getGroupPrincipalsForUser(USERNAME)).thenReturn(null);
-
- getAndAssertGroupPrincipals(_group2);
- }
-
- public void testGetGroupPrincipalsWhenAGroupManagerReturnsEmptySet()
- {
- when(_groupManager2.getGroupPrincipalsForUser(USERNAME)).thenReturn(new HashSet<Principal>());
-
- getAndAssertGroupPrincipals(_group1);
- }
-
- private void getAndAssertGroupPrincipals(Principal... expectedGroups)
- {
- GroupPrincipalAccessor groupPrincipalAccessor = new GroupPrincipalAccessor(Arrays.asList(_groupManager1, _groupManager2));
-
- Set<Principal> actualGroupPrincipals = groupPrincipalAccessor.getGroupPrincipals(USERNAME);
-
- Set<Principal> expectedGroupPrincipals = new HashSet<Principal>(Arrays.asList(expectedGroups));
-
- assertEquals(expectedGroupPrincipals, actualGroupPrincipals);
- }
-}
diff --git a/qpid/java/build.deps b/qpid/java/build.deps
index 416ca090ef..b53ac55b6d 100644
--- a/qpid/java/build.deps
+++ b/qpid/java/build.deps
@@ -104,7 +104,7 @@ jca.libs=${geronimo-j2ee} ${geronimo-jta} ${geronimo-jms} ${geronimo-openejb} ${
jca.test.libs=${test.libs}
# optional bdbstore module deps
-bdb-je=lib/bdbstore/je-5.0.58.jar
+bdb-je=lib/bdbstore/je-5.0.73.jar
bdbstore.libs=${bdb-je}
bdbstore.test.libs=${test.libs}
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQTopic.java b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQTopic.java
index 51b6c7e478..96cd209447 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQTopic.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQTopic.java
@@ -20,6 +20,7 @@
*/
package org.apache.qpid.client;
+import org.apache.qpid.client.AMQDestination.DestSyntax;
import org.apache.qpid.exchange.ExchangeDefaults;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.messaging.Address;
@@ -216,13 +217,27 @@ public class AMQTopic extends AMQDestination implements Topic
public boolean equals(Object o)
{
- return (o instanceof AMQTopic)
+ if (getDestSyntax() == DestSyntax.ADDR)
+ {
+ return super.equals(o);
+ }
+ else
+ {
+ return (o instanceof AMQTopic)
&& ((AMQTopic)o).getExchangeName().equals(getExchangeName())
&& ((AMQTopic)o).getRoutingKey().equals(getRoutingKey());
+ }
}
public int hashCode()
{
- return getExchangeName().hashCode() + getRoutingKey().hashCode();
+ if (getDestSyntax() == DestSyntax.ADDR)
+ {
+ return super.hashCode();
+ }
+ else
+ {
+ return getExchangeName().hashCode() + getRoutingKey().hashCode();
+ }
}
}
diff --git a/qpid/java/client/src/test/java/org/apache/qpid/client/AMQDestinationTest.java b/qpid/java/client/src/test/java/org/apache/qpid/client/AMQDestinationTest.java
index e034fa5b3f..f46623ad3b 100644
--- a/qpid/java/client/src/test/java/org/apache/qpid/client/AMQDestinationTest.java
+++ b/qpid/java/client/src/test/java/org/apache/qpid/client/AMQDestinationTest.java
@@ -24,12 +24,12 @@ import junit.framework.TestCase;
public class AMQDestinationTest extends TestCase
{
- public void testEqaulsAndHashCodeForAddressBasedDestinations() throws Exception
+ public void testEqualsAndHashCodeForAddressBasedDestinations() throws Exception
{
AMQDestination dest = new AMQQueue("ADDR:Foo; {node :{type:queue}}");
AMQDestination dest1 = new AMQTopic("ADDR:Foo; {node :{type:topic}}");
- AMQDestination dest2 = new AMQQueue(
- "ADDR:Foo; {create:always,node :{type:queue}}");
+ AMQDestination dest10 = new AMQTopic("ADDR:Foo; {node :{type:topic}, link:{name:my-topic}}");
+ AMQDestination dest2 = new AMQQueue("ADDR:Foo; {create:always,node :{type:queue}}");
String bUrl = "BURL:direct://amq.direct/test-route/Foo?routingkey='Foo'";
AMQDestination dest3 = new AMQQueue(bUrl);
@@ -37,14 +37,30 @@ public class AMQDestinationTest extends TestCase
assertFalse(dest.equals(dest1));
assertTrue(dest.equals(dest2));
assertFalse(dest.equals(dest3));
+ assertTrue(dest1.equals(dest10));
assertTrue(dest.hashCode() == dest.hashCode());
assertTrue(dest.hashCode() != dest1.hashCode());
assertTrue(dest.hashCode() == dest2.hashCode());
assertTrue(dest.hashCode() != dest3.hashCode());
+ assertTrue(dest1.hashCode() == dest10.hashCode());
AMQDestination dest4 = new AMQQueue("ADDR:Foo/Bar; {node :{type:queue}}");
AMQDestination dest5 = new AMQQueue("ADDR:Foo/Bar2; {node :{type:queue}}");
+ assertFalse(dest4.equals(dest5));
assertTrue(dest4.hashCode() != dest5.hashCode());
+
+ AMQDestination dest6 = new AMQAnyDestination("ADDR:Foo; {node :{type:queue}}");
+ AMQDestination dest7 = new AMQAnyDestination("ADDR:Foo; {create: always, node :{type:queue}, link:{capacity: 10}}");
+ AMQDestination dest8 = new AMQAnyDestination("ADDR:Foo; {create: always, link:{capacity: 10}}");
+ AMQDestination dest9 = new AMQAnyDestination("ADDR:Foo/bar");
+ assertTrue(dest6.equals(dest7));
+ assertFalse(dest6.equals(dest8)); //dest8 type unknown, could be a topic
+ assertFalse(dest7.equals(dest8)); //dest8 type unknown, could be a topic
+ assertFalse(dest6.equals(dest9));
+ assertTrue(dest6.hashCode() == dest7.hashCode());
+ assertTrue(dest6.hashCode() != dest8.hashCode());
+ assertTrue(dest7.hashCode() != dest8.hashCode());
+ assertTrue(dest6.hashCode() != dest9.hashCode());
}
}
diff --git a/qpid/java/ivy.retrieve.xml b/qpid/java/ivy.retrieve.xml
index 5998a3e78e..4c8e935aca 100644
--- a/qpid/java/ivy.retrieve.xml
+++ b/qpid/java/ivy.retrieve.xml
@@ -75,7 +75,7 @@
<!-- The following are optional dependencies, for modules providing optional functionlity or
for use in optional build/test steps. Their optional status is usually indicative of licences
which are not compatible with the Apache Licence -->
- <dependency org="com.sleepycat" name="je" rev="5.0.58" transitive="false" conf="bdbje"/>
+ <dependency org="com.sleepycat" name="je" rev="5.0.73" transitive="false" conf="bdbje"/>
<dependency org="jfree" name="jfreechart" rev="1.0.13" transitive="false" conf="jfree"/>
<dependency org="jfree" name="jcommon" rev="1.0.16" transitive="false" conf="jfree"/>
<dependency org="net.sourceforge.csvjdbc" name="csvjdbc" rev="1.0.8" transitive="false" conf="csvjdbc"/>
diff --git a/qpid/java/lib/poms/je-5.0.58.xml b/qpid/java/lib/poms/je-5.0.73.xml
index d71a935dff..d55c4ec14f 100644
--- a/qpid/java/lib/poms/je-5.0.58.xml
+++ b/qpid/java/lib/poms/je-5.0.73.xml
@@ -18,5 +18,5 @@
<dep>
<groupId>com.sleepycat</groupId>
<artifactId>je</artifactId>
- <version>5.0.58</version>
+ <version>5.0.73</version>
</dep>
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationTest.java
index e9e6f93ab6..2e051d93dd 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationTest.java
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationTest.java
@@ -21,13 +21,14 @@
package org.apache.qpid.server.security.auth.manager;
import static org.apache.qpid.test.utils.TestSSLConstants.KEYSTORE;
-import static org.apache.qpid.test.utils.TestSSLConstants.UNTRUSTED_KEYSTORE;
import static org.apache.qpid.test.utils.TestSSLConstants.KEYSTORE_PASSWORD;
import static org.apache.qpid.test.utils.TestSSLConstants.TRUSTSTORE;
import static org.apache.qpid.test.utils.TestSSLConstants.TRUSTSTORE_PASSWORD;
+import static org.apache.qpid.test.utils.TestSSLConstants.UNTRUSTED_KEYSTORE;
import java.util.Collections;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import javax.jms.Connection;
@@ -35,11 +36,13 @@ import javax.jms.JMSException;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.qpid.client.AMQConnectionURL;
+import org.apache.qpid.management.common.mbeans.ManagedConnection;
import org.apache.qpid.server.model.AuthenticationProvider;
import org.apache.qpid.server.model.Broker;
import org.apache.qpid.server.model.Port;
import org.apache.qpid.server.model.Transport;
import org.apache.qpid.server.plugin.AuthenticationManagerFactory;
+import org.apache.qpid.test.utils.JMXTestUtils;
import org.apache.qpid.test.utils.QpidBrokerTestCase;
import org.apache.qpid.test.utils.TestBrokerConfiguration;
@@ -193,9 +196,78 @@ public class ExternalAuthenticationTest extends QpidBrokerTestCase
}
}
+ /**
+ * Tests the creation of usernames when EXTERNAL authentication is used.
+ * The username should be created as CN@DC1.DC2...DCn by default.
+ */
+ public void testExternalAuthenticationManagerUsernameAsCN() throws Exception
+ {
+ JMXTestUtils jmxUtils = new JMXTestUtils(this);
+ jmxUtils.setUp();
+
+ setCommonBrokerSSLProperties(true);
+ getBrokerConfiguration().setObjectAttribute(TestBrokerConfiguration.ENTRY_NAME_SSL_PORT, Port.AUTHENTICATION_PROVIDER, TestBrokerConfiguration.ENTRY_NAME_EXTERNAL_PROVIDER);
+
+ super.setUp();
+
+ setClientKeystoreProperties();
+ setClientTrustoreProperties();
+
+ try
+ {
+ getExternalSSLConnection(false);
+ }
+ catch (JMSException e)
+ {
+ fail("Should be able to create a connection to the SSL port: " + e.getMessage());
+ }
+
+ // Getting the used username using JMX
+ jmxUtils.open();
+ List<ManagedConnection> connections = jmxUtils.getManagedConnections("test");
+ assertNotNull("Connections are null", connections);
+ assertEquals("Unexpected number of connections", 1, connections.size());
+ assertEquals("Wrong authorized ID", "app2@acme.org", connections.get(0).getAuthorizedId());
+ }
+
+ /**
+ * Tests the creation of usernames when EXTERNAL authentication is used.
+ * The username should be created as full DN when the useFullDN option is used.
+ */
+ public void testExternalAuthenticationManagerUsernameAsDN() throws Exception
+ {
+ JMXTestUtils jmxUtils = new JMXTestUtils(this);
+ jmxUtils.setUp();
+
+ setCommonBrokerSSLProperties(true);
+ getBrokerConfiguration().setObjectAttribute(TestBrokerConfiguration.ENTRY_NAME_SSL_PORT, Port.AUTHENTICATION_PROVIDER, TestBrokerConfiguration.ENTRY_NAME_EXTERNAL_PROVIDER);
+ getBrokerConfiguration().setObjectAttribute(TestBrokerConfiguration.ENTRY_NAME_EXTERNAL_PROVIDER, ExternalAuthenticationManagerFactory.ATTRIBUTE_USE_FULL_DN, "true");
+
+ super.setUp();
+
+ setClientKeystoreProperties();
+ setClientTrustoreProperties();
+
+ try
+ {
+ getExternalSSLConnection(false);
+ }
+ catch (JMSException e)
+ {
+ fail("Should be able to create a connection to the SSL port: " + e.getMessage());
+ }
+
+ // Getting the used username using JMX
+ jmxUtils.open();
+ List<ManagedConnection> connections = jmxUtils.getManagedConnections("test");
+ assertNotNull("Connections are null", connections);
+ assertEquals("Unexpected number of connections", 1, connections.size());
+ assertEquals("Wrong authorized ID", "CN=app2@acme.org,OU=art,O=acme,L=Toronto,ST=ON,C=CA", connections.get(0).getAuthorizedId());
+ }
+
private Connection getExternalSSLConnection(boolean includeUserNameAndPassword) throws Exception
{
- String url = "amqp://%s@test/?brokerlist='tcp://localhost:%s?ssl='true'&sasl_mechs='EXTERNAL''";
+ String url = "amqp://%s@test/?brokerlist='tcp://localhost:%s?ssl='true'&sasl_mechs='EXTERNAL'&ssl_cert_alias='app2''";
if (includeUserNameAndPassword)
{
url = String.format(url, "guest:guest", String.valueOf(QpidBrokerTestCase.DEFAULT_SSL_PORT));
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/systest/rest/AuthenticationProviderRestTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/systest/rest/AuthenticationProviderRestTest.java
index 4ba2069dfd..09408572d7 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/systest/rest/AuthenticationProviderRestTest.java
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/systest/rest/AuthenticationProviderRestTest.java
@@ -24,6 +24,7 @@ import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.UUID;
import org.apache.qpid.server.model.AuthenticationProvider;
import org.apache.qpid.server.model.LifetimePolicy;
@@ -90,6 +91,22 @@ public class AuthenticationProviderRestTest extends QpidRestTestCase
assertProvider(false, AnonymousAuthenticationManagerFactory.PROVIDER_TYPE, provider);
}
+ public void testUpdateAuthenticationProviderIdFails() throws Exception
+ {
+ String providerName = "test-provider";
+ Map<String, Object> attributes = new HashMap<String, Object>();
+ attributes.put(AuthenticationProvider.NAME, providerName);
+ attributes.put(AuthenticationProvider.TYPE, AnonymousAuthenticationManagerFactory.PROVIDER_TYPE);
+
+ int responseCode = getRestTestHelper().submitRequest("/rest/authenticationprovider/" + providerName, "PUT", attributes);
+ assertEquals("Unexpected response code", 201, responseCode);
+
+ attributes.put(AuthenticationProvider.ID, UUID.randomUUID());
+
+ responseCode = getRestTestHelper().submitRequest("/rest/authenticationprovider/" + providerName, "PUT", attributes);
+ assertEquals("Update with new ID should fail", 409, responseCode);
+ }
+
public void testDeleteOfDefaultAuthenticationProviderFails() throws Exception
{
String providerName = TestBrokerConfiguration.ENTRY_NAME_AUTHENTICATION_PROVIDER;
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/systest/rest/PortRestTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/systest/rest/PortRestTest.java
index f8a7a9855f..1497d740dc 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/systest/rest/PortRestTest.java
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/systest/rest/PortRestTest.java
@@ -21,16 +21,20 @@
package org.apache.qpid.systest.rest;
import java.net.URLDecoder;
+import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
import org.apache.qpid.server.model.AuthenticationProvider;
+import org.apache.qpid.server.model.Broker;
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;
import org.apache.qpid.server.plugin.AuthenticationManagerFactory;
import org.apache.qpid.server.security.auth.manager.AnonymousAuthenticationManagerFactory;
import org.apache.qpid.test.utils.TestBrokerConfiguration;
@@ -159,8 +163,7 @@ public class PortRestTest extends QpidRestTestCase
responseCode = getRestTestHelper().submitRequest("/rest/port/" + portName, "PUT", attributes);
assertEquals("Port cannot be updated in non management mode", 409, responseCode);
- stopBroker();
- startBroker(DEFAULT_PORT, true);
+ restartBrokerInManagementMode();
responseCode = getRestTestHelper().submitRequest("/rest/port/" + portName, "PUT", attributes);
assertEquals("Port should be allwed to update in a management mode", 200, responseCode);
@@ -193,4 +196,133 @@ public class PortRestTest extends QpidRestTestCase
port = getRestTestHelper().getJsonAsSingletonList("/rest/port/" + TestBrokerConfiguration.ENTRY_NAME_AMQP_PORT);
assertEquals("Port has been changed", portValue, port.get(Port.PORT));
}
+
+ public void testUpdatePortTransportFromTCPToSSLWhenKeystoreIsConfigured() throws Exception
+ {
+ restartBrokerInManagementMode();
+
+ String portName = TestBrokerConfiguration.ENTRY_NAME_AMQP_PORT;
+ Map<String, Object> attributes = new HashMap<String, Object>();
+ attributes.put(Port.NAME, portName);
+ attributes.put(Port.TRANSPORTS, Collections.singleton(Transport.SSL));
+
+ int responseCode = getRestTestHelper().submitRequest("/rest/port/" + portName, "PUT", attributes);
+ assertEquals("Transport has not been changed to SSL " , 200, responseCode);
+
+ restartBroker();
+
+ Map<String, Object> port = getRestTestHelper().getJsonAsSingletonList("/rest/port/" + portName);
+
+ @SuppressWarnings("unchecked")
+ Collection<String> transports = (Collection<String>) port.get(Port.TRANSPORTS);
+ assertEquals("Unexpected auth provider", new HashSet<String>(Arrays.asList(Transport.SSL.name())),
+ new HashSet<String>(transports));
+ }
+
+ public void testUpdateTransportFromTCPToSSLWithoutKeystoreConfiguredFails() throws Exception
+ {
+ getBrokerConfiguration().setBrokerAttribute(Broker.KEY_STORE_PATH, null);
+ getBrokerConfiguration().setSaved(false);
+ restartBrokerInManagementMode();
+
+ String portName = TestBrokerConfiguration.ENTRY_NAME_AMQP_PORT;
+ Map<String, Object> attributes = new HashMap<String, Object>();
+ attributes.put(Port.NAME, portName);
+ attributes.put(Port.TRANSPORTS, Collections.singleton(Transport.SSL));
+
+ int responseCode = getRestTestHelper().submitRequest("/rest/port/" + portName, "PUT", attributes);
+ assertEquals("Creation of SSL port without keystore should fail", 409, responseCode);
+ }
+
+ public void testUpdateWantNeedClientAuth() throws Exception
+ {
+ String portName = TestBrokerConfiguration.ENTRY_NAME_SSL_PORT;
+ Map<String, Object> attributes = new HashMap<String, Object>();
+ attributes.put(Port.NAME, portName);
+ attributes.put(Port.PORT, DEFAULT_SSL_PORT);
+ attributes.put(Port.TRANSPORTS, Collections.singleton(Transport.SSL));
+
+ int responseCode = getRestTestHelper().submitRequest("/rest/port/" + portName, "PUT", attributes);
+ assertEquals("SSL port was not added", 201, responseCode);
+
+ restartBrokerInManagementMode();
+
+ attributes.put(Port.NEED_CLIENT_AUTH, true);
+ attributes.put(Port.WANT_CLIENT_AUTH, true);
+
+ responseCode = getRestTestHelper().submitRequest("/rest/port/" + portName, "PUT", attributes);
+ assertEquals("Attributes for need/want client auth are not set", 200, responseCode);
+
+ restartBroker();
+ Map<String, Object> port = getRestTestHelper().getJsonAsSingletonList("/rest/port/" + portName);
+ assertEquals("Unexpected " + Port.NEED_CLIENT_AUTH, true, port.get(Port.NEED_CLIENT_AUTH));
+ assertEquals("Unexpected " + Port.WANT_CLIENT_AUTH, true, port.get(Port.WANT_CLIENT_AUTH));
+
+ restartBrokerInManagementMode();
+
+ attributes = new HashMap<String, Object>();
+ attributes.put(Port.NAME, portName);
+ attributes.put(Port.TRANSPORTS, Collections.singleton(Transport.TCP));
+
+ responseCode = getRestTestHelper().submitRequest("/rest/port/" + portName, "PUT", attributes);
+ assertEquals("Should not be able to change transport to SSL without reseting of attributes for need/want client auth", 409, responseCode);
+
+ attributes = new HashMap<String, Object>();
+ attributes.put(Port.NAME, portName);
+ attributes.put(Port.TRANSPORTS, Collections.singleton(Transport.TCP));
+ attributes.put(Port.NEED_CLIENT_AUTH, false);
+ attributes.put(Port.WANT_CLIENT_AUTH, false);
+
+ responseCode = getRestTestHelper().submitRequest("/rest/port/" + portName, "PUT", attributes);
+ assertEquals("Should be able to change transport to TCP ", 200, responseCode);
+
+ restartBroker();
+ port = getRestTestHelper().getJsonAsSingletonList("/rest/port/" + portName);
+ assertEquals("Unexpected " + Port.NEED_CLIENT_AUTH, false, port.get(Port.NEED_CLIENT_AUTH));
+ assertEquals("Unexpected " + Port.WANT_CLIENT_AUTH, false, port.get(Port.WANT_CLIENT_AUTH));
+
+ @SuppressWarnings("unchecked")
+ Collection<String> transports = (Collection<String>) port.get(Port.TRANSPORTS);
+ assertEquals("Unexpected auth provider", new HashSet<String>(Arrays.asList(Transport.TCP.name())),
+ new HashSet<String>(transports));
+ }
+
+ public void testUpdateSettingWantNeedCertificateFailsForNonSSLPort() throws Exception
+ {
+ restartBrokerInManagementMode();
+
+ String portName = TestBrokerConfiguration.ENTRY_NAME_AMQP_PORT;
+ Map<String, Object> attributes = new HashMap<String, Object>();
+ attributes.put(Port.NAME, portName);
+ attributes.put(Port.NEED_CLIENT_AUTH, true);
+ int responseCode = getRestTestHelper().submitRequest("/rest/port/" + portName, "PUT", attributes);
+ assertEquals("Unexpected response when trying to set 'needClientAuth' on non-SSL port", 409, responseCode);
+
+ attributes = new HashMap<String, Object>();
+ attributes.put(Port.NAME, portName);
+ attributes.put(Port.WANT_CLIENT_AUTH, true);
+ responseCode = getRestTestHelper().submitRequest("/rest/port/" + portName, "PUT", attributes);
+ assertEquals("Unexpected response when trying to set 'wantClientAuth' on non-SSL port", 409, responseCode);
+ }
+
+ public void testUpdatePortAuthenticationProvider() throws Exception
+ {
+ restartBrokerInManagementMode();
+
+ String portName = TestBrokerConfiguration.ENTRY_NAME_AMQP_PORT;
+ Map<String, Object> attributes = new HashMap<String, Object>();
+ attributes.put(Port.NAME, portName);
+ attributes.put(Port.AUTHENTICATION_PROVIDER, "non-existing");
+ int responseCode = getRestTestHelper().submitRequest("/rest/port/" + portName, "PUT", attributes);
+ assertEquals("Unexpected response when trying to change auth provider to non-existing one", 409, responseCode);
+
+ attributes = new HashMap<String, Object>();
+ attributes.put(Port.NAME, portName);
+ attributes.put(Port.AUTHENTICATION_PROVIDER, ANONYMOUS_AUTHENTICATION_PROVIDER);
+ responseCode = getRestTestHelper().submitRequest("/rest/port/" + portName, "PUT", attributes);
+ assertEquals("Unexpected response when trying to change auth provider to existing one", 200, responseCode);
+
+ Map<String, Object> port = getRestTestHelper().getJsonAsSingletonList("/rest/port/" + portName);
+ assertEquals("Unexpected auth provider", ANONYMOUS_AUTHENTICATION_PROVIDER, port.get(Port.AUTHENTICATION_PROVIDER));
+ }
}