summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Rudyy <orudyy@apache.org>2013-03-11 18:30:31 +0000
committerAlex Rudyy <orudyy@apache.org>2013-03-11 18:30:31 +0000
commit3f138e2ddc02857c61e578aaaf12c82d9eefc93c (patch)
tree3de578ab99d630bc1610a263452c6715a0f0d901
parent66de8678fb2ab2af8dc5b6d653402b1efd70779b (diff)
downloadqpid-python-3f138e2ddc02857c61e578aaaf12c82d9eefc93c.tar.gz
QPID-4639: Add UI to add/delete virtual hosts into java broker web management console
git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@1455274 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/HelperServlet.java3
-rw-r--r--qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/action/ListMessageStoreTypes.java23
-rw-r--r--qpid/java/broker-plugins/management-http/src/main/java/resources/addVirtualHost.html71
-rw-r--r--qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/Broker.js38
-rw-r--r--qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/VirtualHost.js15
-rw-r--r--qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/addVirtualHost.js211
-rw-r--r--qpid/java/broker-plugins/management-http/src/main/java/resources/showBroker.html2
-rw-r--r--qpid/java/broker-plugins/management-http/src/main/java/resources/showVirtualHost.html7
-rw-r--r--qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagement.java19
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/BrokerRecoverer.java1
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/logging/LogRecorder.java30
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java6
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/VirtualHostAdapter.java41
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/store/MessageStoreCreator.java5
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/startup/VirtualHostRecovererTest.java11
-rw-r--r--qpid/java/systests/etc/config-systests.json2
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/systest/rest/AuthenticationProviderRestTest.java16
17 files changed, 471 insertions, 30 deletions
diff --git a/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/HelperServlet.java b/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/HelperServlet.java
index fa82632dc1..3c6fb1c44d 100644
--- a/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/HelperServlet.java
+++ b/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/HelperServlet.java
@@ -32,6 +32,7 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.qpid.server.management.plugin.servlet.rest.action.ListAuthenticationProviderAttributes;
+import org.apache.qpid.server.management.plugin.servlet.rest.action.ListMessageStoreTypes;
import org.apache.qpid.server.model.Broker;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.SerializationConfig;
@@ -50,6 +51,8 @@ public class HelperServlet extends AbstractServlet
_actions = new HashMap<String, Action>();
Action listProviderAttributes = new ListAuthenticationProviderAttributes();
_actions.put(listProviderAttributes.getName(), listProviderAttributes);
+ Action listMessageStoreTypes = new ListMessageStoreTypes();
+ _actions.put(listMessageStoreTypes.getName(), listMessageStoreTypes);
}
@Override
diff --git a/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/action/ListMessageStoreTypes.java b/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/action/ListMessageStoreTypes.java
new file mode 100644
index 0000000000..4166736c01
--- /dev/null
+++ b/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/action/ListMessageStoreTypes.java
@@ -0,0 +1,23 @@
+package org.apache.qpid.server.management.plugin.servlet.rest.action;
+
+import java.util.Map;
+
+import org.apache.qpid.server.management.plugin.servlet.rest.Action;
+import org.apache.qpid.server.model.Broker;
+
+public class ListMessageStoreTypes implements Action
+{
+
+ @Override
+ public String getName()
+ {
+ return ListMessageStoreTypes.class.getSimpleName();
+ }
+
+ @Override
+ public Object perform(Map<String, Object> request, Broker broker)
+ {
+ return broker.getAttribute(Broker.SUPPORTED_STORE_TYPES);
+ }
+
+}
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
new file mode 100644
index 0000000000..d66e0e1b03
--- /dev/null
+++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/addVirtualHost.html
@@ -0,0 +1,71 @@
+<!--
+ -
+ - Licensed to the Apache Software Foundation (ASF) under one
+ - or more contributor license agreements. See the NOTICE file
+ - distributed with this work for additional information
+ - regarding copyright ownership. The ASF licenses this file
+ - to you under the Apache License, Version 2.0 (the
+ - "License"); you may not use this file except in compliance
+ - with the License. You may obtain a copy of the License at
+ -
+ - http://www.apache.org/licenses/LICENSE-2.0
+ -
+ - Unless required by applicable law or agreed to in writing,
+ - software distributed under the License is distributed on an
+ - "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ - KIND, either express or implied. See the License for the
+ - specific language governing permissions and limitations
+ - under the License.
+ -
+ -->
+<div class="dijitHidden">
+ <div data-dojo-type="dijit.Dialog" style="width:600px;" data-dojo-props="title:'Add Virtual Host'" id="addVirtualHost">
+ <form id="formAddVirtualHost" method="post" dojoType="dijit.form.Form">
+ <table class="tableContainer-table tableContainer-table-horiz">
+ <tr>
+ <td class="tableContainer-labelCell" style="width: 300px;"><strong>Name*: </strong></td>
+ <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" />
+ </td>
+ </tr>
+ </table>
+ <br />
+ <div>Specify either a store type and location, or an XML configuration file location, but not both.</div>
+ <div style="height: 300px;" id="addVirtualHost.variants">
+ <div id="addVirtualHost.configPathDiv">
+ <table class="tableContainer-table tableContainer-table-horiz">
+ <tr>
+ <td class="tableContainer-labelCell" style="width: 300px;"><strong>Path to virtual host configuration file*: </strong></td>
+ <td class="tableContainer-valueCell">
+ <input dojoType="dijit.form.ValidationTextBox" id="formAddVirtualHost.configPath"
+ name="configPath" placeholder="/path/to/virtualhost.xml" />
+ </td>
+ </tr>
+ </table>
+ </div>
+ <div id="addVirtualHost.attributesDiv">
+ <table class="tableContainer-table tableContainer-table-horiz">
+ <tr>
+ <td class="tableContainer-labelCell" style="width: 300px;"><strong>Store Type*: </strong></td>
+ <td class="tableContainer-valueCell" ><div id="addVirtualHost.selectStoreType"></div></td>
+ </tr>
+ <tr>
+ <td class="tableContainer-labelCell" style="width: 300px;"><strong>Path to store location*: </strong></td>
+ <td class="tableContainer-valueCell">
+ <input dojoType="dijit.form.ValidationTextBox" id="formAddVirtualHost.storePath"
+ name="storePath" placeholder="/path/to/message/store" />
+ </td>
+ </tr>
+ </table>
+ </div>
+ </div>
+
+ <br/>
+ <!-- submit buttons -->
+ <input type="submit" value="Save" label="Save" dojoType="dijit.form.Button" />
+ <input type="hidden" id="formAddVirtualHost.id" name="id"/>
+ </form>
+ </div>
+</div>
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 9b4e7aa3f9..84a0d8ca68 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
@@ -29,10 +29,13 @@ define(["dojo/_base/xhr",
"dojox/grid/EnhancedGrid",
"dijit/registry",
"qpid/management/addAuthenticationProvider",
+ "qpid/management/addVirtualHost",
"dojox/grid/enhanced/plugins/Pagination",
"dojox/grid/enhanced/plugins/IndirectSelection",
+ "dijit/layout/AccordionContainer",
+ "dijit/layout/AccordionPane",
"dojo/domReady!"],
- function (xhr, parser, query, connect, properties, updater, util, UpdatableStore, EnhancedGrid, registry, addAuthenticationProvider) {
+ function (xhr, parser, query, connect, properties, updater, util, UpdatableStore, EnhancedGrid, registry, addAuthenticationProvider, addVirtualHost) {
function Broker(name, parent, controller) {
this.name = name;
@@ -78,6 +81,19 @@ define(["dojo/_base/xhr",
}
);
+ var addHostButton = query(".addVirtualHost", contentPane.containerNode)[0];
+ connect.connect(registry.byNode(addHostButton), "onClick", function(evt){ addVirtualHost.show(); });
+
+ var deleteHostButton = query(".deleteVirtualHost", contentPane.containerNode)[0];
+ connect.connect(registry.byNode(deleteHostButton), "onClick",
+ function(evt){
+ util.deleteGridSelections(
+ that.brokerUpdater,
+ that.brokerUpdater.vhostsGrid.grid,
+ "rest/virtualhost",
+ "Deletion of virtual will delete the message store data.\n\n Are you sure you want to delete virtual host");
+ }
+ );
}});
};
@@ -105,6 +121,22 @@ define(["dojo/_base/xhr",
util.flattenStatistics( that.brokerData);
that.updateHeader();
+
+ var gridProperties = {
+ height: 400,
+ plugins: {
+ pagination: {
+ pageSizes: ["10", "25", "50", "100"],
+ description: true,
+ sizeSwitch: true,
+ pageStepper: true,
+ gotoButton: true,
+ maxPageStep: 4,
+ position: "bottom"
+ },
+ indirectSelection: true
+ }};
+
that.vhostsGrid =
new UpdatableStore(that.brokerData.vhosts, query(".broker-virtualhosts")[0],
[ { name: "Virtual Host", field: "name", width: "120px"},
@@ -119,7 +151,7 @@ define(["dojo/_base/xhr",
var name = obj.dataStore.getValue(theItem,"name");
that.controller.show("virtualhost", name, brokerObj);
});
- });
+ }, gridProperties, EnhancedGrid);
that.portsGrid =
new UpdatableStore(that.brokerData.ports, query(".broker-ports")[0],
@@ -137,7 +169,7 @@ define(["dojo/_base/xhr",
});
});
- var gridProperties = {
+ gridProperties = {
keepSelection: true,
plugins: {
indirectSelection: true
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 2efc46476d..ceab5640d3 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
@@ -134,7 +134,10 @@ define(["dojo/_base/xhr",
"bytesInRateUnits",
"msgOutRate",
"bytesOutRate",
- "bytesOutRateUnits"]);
+ "bytesOutRateUnits",
+ "storeType",
+ "storePath",
+ "configPath"]);
this.query = "rest/virtualhost/"+ encodeURIComponent(vhost.name);
@@ -143,6 +146,11 @@ define(["dojo/_base/xhr",
xhr.get({url: this.query, sync: properties.useSyncGet, handleAs: "json"}).then(function(data) {
that.vhostData = data[0];
+ if (!that.vhostData.hasOwnProperty("configPath"))
+ {
+ var node = findNode("configPathDiv");
+ node.style.display = "none";
+ }
// flatten statistics into attributes
util.flattenStatistics( that.vhostData );
@@ -233,8 +241,9 @@ define(["dojo/_base/xhr",
this.state.innerHTML = this.vhostData[ "state" ];
this.durable.innerHTML = this.vhostData[ "durable" ];
this.lifetimePolicy.innerHTML = this.vhostData[ "lifetimePolicy" ];
-
-
+ this.storeType.innerHTML = this.vhostData[ "storeType" ];
+ this.storePath.innerHTML = this.vhostData[ "storePath" ];
+ this.configPath.innerHTML = this.vhostData[ "configPath" ];
};
Updater.prototype.update = function()
diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/addVirtualHost.js b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/addVirtualHost.js
new file mode 100644
index 0000000000..9c04c3014f
--- /dev/null
+++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/addVirtualHost.js
@@ -0,0 +1,211 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+define(["dojo/_base/xhr",
+ "dojo/dom",
+ "dojo/dom-construct",
+ "dojo/_base/window",
+ "dijit/registry",
+ "dojo/parser",
+ "dojo/_base/array",
+ "dojo/_base/event",
+ 'dojo/_base/json',
+ "dojo/store/Memory",
+ "dijit/form/FilteringSelect",
+ "dojo/_base/connect",
+ "dojo/dom-style",
+ "dijit/form/NumberSpinner", // required by the form
+ /* dojox/ validate resources */
+ "dojox/validate/us", "dojox/validate/web",
+ /* basic dijit classes */
+ "dijit/Dialog",
+ "dijit/form/CheckBox", "dijit/form/Textarea",
+ "dijit/form/FilteringSelect", "dijit/form/TextBox",
+ "dijit/form/ValidationTextBox", "dijit/form/DateTextBox",
+ "dijit/form/TimeTextBox", "dijit/form/Button",
+ "dijit/form/RadioButton", "dijit/form/Form",
+ "dijit/form/DateTextBox",
+ /* basic dojox classes */
+ "dojox/form/BusyButton", "dojox/form/CheckedMultiSelect",
+ "dojox/layout/TableContainer",
+ "dijit/layout/AccordionContainer",
+ "dijit/layout/AccordionPane",
+ "dojo/domReady!"],
+ function (xhr, dom, construct, win, registry, parser, array, event, json, Memory, FilteringSelect, connect, domStyle) {
+
+ var addVirtualHost = {};
+
+ var node = construct.create("div", null, win.body(), "last");
+
+ var convertToVirtualHost = function convertToVirtualHost(formValues)
+ {
+ var newVirtualHost = {};
+ var id = dojo.byId("formAddVirtualHost.id").value;
+ if (id)
+ {
+ newVirtualHost.id = id;
+ }
+ for(var propName in formValues)
+ {
+ if(formValues.hasOwnProperty(propName))
+ {
+ if(formValues[ propName ] !== "") {
+ newVirtualHost[ propName ] = formValues[propName];
+ }
+
+ }
+ }
+
+ return newVirtualHost;
+ }
+
+ if (!dijit.registry["addVirtualHost"])
+ {
+ var that = this;
+ xhr.get({url: "addVirtualHost.html",
+ sync: true,
+ load: function(data) {
+ var theForm;
+ node.innerHTML = data;
+ addVirtualHost.dialogNode = dom.byId("addVirtualHost");
+ parser.instantiate([addVirtualHost.dialogNode]);
+
+ var configPathPane = new dijit.layout.AccordionPane({
+ title: "Configuration File"
+ }, "addVirtualHost.configPathDiv");
+
+ var attributesPane = new dijit.layout.AccordionPane({
+ title: "Store Attributes",
+ selected: true
+ }, "addVirtualHost.attributesDiv");
+
+ var aContainer = new dijit.layout.AccordionContainer({
+ style: "height: 150px"
+ },
+ "addVirtualHost.variants");
+
+ aContainer.addChild(attributesPane);
+ aContainer.addChild(configPathPane);
+ aContainer.startup();
+
+ theForm = registry.byId("formAddVirtualHost");
+ theForm.on("submit", function(e) {
+
+ event.stop(e);
+ if(theForm.validate()){
+
+ var formValues = theForm.getValues();
+ if (formValues.configPath == "" && formValues.storeType == "")
+ {
+ alert("Please specify either configuration or store type for the virtual host");
+ return false;
+ }
+ if (formValues.configPath != "" && formValues.storeType != "")
+ {
+ alert("Either configuration or store type with path have to be specified!");
+ return false;
+ }
+ var newVirtualHost = convertToVirtualHost(formValues);
+ var that = this;
+
+ xhr.put({url: "rest/virtualhost/" + encodeURIComponent(newVirtualHost.name),
+ sync: true, handleAs: "json",
+ headers: { "Content-Type": "application/json"},
+ putData: json.toJson(newVirtualHost),
+ load: function(x) {that.success = true; },
+ error: function(error) {that.success = false; that.failureReason = error;}});
+
+ if(this.success === true)
+ {
+ registry.byId("addVirtualHost").hide();
+ }
+ else
+ {
+ alert("Error:" + this.failureReason);
+ }
+ return false;
+ }else{
+ alert('Form contains invalid data. Please correct first');
+ return false;
+ }
+ });
+ }});
+ }
+
+ addVirtualHost.show = function(virtualHostName) {
+ var that = this;
+ registry.byId("formAddVirtualHost").reset();
+ dojo.byId("formAddVirtualHost.id").value="";
+ if (!that.hasOwnProperty("storeTypeChooser"))
+ {
+ xhr.get({
+ sync: true,
+ url: "rest/helper?action=ListMessageStoreTypes",
+ handleAs: "json"
+ }).then(
+ function(data) {
+ var storeTypes = data;
+ var storeTypesData = [];
+ for (var i =0 ; i < storeTypes.length; i++)
+ {
+ storeTypesData[i]= {id: storeTypes[i], name: storeTypes[i]};
+ }
+ var storeTypesStore = new Memory({ data: storeTypesData });
+ var storeTypesDiv = dom.byId("addVirtualHost.selectStoreType");
+ var input = construct.create("input", {id: "addStoreType", required: false}, storeTypesDiv);
+ that.storeTypeChooser = new FilteringSelect({ id: "addVirtualHost.storeType",
+ name: "storeType",
+ store: storeTypesStore,
+ searchAttr: "name", required: false}, input);
+ });
+ }
+ if (virtualHostName)
+ {
+ xhr.get({
+ url: "rest/virtualhost/" + encodeURIComponent(virtualHostName),
+ handleAs: "json"
+ }).then(
+ function(data) {
+ var host = data[0];
+ var nameField = dijit.byId("formAddVirtualHost.name");
+ nameField.set("value", host.name);
+ dojo.byId("formAddVirtualHost.id").value=host.id;
+ var configPath = host.configPath;
+ if (configPath)
+ {
+ var configPathField = dijit.byId("formAddVirtualHost.configPath");
+ configPathField.set("value", host.configPath);
+ }
+ else
+ {
+ that.storeTypeChooser.set("value", host.storeType.toLowerCase());
+ var storePathField = dijit.byId("formAddVirtualHost.storePath");
+ storePathField.set("value", host.storePath);
+ }
+ registry.byId("addVirtualHost").show();
+ });
+ }
+ else
+ {
+ registry.byId("addVirtualHost").show();
+ }
+ }
+ return addVirtualHost;
+ }); \ No newline at end of file
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 f656124a2a..527d38c333 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
@@ -30,6 +30,8 @@
<br/>
<div data-dojo-type="dijit.TitlePane" data-dojo-props="title: 'Virtual Hosts'">
<div class="broker-virtualhosts"></div>
+ <button data-dojo-type="dijit.form.Button" class="addVirtualHost">Add Virtual Host</button>
+ <button data-dojo-type="dijit.form.Button" class="deleteVirtualHost">Delete Virtual Host</button>
</div>
<br/>
<div data-dojo-type="dijit.TitlePane" data-dojo-props="title: 'Ports'">
diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/showVirtualHost.html b/qpid/java/broker-plugins/management-http/src/main/java/resources/showVirtualHost.html
index 73c912e0d4..14833e0d2e 100644
--- a/qpid/java/broker-plugins/management-http/src/main/java/resources/showVirtualHost.html
+++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/showVirtualHost.html
@@ -39,6 +39,13 @@
<span class="bytesOutRate" style="position:absolute; right: 3.3em"></span>
<span class="bytesOutRateUnits" style="position:absolute; right: 0em; width: 3em"></span>
<br/>
+ <span style="">Store Type:</span><span style="position:absolute; left:6em" class="storeType"></span>
+ <span style="position:absolute; left:26em">Store Path:</span>
+ <span class="storePath" style="position:absolute; right: 1em"></span>
+ <div class="configPathDiv">
+ <span style="">ConfigPath:</span><span style="position:absolute; left:6em" class="configPath"></span>
+ </div>
+
<br/>
<div data-dojo-type="dijit.TitlePane" data-dojo-props="title: 'Exchanges'">
<div class="exchanges"></div>
diff --git a/qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagement.java b/qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagement.java
index d725dc4dc3..3342aea4fb 100644
--- a/qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagement.java
+++ b/qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagement.java
@@ -297,12 +297,27 @@ public class JMXManagement extends AbstractPluginAdapter implements Configuratio
}
catch(JMException e)
{
- LOGGER.error("Error creating mbean", e);
+ LOGGER.error("Error unregistering user management mbean: " + child.getName(), e);
+ //TODO - report error on removing child MBean
+ }
+ }
+ }
+ else if (child instanceof VirtualHost)
+ {
+ AMQManagedObject mbean = _children.remove(child);
+ if(mbean != null)
+ {
+ try
+ {
+ mbean.unregister();
+ }
+ catch(JMException e)
+ {
+ LOGGER.error("Error unregistering virtual host mbean :" + child.getName(), e);
//TODO - report error on removing child MBean
}
}
}
-
}
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/BrokerRecoverer.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/BrokerRecoverer.java
index 4bfa0ca7a3..48d80592f6 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/BrokerRecoverer.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/BrokerRecoverer.java
@@ -51,6 +51,7 @@ public class BrokerRecoverer implements ConfiguredObjectRecoverer<Broker>
StoreConfigurationChangeListener storeChangeListener = new StoreConfigurationChangeListener(entry.getStore());
BrokerAdapter broker = new BrokerAdapter(entry.getId(), entry.getAttributes(), _statisticsGatherer, _virtualHostRegistry,
_logRecorder, _rootMessageLogger, _authenticationProviderFactory, _portFactory, _taskExecutor);
+
broker.addChangeListener(storeChangeListener);
Map<String, Collection<ConfigurationEntry>> childEntries = entry.getChildren();
for (String type : childEntries.keySet())
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/LogRecorder.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/LogRecorder.java
index d053dd3fe2..5528a05360 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/LogRecorder.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/LogRecorder.java
@@ -24,6 +24,7 @@ import org.apache.log4j.Logger;
import org.apache.log4j.spi.ErrorHandler;
import org.apache.log4j.spi.Filter;
import org.apache.log4j.spi.LoggingEvent;
+import org.apache.log4j.spi.ThrowableInformation;
public class LogRecorder implements Appender, Iterable<LogRecorder.Record>
{
@@ -54,7 +55,34 @@ public class LogRecorder implements Appender, Iterable<LogRecorder.Record>
_timestamp = event.timeStamp;
_threadName = event.getThreadName();
_level = event.getLevel().toString();
- _message = event.getRenderedMessage();
+ StringBuilder message = new StringBuilder();
+ String renderedMessage = event.getRenderedMessage();
+ if (renderedMessage != null)
+ {
+ message.append(renderedMessage);
+ }
+ ThrowableInformation ti = event.getThrowableInformation();
+ if (ti != null)
+ {
+ Throwable t = ti.getThrowable();
+ if (t != null)
+ {
+ if (message.length() > 0)
+ {
+ message.append(":");
+ }
+ String exceptionMessage = t.getMessage();
+ if (exceptionMessage != null && !"".equals(exceptionMessage))
+ {
+ message.append(t.getMessage());
+ }
+ else
+ {
+ message.append(t.getClass().getName());
+ }
+ }
+ }
+ _message = message.toString();
}
public long getId()
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 6b7cf98c8a..628ba5a099 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
@@ -63,6 +63,7 @@ import org.apache.qpid.server.security.group.GroupPrincipalAccessor;
import org.apache.qpid.server.security.SecurityManager;
import org.apache.qpid.server.security.SubjectCreator;
import org.apache.qpid.server.stats.StatisticsGatherer;
+import org.apache.qpid.server.store.MessageStoreCreator;
import org.apache.qpid.server.util.MapValueConverter;
import org.apache.qpid.server.virtualhost.VirtualHostRegistry;
@@ -168,6 +169,8 @@ public class BrokerAdapter extends AbstractAdapter implements Broker, Configurat
private final UUID _defaultKeyStoreId;
private final UUID _defaultTrustStoreId;
+ private Collection<String> _supportedStoreTypes;
+
public BrokerAdapter(UUID id, Map<String, Object> attributes, StatisticsGatherer statisticsGatherer, VirtualHostRegistry virtualHostRegistry,
LogRecorder logRecorder, RootMessageLogger rootMessageLogger, AuthenticationProviderFactory authenticationProviderFactory,
PortFactory portFactory, TaskExecutor taskExecutor)
@@ -185,6 +188,7 @@ public class BrokerAdapter extends AbstractAdapter implements Broker, Configurat
_defaultKeyStoreId = UUIDGenerator.generateBrokerChildUUID(KeyStore.class.getSimpleName(), DEFAULT_KEY_STORE_NAME);
_defaultTrustStoreId = UUIDGenerator.generateBrokerChildUUID(TrustStore.class.getSimpleName(), DEFAULT_TRUST_STORE_NAME);
createBrokerChildrenFromAttributes();
+ _supportedStoreTypes = new MessageStoreCreator().getStoreTypes();
}
/*
@@ -646,7 +650,7 @@ public class BrokerAdapter extends AbstractAdapter implements Broker, Configurat
}
else if(SUPPORTED_STORE_TYPES.equals(name))
{
- // TODO
+ return _supportedStoreTypes;
}
else if(SUPPORTED_AUTHENTICATION_PROVIDERS.equals(name))
{
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 40af67f211..8680911000 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
@@ -115,9 +115,9 @@ public final class VirtualHostAdapter extends AbstractAdapter implements Virtual
public VirtualHostAdapter(UUID id, Map<String, Object> attributes, Broker broker, StatisticsGatherer brokerStatisticsGatherer, TaskExecutor taskExecutor)
{
super(id, null, MapValueConverter.convert(attributes, ATTRIBUTE_TYPES), taskExecutor);
- validateAttributes();
_broker = broker;
_brokerStatisticsGatherer = brokerStatisticsGatherer;
+ validateAttributes();
addParent(Broker.class, broker);
}
@@ -145,11 +145,22 @@ public final class VirtualHostAdapter extends AbstractAdapter implements Virtual
{
invalidAttributes = true;
}
+
}
if (invalidAttributes)
{
throw new IllegalConfigurationException("Please specify either the 'configPath' attribute or 'storeType' and 'storePath' attributes");
}
+
+ // pre-load the configuration in order to validate
+ try
+ {
+ createVirtualHostConfiguration(name);
+ }
+ catch(ConfigurationException e)
+ {
+ throw new IllegalConfigurationException("Failed to validate configuration", e);
+ }
}
private void populateExchanges()
@@ -504,11 +515,19 @@ public final class VirtualHostAdapter extends AbstractAdapter implements Virtual
{
if(childClass == Exchange.class)
{
- return (C) createExchange(attributes);
+ createExchange(attributes);
+
+ // return null to avoid double notification of VirtualHostMBean
+ // as we already notify it in the exchangeRegistered
+ return null;
}
else if(childClass == Queue.class)
{
- return (C) createQueue(attributes);
+ createQueue(attributes);
+
+ // return null to avoid double notification of VirtualHostMBean
+ // as we already notify it in the queueRegistered
+ return null;
}
else if(childClass == VirtualHostAlias.class)
{
@@ -969,12 +988,24 @@ public final class VirtualHostAdapter extends AbstractAdapter implements Virtual
{
throw new IntegrityViolationException("Cannot delete default virtual host '" + hostName + "'");
}
+ String storePath = (String)getAttribute(STORE_PATH);
if (_virtualHost != null && _virtualHost.getState() == org.apache.qpid.server.virtualhost.State.ACTIVE)
{
setDesiredState(currentState, State.STOPPED);
}
_virtualHost = null;
setAttribute(VirtualHost.STATE, getActualState(), State.DELETED);
+ if (storePath != null)
+ {
+ if (LOGGER.isDebugEnabled())
+ {
+ LOGGER.debug("Deleting store at " + storePath);
+ }
+ if (!FileUtils.delete(new File(storePath), true))
+ {
+ LOGGER.warn("Cannot delete " + storePath);
+ }
+ }
return true;
}
return false;
@@ -1034,6 +1065,10 @@ public final class VirtualHostAdapter extends AbstractAdapter implements Virtual
}
else
{
+ if (!new File(configurationFile).exists())
+ {
+ throw new IllegalConfigurationException("Configuration file '" + configurationFile + "' does not exist");
+ }
configuration = new VirtualHostConfiguration(virtualHostName, new File(configurationFile) , _broker);
}
return configuration;
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/store/MessageStoreCreator.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/store/MessageStoreCreator.java
index 0bc83c89d2..d67ccfd8a4 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/store/MessageStoreCreator.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/store/MessageStoreCreator.java
@@ -64,4 +64,9 @@ public class MessageStoreCreator
{
return Collections.unmodifiableCollection(_factories.values());
}
+
+ public Collection<String> getStoreTypes()
+ {
+ return Collections.unmodifiableCollection(_factories.keySet());
+ }
}
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/startup/VirtualHostRecovererTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/startup/VirtualHostRecovererTest.java
index eb5b2b350f..adb1f81a43 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/startup/VirtualHostRecovererTest.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/startup/VirtualHostRecovererTest.java
@@ -23,6 +23,7 @@ package org.apache.qpid.server.configuration.startup;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
+import java.io.File;
import java.util.HashMap;
import java.util.Map;
@@ -34,6 +35,7 @@ import org.apache.qpid.server.model.Broker;
import org.apache.qpid.server.model.VirtualHost;
import org.apache.qpid.server.security.SecurityManager;
import org.apache.qpid.server.stats.StatisticsGatherer;
+import org.apache.qpid.test.utils.TestFileUtils;
public class VirtualHostRecovererTest extends TestCase
{
@@ -43,12 +45,16 @@ public class VirtualHostRecovererTest extends TestCase
SecurityManager securityManager = mock(SecurityManager.class);
ConfigurationEntry entry = mock(ConfigurationEntry.class);
Broker parent = mock(Broker.class);
+ when(parent.getAttribute(Broker.HOUSEKEEPING_CHECK_PERIOD)).thenReturn(3000l);
when(parent.getSecurityManager()).thenReturn(securityManager);
VirtualHostRecoverer recoverer = new VirtualHostRecoverer(statisticsGatherer);
Map<String, Object> attributes = new HashMap<String, Object>();
- attributes.put(VirtualHost.NAME, getName());
- attributes.put(VirtualHost.CONFIG_PATH, "/path/to/virtualhost.xml");
+ String name = getName();
+ attributes.put(VirtualHost.NAME, name);
+ File file = TestFileUtils.createTempFile(this, ".xml", "<virtualhosts><virtualhost><name>" + name + "</name><" + name
+ + "></" + name + "></virtualhost></virtualhosts>");
+ attributes.put(VirtualHost.CONFIG_PATH, file.getAbsolutePath());
when(entry.getAttributes()).thenReturn(attributes);
VirtualHost host = recoverer.create(null, entry, parent);
@@ -63,6 +69,7 @@ public class VirtualHostRecovererTest extends TestCase
SecurityManager securityManager = mock(SecurityManager.class);
ConfigurationEntry entry = mock(ConfigurationEntry.class);
Broker parent = mock(Broker.class);
+ when(parent.getAttribute(Broker.HOUSEKEEPING_CHECK_PERIOD)).thenReturn(3000l);
when(parent.getSecurityManager()).thenReturn(securityManager);
VirtualHostRecoverer recoverer = new VirtualHostRecoverer(statisticsGatherer);
diff --git a/qpid/java/systests/etc/config-systests.json b/qpid/java/systests/etc/config-systests.json
index a5b85a2050..412bee3f6b 100644
--- a/qpid/java/systests/etc/config-systests.json
+++ b/qpid/java/systests/etc/config-systests.json
@@ -28,7 +28,7 @@
"trustStorePassword": "password",
"authenticationproviders" : [ {
"name" : "plain",
- "authenticationProviderType" : "PlainPasswordFileAuthenticationProvider",
+ "type" : "PlainPasswordFileAuthenticationProvider",
"path" : "${QPID_HOME}/etc/passwd"
} ],
"ports" : [ {
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 89645507c4..40a1c13718 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
@@ -52,7 +52,7 @@ public class AuthenticationProviderRestTest extends QpidRestTestCase
}
}
- public void testPutCreateNewPlainPrincipalDatabaseProvider() throws Exception
+ public void testPutCreateSecondPlainPrincipalDatabaseProviderFails() throws Exception
{
File principalDatabase = getRestTestHelper().createTemporaryPasswdFile(new String[]{"admin2", "guest2", "test2"});
@@ -63,19 +63,7 @@ public class AuthenticationProviderRestTest extends QpidRestTestCase
attributes.put(PlainPasswordFileAuthenticationManagerFactory.ATTRIBUTE_PATH, principalDatabase.getAbsolutePath());
int responseCode = getRestTestHelper().submitRequest("/rest/authenticationprovider/" + providerName, "PUT", attributes);
- assertEquals("Unexpected response code", 201, responseCode);
-
- List<Map<String, Object>> providerDetails = getRestTestHelper().getJsonAsList("/rest/authenticationprovider/" + providerName);
- assertNotNull("Providers details cannot be null", providerDetails);
- assertEquals("Unexpected number of providers", 1, providerDetails.size());
- Map<String, Object> provider = providerDetails.get(0);
- assertProvider(true, PlainPasswordFileAuthenticationManagerFactory.PROVIDER_TYPE, provider);
-
- // provider should exists after broker restart
- restartBroker();
- providerDetails = getRestTestHelper().getJsonAsList("/rest/authenticationprovider/" + providerName);
- assertNotNull("Providers details cannot be null", providerDetails);
- assertEquals("Unexpected number of providers", 1, providerDetails.size());
+ assertEquals("Expected to fail because we can have only one password provider", 409, responseCode);
}
public void testPutCreateNewAnonymousProvider() throws Exception