summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Gemmell <robbie@apache.org>2012-07-20 14:46:19 +0000
committerRobert Gemmell <robbie@apache.org>2012-07-20 14:46:19 +0000
commit373c004d206575dd21d37ee9cba1cea9ef66b881 (patch)
tree1336bc51ff7c1a58c7d5b7ca7ea30fc04534a961
parent3595a98e8527e16ab078dfe45b602dc42d21430b (diff)
downloadqpid-python-373c004d206575dd21d37ee9cba1cea9ef66b881.tar.gz
QPID-4149: Add REST functionality to delete exchanges, queues and bindings, add queue/exchange/binding delete operations into web UI
Applied patch from Oleksandr Rudyy <orudyy@gmail.com> and myself. merged from trunk r1363298 git-svn-id: https://svn.apache.org/repos/asf/qpid/branches/0.18@1363810 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/util.js68
-rw-r--r--qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/Exchange.js66
-rw-r--r--qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/Queue.js23
-rw-r--r--qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/VirtualHost.js69
-rw-r--r--qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/addExchange.js1
-rw-r--r--qpid/java/broker-plugins/management-http/src/main/java/resources/showExchange.html4
-rw-r--r--qpid/java/broker-plugins/management-http/src/main/java/resources/showQueue.html4
-rw-r--r--qpid/java/broker-plugins/management-http/src/main/java/resources/showVirtualHost.html2
-rw-r--r--qpid/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/BindingRestTest.java45
-rw-r--r--qpid/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/VirtualHostRestTest.java50
-rw-r--r--qpid/java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/systest/management/jmx/BrokerManagementTest.java8
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/DefaultExchangeRegistry.java17
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/ExchangeRegistry.java7
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/model/VirtualHost.java2
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/BindingAdapter.java13
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/ExchangeAdapter.java33
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/QueueAdapter.java26
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/VirtualHostAdapter.java71
18 files changed, 450 insertions, 59 deletions
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 d7917b640e..08fdf5c99b 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
@@ -18,8 +18,8 @@
* under the License.
*
*/
-define([],
- function () {
+define(["dojo/_base/xhr"],
+ function (xhr) {
var util = {};
if (Array.isArray) {
util.isArray = function (object) {
@@ -52,5 +52,69 @@ define([],
}
}
};
+
+ util.isReservedExchangeName = function(exchangeName)
+ {
+ return exchangeName == null || exchangeName == "" || "<<default>>" == exchangeName || exchangeName.indexOf("amq.") == 0 || exchangeName.indexOf("qpid.") == 0;
+ };
+
+ util.deleteGridSelections = function(updater, gridName, url, confirmationMessageStart)
+ {
+ var grid = updater[gridName].grid;
+ var data = grid.selection.getSelected();
+ if(data.length)
+ {
+ var confirmationMessage = null;
+ if (data.length == 1)
+ {
+ confirmationMessage = confirmationMessageStart + " '" + data[0].name + "'?";
+ }
+ else
+ {
+ var names = '';
+ for(var i = 0; i<data.length; i++)
+ {
+ if (names)
+ {
+ names += ', ';
+ }
+ names += "\""+ data[i].name + "\"";
+ }
+ confirmationMessage = confirmationMessageStart + "s " + names + "?";
+ }
+ if(confirm(confirmationMessage))
+ {
+ var i, queryParam;
+ for(i = 0; i<data.length; i++)
+ {
+ if(queryParam)
+ {
+ queryParam += "&";
+ }
+ else
+ {
+ queryParam = "?";
+ }
+ queryParam += "id=" + data[i].id;
+ }
+ var query = url + queryParam;
+ var success = true
+ var failureReason = "";
+ xhr.del({url: query, sync: true, handleAs: "json"}).then(
+ function(data)
+ {
+ grid.setQuery({id: "*"});
+ grid.selection.deselectAll();
+ updater.update();
+ },
+ function(error) {success = false; failureReason = error;});
+ if(!success )
+ {
+ alert("Error:" + failureReason);
+ }
+ }
+ }
+ }
+
return util;
}); \ No newline at end of file
diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/Exchange.js b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/Exchange.js
index 0450ef53ac..37bae1ef8e 100644
--- a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/Exchange.js
+++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/Exchange.js
@@ -29,8 +29,9 @@ define(["dojo/_base/xhr",
"qpid/common/formatter",
"qpid/common/UpdatableStore",
"qpid/management/addBinding",
+ "dojox/grid/EnhancedGrid",
"dojo/domReady!"],
- function (xhr, parser, query, connect, registry, properties, updater, util, formatter, UpdatableStore, addBinding) {
+ function (xhr, parser, query, connect, registry, properties, updater, util, formatter, UpdatableStore, addBinding, EnhancedGrid) {
function Exchange(name, parent, controller) {
this.name = name;
@@ -82,6 +83,27 @@ define(["dojo/_base/xhr",
exchange: that.getExchangeName()});
});
+ var deleteBindingButton = query(".deleteBindingButton", contentPane.containerNode)[0];
+ connect.connect(registry.byNode(deleteBindingButton), "onClick",
+ function(evt){
+ that.deleteBindings();
+ });
+
+ var isStandard = util.isReservedExchangeName(that.name);
+ var deleteExchangeButton = query(".deleteExchangeButton", contentPane.containerNode)[0];
+ var node = registry.byNode(deleteExchangeButton);
+ if(isStandard)
+ {
+ node.set('disabled', true);
+ }
+ else
+ {
+ connect.connect(node, "onClick",
+ function(evt){
+ that.deleteExchange();
+ });
+ }
+
}});
};
@@ -89,6 +111,15 @@ define(["dojo/_base/xhr",
updater.remove( this.exchangeUpdater );
};
+ Exchange.prototype.deleteBindings = function()
+ {
+ util.deleteGridSelections(
+ this.exchangeUpdater,
+ "bindingsGrid",
+ "rest/binding/"+ encodeURIComponent(this.getVirtualHostName()) + "/" + encodeURIComponent(this.name),
+ "Are you sure you want to delete binding for queue");
+ }
+
function ExchangeUpdater(containerNode, exchangeObj, controller)
{
var that = this;
@@ -138,7 +169,21 @@ define(["dojo/_base/xhr",
[ { name: "Queue", field: "queue", width: "90px"},
{ name: "Binding Key", field: "name", width: "120px"},
{ name: "Arguments", field: "argumentString", width: "100%"}
- ]);
+ ], null, {
+ keepSelection: true,
+ plugins: {
+ pagination: {
+ pageSizes: ["10", "25", "50", "100"],
+ description: true,
+ sizeSwitch: true,
+ pageStepper: true,
+ gotoButton: true,
+ maxPageStep: 4,
+ position: "bottom"
+ },
+ indirectSelection: true
+
+ }}, EnhancedGrid);
});
@@ -224,6 +269,23 @@ define(["dojo/_base/xhr",
});
};
+ Exchange.prototype.deleteExchange = function() {
+ if(confirm("Are you sure you want to delete exchange '" +this.name+"'?")) {
+ var query = "rest/exchange/"+ encodeURIComponent(this.getVirtualHostName()) + "/" + encodeURIComponent(this.name);
+ this.success = true
+ var that = this;
+ xhr.del({url: query, sync: true, handleAs: "json"}).then(
+ function(data) {
+ that.contentPane.onClose()
+ that.controller.tabContainer.removeChild(that.contentPane);
+ that.contentPane.destroyRecursive();
+ },
+ function(error) {that.success = false; that.failureReason = error;});
+ if(!this.success ) {
+ alert("Error:" + this.failureReason);
+ }
+ }
+ }
return Exchange;
});
diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/Queue.js b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/Queue.js
index 3ac8b0057d..b812ca2a0b 100644
--- a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/Queue.js
+++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/Queue.js
@@ -157,6 +157,12 @@ define(["dojo/_base/xhr",
queue: that.getQueueName()});
});
+ var deleteQueueButton = query(".deleteQueueButton", contentPane.containerNode)[0];
+ connect.connect(registry.byNode(deleteQueueButton), "onClick",
+ function(evt){
+ event.stop(evt);
+ that.deleteQueue();
+ });
}});
@@ -458,6 +464,23 @@ define(["dojo/_base/xhr",
});
};
+ Queue.prototype.deleteQueue = function() {
+ if(confirm("Are you sure you want to delete queue '" +this.name+"'?")) {
+ var query = "rest/queue/"+ encodeURIComponent(this.getVirtualHostName()) + "/" + encodeURIComponent(this.name);
+ this.success = true
+ var that = this;
+ xhr.del({url: query, sync: true, handleAs: "json"}).then(
+ function(data) {
+ that.contentPane.onClose()
+ that.controller.tabContainer.removeChild(that.contentPane);
+ that.contentPane.destroyRecursive();
+ },
+ function(error) {that.success = false; that.failureReason = error;});
+ if(!this.success ) {
+ alert("Error:" + this.failureReason);
+ }
+ }
+ }
return Queue;
});
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 ce24145930..957f2381cf 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
@@ -30,8 +30,9 @@ define(["dojo/_base/xhr",
"qpid/common/UpdatableStore",
"qpid/management/addQueue",
"qpid/management/addExchange",
+ "dojox/grid/EnhancedGrid",
"dojo/domReady!"],
- function (xhr, parser, query, connect, registry, properties, updater, util, formatter, UpdatableStore, addQueue, addExchange) {
+ function (xhr, parser, query, connect, registry, properties, updater, util, formatter, UpdatableStore, addQueue, addExchange, EnhancedGrid) {
function VirtualHost(name, parent, controller) {
this.name = name;
@@ -66,8 +67,31 @@ define(["dojo/_base/xhr",
var addQueueButton = query(".addQueueButton", contentPane.containerNode)[0];
connect.connect(registry.byNode(addQueueButton), "onClick", function(evt){ addQueue.show(that.name) });
+ var deleteQueueButton = query(".deleteQueueButton", contentPane.containerNode)[0];
+ connect.connect(registry.byNode(deleteQueueButton), "onClick",
+ function(evt){
+ util.deleteGridSelections(
+ that.vhostUpdater,
+ "queuesGrid",
+ "rest/queue/"+ encodeURIComponent(that.name),
+ "Are you sure you want to delete queue");
+ }
+ );
+
var addExchangeButton = query(".addExchangeButton", contentPane.containerNode)[0];
connect.connect(registry.byNode(addExchangeButton), "onClick", function(evt){ addExchange.show(that.name) });
+
+ var deleteExchangeButton = query(".deleteExchangeButton", contentPane.containerNode)[0];
+ connect.connect(registry.byNode(deleteExchangeButton), "onClick",
+ function(evt)
+ {
+ util.deleteGridSelections(
+ that.vhostUpdater,
+ "exchangesGrid",
+ "rest/exchange/"+ encodeURIComponent(that.name),
+ "Are you sure you want to delete exchange");
+ }
+ );
}});
};
@@ -76,7 +100,6 @@ define(["dojo/_base/xhr",
updater.remove( this.vhostUpdater );
};
-
function Updater(node, vhost, controller)
{
@@ -123,6 +146,22 @@ define(["dojo/_base/xhr",
// flatten statistics into attributes
util.flattenStatistics( that.vhostData );
+ var gridProperties = {
+ keepSelection: true,
+ plugins: {
+ pagination: {
+ pageSizes: ["10", "25", "50", "100"],
+ description: true,
+ sizeSwitch: true,
+ pageStepper: true,
+ gotoButton: true,
+ maxPageStep: 4,
+ position: "bottom"
+ },
+ indirectSelection: true
+
+ }};
+
that.updateHeader();
that.queuesGrid = new UpdatableStore(that.vhostData.queues, findNode("queues"),
[ { name: "Name", field: "name", width: "90px"},
@@ -138,24 +177,24 @@ define(["dojo/_base/xhr",
var queueName = obj.dataStore.getValue(theItem,"name");
controller.show("queue", queueName, vhost);
});
- } );
+ } , gridProperties, EnhancedGrid);
that.exchangesGrid = new UpdatableStore(that.vhostData.exchanges, findNode("exchanges"),
- [ { name: "Name", field: "name", width: "120px"},
- { name: "Type", field: "type", width: "120px"},
- { name: "Binding Count", field: "bindingCount",
- width: "100%"}
+ [
+ { name: "Name", field: "name", width: "120px"},
+ { name: "Type", field: "type", width: "120px"},
+ { name: "Binding Count", field: "bindingCount", width: "100%"}
],
function(obj)
{
connect.connect(obj.grid, "onRowDblClick", obj.grid,
function(evt){
var idx = evt.rowIndex,
- theItem = this.getItem(idx);
+ theItem = this.getItem(idx);
var exchangeName = obj.dataStore.getValue(theItem,"name");
controller.show("exchange", exchangeName, vhost);
});
- } );
+ } , gridProperties, EnhancedGrid);
that.connectionsGrid = new UpdatableStore(that.vhostData.connections,
@@ -315,6 +354,18 @@ define(["dojo/_base/xhr",
// update exchanges
thisObj.exchangesGrid.update(thisObj.vhostData.exchanges);
+ var exchangesGrid = thisObj.exchangesGrid.grid;
+ for(var i=0; i< thisObj.vhostData.exchanges.length; i++)
+ {
+ var data = exchangesGrid.getItem(i);
+ var isStandard = false;
+ if (data && data.name)
+ {
+ isStandard = util.isReservedExchangeName(data.name);
+ }
+ exchangesGrid.rowSelectCell.setDisabled(i, isStandard);
+ }
+
// update connections
thisObj.connectionsGrid.update(thisObj.vhostData.connections)
diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/addExchange.js b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/addExchange.js
index f88daa54bb..915092a9d1 100644
--- a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/addExchange.js
+++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/addExchange.js
@@ -109,7 +109,6 @@ define(["dojo/_base/xhr",
var newExchange = convertToExchange(theForm.getValues());
var that = this;
-
xhr.put({url: "rest/exchange/"+encodeURIComponent(addExchange.vhost) +
"/"+encodeURIComponent(newExchange.name), sync: true, handleAs: "json",
headers: { "Content-Type": "application/json"},
diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/showExchange.html b/qpid/java/broker-plugins/management-http/src/main/java/resources/showExchange.html
index b0aa302782..f33b029026 100644
--- a/qpid/java/broker-plugins/management-http/src/main/java/resources/showExchange.html
+++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/showExchange.html
@@ -41,6 +41,10 @@
<div data-dojo-type="dijit.TitlePane" data-dojo-props="title: 'Bindings'">
<div class="bindings"></div>
<button data-dojo-type="dijit.form.Button" class="addBindingButton">Add Binding</button>
+ <button data-dojo-type="dijit.form.Button" class="deleteBindingButton">Delete Binding</button>
</div>
<br/>
+ <div class="dijitDialogPaneActionBar">
+ <button data-dojo-type="dijit.form.Button" class="deleteExchangeButton" type="button">Delete Exchange</button>
+ </div>
</div>
diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/showQueue.html b/qpid/java/broker-plugins/management-http/src/main/java/resources/showQueue.html
index 3be53a45a2..f4960055b0 100644
--- a/qpid/java/broker-plugins/management-http/src/main/java/resources/showQueue.html
+++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/showQueue.html
@@ -97,5 +97,9 @@
</div>
+
+ <div class="dijitDialogPaneActionBar">
+ <button data-dojo-type="dijit.form.Button" class="deleteQueueButton" type="button">Delete Queue</button>
+ </div>
</div>
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 9d16d523d6..f4d998458f 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
@@ -43,11 +43,13 @@
<div data-dojo-type="dijit.TitlePane" data-dojo-props="title: 'Exchanges'">
<div class="exchanges"></div>
<button data-dojo-type="dijit.form.Button" class="addExchangeButton">Add Exchange</button>
+ <button data-dojo-type="dijit.form.Button" class="deleteExchangeButton">Delete Exchange</button>
</div>
<br/>
<div data-dojo-type="dijit.TitlePane" data-dojo-props="title: 'Queues'">
<div class="queues"></div>
<button data-dojo-type="dijit.form.Button" class="addQueueButton">Add Queue</button>
+ <button data-dojo-type="dijit.form.Button" class="deleteQueueButton">Delete Queue</button>
</div>
<br/>
<div data-dojo-type="dijit.TitlePane" data-dojo-props="title: 'Connections'">
diff --git a/qpid/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/BindingRestTest.java b/qpid/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/BindingRestTest.java
index 91b41c3476..527eb16927 100644
--- a/qpid/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/BindingRestTest.java
+++ b/qpid/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/BindingRestTest.java
@@ -1,5 +1,6 @@
package org.apache.qpid.server.management.plugin.servlet.rest;
+import java.net.HttpURLConnection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -61,4 +62,48 @@ public class BindingRestTest extends QpidRestTestCase
Asserts.assertBinding("queue", "amq.direct", bindings.get(0));
}
+
+ public void testDeleteBinding() throws Exception
+ {
+ List<Map<String, Object>> bindings = getJsonAsList("/rest/binding/test/amq.direct/queue/queue");
+ assertEquals("Unexpected number of bindings", 1, bindings.size());
+ Asserts.assertBinding("queue", "amq.direct", bindings.get(0));
+
+ HttpURLConnection connection = openManagementConection("/rest/binding/test/amq.direct/queue/queue", "DELETE");
+ connection.connect();
+ assertEquals("Unexpected response code", 200, connection.getResponseCode());
+
+ bindings = getJsonAsList("/rest/binding/test/amq.direct/queue/queue");
+ assertEquals("Binding should be deleted", 0, bindings.size());
+ }
+
+ public void testDeleteBindingById() throws Exception
+ {
+ Map<String, Object> binding = getJsonAsSingletonList("/rest/binding/test/amq.direct/queue");
+ HttpURLConnection connection = openManagementConection("/rest/binding/test/amq.direct?id=" + binding.get(Binding.ID), "DELETE");
+ connection.connect();
+ assertEquals("Unexpected response code", 200, connection.getResponseCode());
+ List<Map<String, Object>> bindings = getJsonAsList("/rest/binding/test/amq.direct/queue");
+ assertEquals("Binding should be deleted", 0, bindings.size());
+ }
+
+ public void testCreateBinding() throws Exception
+ {
+ String bindingName = getTestName();
+ Map<String, Object> bindingData = new HashMap<String, Object>();
+ bindingData.put(Binding.NAME, bindingName);
+ bindingData.put(Binding.QUEUE, "queue");
+ bindingData.put(Binding.EXCHANGE, "amq.direct");
+
+ HttpURLConnection connection = openManagementConection("/rest/binding/test/amq.direct/queue/" + bindingName, "PUT");
+ connection.connect();
+ writeJsonRequest(connection, bindingData);
+ int responseCode = connection.getResponseCode();
+ connection.disconnect();
+ assertEquals("Unexpected response code", 201, responseCode);
+ Map<String, Object> binding = getJsonAsSingletonList("/rest/binding/test/amq.direct/queue/" + bindingName);
+
+ Asserts.assertBinding(bindingName, "queue", "amq.direct", binding);
+ }
+
}
diff --git a/qpid/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/VirtualHostRestTest.java b/qpid/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/VirtualHostRestTest.java
index 71e85d389e..eaf2e60478 100644
--- a/qpid/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/VirtualHostRestTest.java
+++ b/qpid/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/VirtualHostRestTest.java
@@ -246,6 +246,56 @@ public class VirtualHostRestTest extends QpidRestTestCase
assertNull("Queue of unsupported type was created", queue);
}
+ public void testDeleteQueue() throws Exception
+ {
+ String queueName = getTestQueueName();
+ createQueue(queueName, null, null);
+
+ HttpURLConnection connection = openManagementConection("/rest/queue/test/" + queueName, "DELETE");
+ connection.connect();
+ assertEquals("Unexpected response code", 200, connection.getResponseCode());
+ List<Map<String, Object>> queues = getJsonAsList("/rest/queue/test/" + queueName);
+ assertEquals("Queue should be deleted", 0, queues.size());
+ }
+
+ public void testDeleteQueueById() throws Exception
+ {
+ String queueName = getTestQueueName();
+ createQueue(queueName, null, null);
+ Map<String, Object> queueDetails = getJsonAsSingletonList("/rest/queue/test/" + queueName);
+
+ HttpURLConnection connection = openManagementConection("/rest/queue/test?id=" + queueDetails.get(Queue.ID), "DELETE");
+ connection.connect();
+ assertEquals("Unexpected response code", 200, connection.getResponseCode());
+ List<Map<String, Object>> queues = getJsonAsList("/rest/queue/test/" + queueName);
+ assertEquals("Queue should be deleted", 0, queues.size());
+ }
+
+ public void testDeleteExchange() throws Exception
+ {
+ String exchangeName = getTestName();
+ createExchange(exchangeName, "direct");
+
+ HttpURLConnection connection = openManagementConection("/rest/exchange/test/" + exchangeName, "DELETE");
+ connection.connect();
+ assertEquals("Unexpected response code", 200, connection.getResponseCode());
+ List<Map<String, Object>> queues = getJsonAsList("/rest/exchange/test/" + exchangeName);
+ assertEquals("Exchange should be deleted", 0, queues.size());
+ }
+
+ public void testDeleteExchangeById() throws Exception
+ {
+ String exchangeName = getTestName();
+ createExchange(exchangeName, "direct");
+ Map<String, Object> echangeDetails = getJsonAsSingletonList("/rest/exchange/test/" + exchangeName);
+
+ HttpURLConnection connection = openManagementConection("/rest/exchange/test?id=" + echangeDetails.get(Exchange.ID), "DELETE");
+ connection.connect();
+ assertEquals("Unexpected response code", 200, connection.getResponseCode());
+ List<Map<String, Object>> queues = getJsonAsList("/rest/exchange/test/" + exchangeName);
+ assertEquals("Exchange should be deleted", 0, queues.size());
+ }
+
private void createExchange(String exchangeName, String exchangeType) throws IOException
{
HttpURLConnection connection = openManagementConection("/rest/exchange/test/" + exchangeName, "PUT");
diff --git a/qpid/java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/systest/management/jmx/BrokerManagementTest.java b/qpid/java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/systest/management/jmx/BrokerManagementTest.java
index 2c341b7f2e..7473a4d3e7 100644
--- a/qpid/java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/systest/management/jmx/BrokerManagementTest.java
+++ b/qpid/java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/systest/management/jmx/BrokerManagementTest.java
@@ -24,9 +24,6 @@ import org.apache.qpid.management.common.mbeans.ManagedExchange;
import org.apache.qpid.test.utils.JMXTestUtils;
import org.apache.qpid.test.utils.QpidBrokerTestCase;
-import javax.management.MBeanException;
-import javax.management.ObjectName;
-
/**
* Tests the JMX API for the Managed Broker.
*
@@ -115,11 +112,10 @@ public class BrokerManagementTest extends QpidBrokerTestCase
_managedBroker.unregisterExchange(defaultExchangeName);
fail("Exception not thrown");
}
- catch (MBeanException mbe)
+ catch (UnsupportedOperationException e)
{
// PASS
- assertEquals("Error in unregistering exchange " + defaultExchangeName, mbe.getMessage());
- assertTrue(mbe.getCause().getMessage().contains("Cannot unregister the default exchange"));
+ assertEquals("'<<default>>' is a reserved exchange and can't be deleted", e.getMessage());
}
final ManagedExchange defaultExchange = _jmxUtils.getManagedExchange(defaultExchangeName);
assertNotNull("Exchange should exist", defaultExchange);
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/DefaultExchangeRegistry.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/DefaultExchangeRegistry.java
index baf9cc3d09..07813b073b 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/DefaultExchangeRegistry.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/DefaultExchangeRegistry.java
@@ -225,4 +225,21 @@ public class DefaultExchangeRegistry implements ExchangeRegistry
}
}
+ public boolean isReservedExchangeName(String name)
+ {
+ if (name == null || "".equals(name) || ExchangeDefaults.DEFAULT_EXCHANGE_NAME.asString().equals(name)
+ || name.startsWith("amq.") || name.startsWith("qpid."))
+ {
+ return true;
+ }
+ Collection<ExchangeType<? extends Exchange>> registeredTypes = _host.getExchangeFactory().getRegisteredTypes();
+ for (ExchangeType<? extends Exchange> type : registeredTypes)
+ {
+ if (type.getDefaultExchangeName().toString().equals(name))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/ExchangeRegistry.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/ExchangeRegistry.java
index 692a2b2b0d..4dcedb4797 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/ExchangeRegistry.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/ExchangeRegistry.java
@@ -62,6 +62,13 @@ public interface ExchangeRegistry
void addRegistryChangeListener(RegistryChangeListener listener);
+ /**
+ * Validates the name of user custom exchange.
+ * <p>
+ * Return true if the exchange name is reserved and false otherwise.
+ */
+ boolean isReservedExchangeName(String name);
+
interface RegistryChangeListener
{
void exchangeRegistered(Exchange exchange);
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 53faefc954..24a3d43386 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
@@ -131,8 +131,6 @@ public interface VirtualHost extends ConfiguredObject
boolean exclusive, LifetimePolicy lifetime, long ttl, Map<String, Object> attributes)
throws AccessControlException, IllegalArgumentException;
- void deleteQueue(Queue queue) throws AccessControlException, IllegalStateException;
-
Collection<String> getExchangeTypes();
public static interface Transaction
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/BindingAdapter.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/BindingAdapter.java
index f041494781..abd3160686 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/BindingAdapter.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/BindingAdapter.java
@@ -31,6 +31,7 @@ import org.apache.qpid.AMQSecurityException;
import org.apache.qpid.server.model.Binding;
import org.apache.qpid.server.model.ConfiguredObject;
import org.apache.qpid.server.model.Exchange;
+import org.apache.qpid.server.model.IllegalStateTransitionException;
import org.apache.qpid.server.model.LifetimePolicy;
import org.apache.qpid.server.model.Queue;
import org.apache.qpid.server.model.State;
@@ -216,4 +217,16 @@ final class BindingAdapter extends AbstractAdapter implements Binding
{
return Binding.AVAILABLE_ATTRIBUTES;
}
+
+ @Override
+ public State setDesiredState(State currentState, State desiredState) throws IllegalStateTransitionException,
+ AccessControlException
+ {
+ if (desiredState == State.DELETED)
+ {
+ delete();
+ return State.DELETED;
+ }
+ return super.setDesiredState(currentState, desiredState);
+ }
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/ExchangeAdapter.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/ExchangeAdapter.java
index c0d85845d6..df0f29fbc3 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/ExchangeAdapter.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/ExchangeAdapter.java
@@ -30,9 +30,13 @@ import java.util.Map;
import org.apache.qpid.AMQException;
import org.apache.qpid.AMQInternalException;
import org.apache.qpid.AMQSecurityException;
+import org.apache.qpid.protocol.AMQConstant;
import org.apache.qpid.server.binding.Binding;
+import org.apache.qpid.server.exchange.ExchangeRegistry;
+import org.apache.qpid.server.exchange.ExchangeType;
import org.apache.qpid.server.model.ConfiguredObject;
import org.apache.qpid.server.model.Exchange;
+import org.apache.qpid.server.model.IllegalStateTransitionException;
import org.apache.qpid.server.model.LifetimePolicy;
import org.apache.qpid.server.model.Publisher;
import org.apache.qpid.server.model.Queue;
@@ -50,7 +54,6 @@ final class ExchangeAdapter extends AbstractAdapter implements Exchange, org.apa
private VirtualHostAdapter _vhost;
private final ExchangeStatistics _statistics;
-
public ExchangeAdapter(final VirtualHostAdapter virtualHostAdapter,
final org.apache.qpid.server.exchange.Exchange exchange)
{
@@ -164,7 +167,21 @@ final class ExchangeAdapter extends AbstractAdapter implements Exchange, org.apa
{
try
{
- _vhost.getVirtualHost().getExchangeRegistry().unregisterExchange(getName(), false);
+ ExchangeRegistry exchangeRegistry = _vhost.getVirtualHost().getExchangeRegistry();
+ if (exchangeRegistry.isReservedExchangeName(getName()))
+ {
+ throw new UnsupportedOperationException("'" + getName() + "' is a reserved exchange and can't be deleted");
+ }
+
+ if(_exchange.hasReferrers())
+ {
+ throw new AMQException( AMQConstant.NOT_ALLOWED, "Exchange in use as an alternate exchange", null);
+ }
+
+ synchronized(exchangeRegistry)
+ {
+ exchangeRegistry.unregisterExchange(getName(), false);
+ }
}
catch(AMQException e)
{
@@ -364,6 +381,18 @@ final class ExchangeAdapter extends AbstractAdapter implements Exchange, org.apa
return AVAILABLE_ATTRIBUTES;
}
+ @Override
+ public State setDesiredState(State currentState, State desiredState) throws IllegalStateTransitionException,
+ AccessControlException
+ {
+ if (desiredState == State.DELETED)
+ {
+ delete();
+ return State.DELETED;
+ }
+ return super.setDesiredState(currentState, desiredState);
+ }
+
private class ExchangeStatistics implements Statistics
{
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/QueueAdapter.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/QueueAdapter.java
index 21c4aef323..5a5f7435a2 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/QueueAdapter.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/QueueAdapter.java
@@ -27,6 +27,7 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
+
import org.apache.qpid.AMQException;
import org.apache.qpid.AMQStoreException;
import org.apache.qpid.server.binding.Binding;
@@ -34,6 +35,7 @@ import org.apache.qpid.server.model.ConfiguredObject;
import org.apache.qpid.server.model.ConfiguredObjectFinder;
import org.apache.qpid.server.model.Consumer;
import org.apache.qpid.server.model.Exchange;
+import org.apache.qpid.server.model.IllegalStateTransitionException;
import org.apache.qpid.server.model.LifetimePolicy;
import org.apache.qpid.server.model.Queue;
import org.apache.qpid.server.model.QueueNotificationListener;
@@ -130,11 +132,14 @@ final class QueueAdapter extends AbstractAdapter implements Queue, AMQQueue.Subs
{
try
{
- _queue.delete();
- if (_queue.isDurable())
+ QueueRegistry queueRegistry = _queue.getVirtualHost().getQueueRegistry();
+ synchronized(queueRegistry)
{
-
- _queue.getVirtualHost().getMessageStore().removeQueue(_queue);
+ _queue.delete();
+ if (_queue.isDurable())
+ {
+ _queue.getVirtualHost().getMessageStore().removeQueue(_queue);
+ }
}
}
catch(AMQException e)
@@ -705,4 +710,17 @@ final class QueueAdapter extends AbstractAdapter implements Queue, AMQQueue.Subs
listener.notifyClients(notification, this, notificationMsg);
}
}
+
+ @Override
+ public State setDesiredState(State currentState, State desiredState) throws IllegalStateTransitionException,
+ AccessControlException
+ {
+ if (desiredState == State.DELETED)
+ {
+ delete();
+ return State.DELETED;
+ }
+ return super.setDesiredState(currentState, desiredState);
+ }
+
}
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 bcfdb22fa9..35838e51d2 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
@@ -228,18 +228,29 @@ final class VirtualHostAdapter extends AbstractAdapter implements VirtualHost, E
try
{
- org.apache.qpid.server.exchange.Exchange exchange =
- _virtualHost.getExchangeFactory().createExchange(name, type, durable,
- lifetime == LifetimePolicy.AUTO_DELETE);
- _virtualHost.getExchangeRegistry().registerExchange(exchange);
- if(durable)
+ ExchangeRegistry exchangeRegistry = _virtualHost.getExchangeRegistry();
+ if (exchangeRegistry.isReservedExchangeName(name))
{
- _virtualHost.getMessageStore().createExchange(exchange);
+ throw new UnsupportedOperationException("'" + name + "' is a reserved exchange name");
}
-
- synchronized (_exchangeAdapters)
+ synchronized(exchangeRegistry)
{
- return _exchangeAdapters.get(exchange);
+ org.apache.qpid.server.exchange.Exchange exchange = exchangeRegistry.getExchange(name);
+ if (exchange != null)
+ {
+ throw new IllegalArgumentException("Exchange with name '" + name + "' already exists");
+ }
+ exchange = _virtualHost.getExchangeFactory().createExchange(name, type, durable,
+ lifetime == LifetimePolicy.AUTO_DELETE);
+ _virtualHost.getExchangeRegistry().registerExchange(exchange);
+ if(durable)
+ {
+ _virtualHost.getMessageStore().createExchange(exchange);
+ }
+ synchronized (_exchangeAdapters)
+ {
+ return _exchangeAdapters.get(exchange);
+ }
}
}
catch(AMQException e)
@@ -326,23 +337,27 @@ final class VirtualHostAdapter extends AbstractAdapter implements VirtualHost, E
}
try
{
- if(_virtualHost.getQueueRegistry().getQueue(name)!=null)
+ QueueRegistry queueRegistry = _virtualHost.getQueueRegistry();
+ synchronized (queueRegistry)
{
- throw new IllegalArgumentException("Queue with name "+name+" already exists");
- }
- AMQQueue queue =
- AMQQueueFactory.createAMQQueueImpl(UUIDGenerator.generateQueueUUID(name, _virtualHost.getName()), name,
- durable, owner, lifetime == LifetimePolicy.AUTO_DELETE,
- exclusive, _virtualHost, attributes);
- _virtualHost.getBindingFactory().addBinding(name, queue, _virtualHost.getExchangeRegistry().getDefaultExchange(), null);
+ if(_virtualHost.getQueueRegistry().getQueue(name)!=null)
+ {
+ throw new IllegalArgumentException("Queue with name "+name+" already exists");
+ }
+ AMQQueue queue =
+ AMQQueueFactory.createAMQQueueImpl(UUIDGenerator.generateQueueUUID(name, _virtualHost.getName()), name,
+ durable, owner, lifetime == LifetimePolicy.AUTO_DELETE,
+ exclusive, _virtualHost, attributes);
+ _virtualHost.getBindingFactory().addBinding(name, queue, _virtualHost.getExchangeRegistry().getDefaultExchange(), null);
- if(durable)
- {
- _virtualHost.getMessageStore().createQueue(queue, FieldTable.convertToFieldTable(attributes));
- }
- synchronized (_queueAdapters)
- {
- return _queueAdapters.get(queue);
+ if(durable)
+ {
+ _virtualHost.getMessageStore().createQueue(queue, FieldTable.convertToFieldTable(attributes));
+ }
+ synchronized (_queueAdapters)
+ {
+ return _queueAdapters.get(queue);
+ }
}
}
@@ -569,13 +584,6 @@ final class VirtualHostAdapter extends AbstractAdapter implements VirtualHost, E
}
}
- public void deleteQueue(Queue queue)
- throws AccessControlException, IllegalStateException
- {
- // TODO
- throw new UnsupportedOperationException("Not Yet Implemented");
- }
-
public Collection<String> getExchangeTypes()
{
Collection<ExchangeType<? extends org.apache.qpid.server.exchange.Exchange>> types =
@@ -880,4 +888,5 @@ final class VirtualHostAdapter extends AbstractAdapter implements VirtualHost, E
}
}
}
+
}