summaryrefslogtreecommitdiff
path: root/java/broker-plugins
diff options
context:
space:
mode:
Diffstat (limited to 'java/broker-plugins')
-rw-r--r--java/broker-plugins/access-control/MANIFEST.MF41
-rw-r--r--java/broker-plugins/access-control/build.xml6
-rw-r--r--java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/AbstractConfiguration.java7
-rw-r--r--java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/AclAction.java102
-rw-r--r--java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/AclRulePredicates.java102
-rw-r--r--java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/Action.java114
-rw-r--r--java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/ClientAction.java88
-rw-r--r--java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/ConfigurationFile.java12
-rw-r--r--java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/PlainConfiguration.java184
-rw-r--r--java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/Rule.java44
-rw-r--r--java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/RuleSet.java113
-rw-r--r--java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/firewall/AccessControlFirewallException.java (renamed from java/broker-plugins/firewall/src/main/java/org/apache/qpid/server/security/access/config/FirewallException.java)25
-rw-r--r--java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/firewall/FirewallRule.java (renamed from java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/AccessControlActivator.java)27
-rw-r--r--java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/firewall/FirewallRuleFactory.java (renamed from java/broker-plugins/firewall/src/main/java/org/apache/qpid/server/security/access/plugins/FirewallActivator.java)26
-rw-r--r--java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/firewall/HostnameFirewallRule.java156
-rw-r--r--java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/firewall/InetNetwork.java177
-rw-r--r--java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/firewall/NetworkFirewallRule.java117
-rw-r--r--java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/logging/AccessControl_logmessages.properties2
-rw-r--r--java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/AccessControlConfiguration.java83
-rw-r--r--java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/DefaultAccessControl.java (renamed from java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/AccessControl.java)96
-rw-r--r--java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/DefaultAccessControlFactory.java59
-rw-r--r--java/broker-plugins/access-control/src/main/resources/META-INF/services/org.apache.qpid.server.plugin.AccessControlFactory19
-rw-r--r--java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/config/AclActionTest.java66
-rw-r--r--java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/config/AclRulePredicatesTest.java87
-rw-r--r--java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/config/ActionTest.java95
-rw-r--r--java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/config/ClientActionTest.java79
-rw-r--r--java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/config/PlainConfigurationTest.java (renamed from java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/PlainConfigurationTest.java)117
-rw-r--r--java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/config/RuleTest.java53
-rw-r--r--java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/firewall/HostnameFirewallRuleTest.java99
-rw-r--r--java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/firewall/NetworkFirewallRuleTest.java115
-rw-r--r--java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/DefaultAccessControlFactoryTest.java69
-rw-r--r--java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/DefaultAccessControlTest.java (renamed from java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/AccessControlTest.java)127
-rw-r--r--java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/RuleSetTest.java92
-rw-r--r--java/broker-plugins/firewall/MANIFEST.MF34
-rw-r--r--java/broker-plugins/firewall/src/main/java/org/apache/qpid/server/security/access/config/FirewallRule.java136
-rw-r--r--java/broker-plugins/firewall/src/main/java/org/apache/qpid/server/security/access/plugins/Firewall.java137
-rw-r--r--java/broker-plugins/firewall/src/main/java/org/apache/qpid/server/security/access/plugins/FirewallConfiguration.java103
-rw-r--r--java/broker-plugins/firewall/src/test/java/org/apache/qpid/server/security/access/FirewallConfigurationTest.java322
-rw-r--r--java/broker-plugins/firewall/src/test/java/org/apache/qpid/server/security/access/FirewallPluginTest.java294
-rw-r--r--java/broker-plugins/management-http/MANIFEST.MF70
-rw-r--r--java/broker-plugins/management-http/build.xml51
-rw-r--r--java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagement.java416
-rw-r--r--java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagementFactory.java (renamed from java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/systest/management/jmx/UserManagementWithBase64MD5PasswordsTest.java)28
-rw-r--r--java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/Management.java248
-rw-r--r--java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/ManagementActivator.java73
-rw-r--r--java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/ManagementConfiguration.java77
-rw-r--r--java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/DefinedFileServlet.java2
-rw-r--r--java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/FileServlet.java5
-rw-r--r--java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/api/ExchangesServlet.java208
-rw-r--r--java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/api/VhostsServlet.java118
-rw-r--r--java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/AbstractServlet.java447
-rw-r--r--java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/LogRecordsServlet.java15
-rw-r--r--java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/LogoutServlet.java65
-rw-r--r--java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/MessageContentServlet.java8
-rw-r--r--java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/MessageServlet.java41
-rw-r--r--java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/RestServlet.java38
-rw-r--r--java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/SaslServlet.java95
-rw-r--r--java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/StructureServlet.java9
-rw-r--r--java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/session/LoginLogoutReporter.java103
-rw-r--r--java/broker-plugins/management-http/src/main/java/resources/authenticationprovider/showPrincipalDatabaseAuthenticationManager.html2
-rw-r--r--java/broker-plugins/management-http/src/main/java/resources/group/addGroupMember.html37
-rw-r--r--java/broker-plugins/management-http/src/main/java/resources/group/showGroup.html (renamed from java/broker-plugins/firewall/build.xml)30
-rw-r--r--java/broker-plugins/management-http/src/main/java/resources/groupprovider/addGroup.html38
-rw-r--r--java/broker-plugins/management-http/src/main/java/resources/groupprovider/showFileGroupManager.html28
-rw-r--r--java/broker-plugins/management-http/src/main/java/resources/index.html (renamed from java/broker-plugins/management-http/src/main/java/resources/management.html)6
-rw-r--r--java/broker-plugins/management-http/src/main/java/resources/js/qpid/authorization/sasl.js59
-rw-r--r--java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/util.js7
-rw-r--r--java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/Exchange.js2
-rw-r--r--java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/GroupProvider.js109
-rw-r--r--java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/VirtualHost.js4
-rw-r--r--java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/controller.js8
-rw-r--r--java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/group/Group.js204
-rw-r--r--java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/group/addGroupMember.js108
-rw-r--r--java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/groupprovider/FileGroupManager.js251
-rw-r--r--java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/treeView.js6
-rw-r--r--java/broker-plugins/management-http/src/main/java/resources/showGroupProvider.html25
-rw-r--r--java/broker-plugins/management-http/src/main/resources/META-INF/services/org.apache.qpid.server.plugin.PluginFactory19
-rw-r--r--java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/HttpManagementFactoryTest.java61
-rw-r--r--java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/Asserts.java249
-rw-r--r--java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/AuthenticationProviderRestTest.java73
-rw-r--r--java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/BindingRestTest.java129
-rw-r--r--java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/BrokerRestHttpsTest.java86
-rw-r--r--java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/BrokerRestTest.java118
-rw-r--r--java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/ConnectionRestTest.java213
-rw-r--r--java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/ExchangeRestTest.java87
-rw-r--r--java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/LogRecordsRestTest.java42
-rw-r--r--java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/MessagesRestTest.java354
-rw-r--r--java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/PortRestTest.java61
-rw-r--r--java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/QpidRestTestCase.java245
-rw-r--r--java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/QueueRestTest.java225
-rw-r--r--java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/StructureRestTest.java115
-rw-r--r--java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/UserRestTest.java112
-rw-r--r--java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/VirtualHostRestTest.java434
-rw-r--r--java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/session/LoginLogoutReporterTest.java74
-rw-r--r--java/broker-plugins/management-jmx/MANIFEST.MF66
-rw-r--r--java/broker-plugins/management-jmx/build.xml20
-rw-r--r--java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/CustomRMIServerSocketFactory.java68
-rw-r--r--java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXActivator.java136
-rw-r--r--java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXConfiguration.java76
-rw-r--r--java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagedObjectRegistry.java407
-rw-r--r--java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagement.java343
-rw-r--r--java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagementFactory.java (renamed from java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/SaslRestTest.java)37
-rw-r--r--java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXService.java193
-rw-r--r--java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/MBeanInvocationHandlerImpl.java101
-rw-r--r--java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/MBeanProvider.java5
-rw-r--r--java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/ManagementLogonLogoffReporter.java95
-rw-r--r--java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/UsernameAccessor.java26
-rw-r--r--java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/UsernameCachingRMIJRMPServer.java100
-rw-r--r--java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/mbeans/ConfigurationManagementMBean.java56
-rw-r--r--java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/mbeans/LoggingManagementMBean.java53
-rw-r--r--java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/mbeans/QueueMBean.java5
-rw-r--r--java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/mbeans/VirtualHostMBean.java66
-rw-r--r--java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/mbeans/VirtualHostManagerMBean.java5
-rw-r--r--java/broker-plugins/management-jmx/src/main/resources/META-INF/services/org.apache.qpid.server.plugin.PluginFactory19
-rw-r--r--java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/server/jmx/JMXManagementFactoryTest.java60
-rw-r--r--java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/server/jmx/ManagementLogActorTest.java170
-rw-r--r--java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/server/jmx/ManagementLogonLogoffReporterTest.java101
-rw-r--r--java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/server/jmx/mbeans/LoggingManagementMBeanTest.java6
-rw-r--r--java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/systest/management/jmx/BrokerManagementTest.java124
-rw-r--r--java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/systest/management/jmx/ConnectionManagementTest.java283
-rw-r--r--java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/systest/management/jmx/LoggingManagementTest.java149
-rw-r--r--java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/systest/management/jmx/ManagementActorLoggingTest.java480
-rw-r--r--java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/systest/management/jmx/ManagementLoggingTest.java317
-rw-r--r--java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/systest/management/jmx/QueueManagementTest.java696
-rw-r--r--java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/systest/management/jmx/StatisticsTest.java204
-rw-r--r--java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/systest/management/jmx/UserManagementTest.java251
126 files changed, 5226 insertions, 8855 deletions
diff --git a/java/broker-plugins/access-control/MANIFEST.MF b/java/broker-plugins/access-control/MANIFEST.MF
deleted file mode 100644
index a8fb99995e..0000000000
--- a/java/broker-plugins/access-control/MANIFEST.MF
+++ /dev/null
@@ -1,41 +0,0 @@
-Manifest-Version: 1.0
-Bundle-ManifestVersion: 2
-Bundle-Name: Qpid Broker-Plugins Access Control
-Bundle-SymbolicName: broker-plugins-access-control
-Bundle-Description: Access control plugin for Qpid.
-Bundle-License: http://www.apache.org/licenses/LICENSE-2.0.txt
-Bundle-DocURL: http://qpid.apache.org/acl.html
-Bundle-Version: 1.0.0
-Bundle-Activator: org.apache.qpid.server.security.access.plugins.AccessControlActivator
-Bundle-RequiredExecutionEnvironment: JavaSE-1.5
-Bundle-ClassPath: .
-Bundle-ActivationPolicy: lazy
-Import-Package: org.apache.qpid,
- org.apache.qpid.exchange,
- org.apache.qpid.framing,
- org.apache.qpid.protocol,
- org.apache.qpid.server.configuration,
- org.apache.qpid.server.configuration.plugins,
- org.apache.qpid.server.exchange,
- org.apache.qpid.server.logging,
- org.apache.qpid.server.logging.actors,
- org.apache.qpid.server.logging.subjects,
- org.apache.qpid.server.plugins,
- org.apache.qpid.server.queue,
- org.apache.qpid.server.registry,
- org.apache.qpid.server.security,
- org.apache.qpid.server.security.access,
- org.apache.qpid.server.virtualhost,
- org.apache.qpid.util,
- org.apache.commons.configuration;version=1.0.0,
- org.apache.commons.lang;version=1.0.0,
- org.apache.commons.lang.builder;version=1.0.0,
- org.apache.log4j;version=1.0.0,
- javax.management;version=1.0.0,
- javax.management.openmbean;version=1.0.0,
- javax.security.auth;version=1.0.0,
- org.osgi.util.tracker;version=1.0.0,
- org.osgi.framework;version=1.3
-Private-Package: org.apache.qpid.server.security.access.config,
- org.apache.qpid.server.security.access.logging
-Export-Package: org.apache.qpid.server.security.access.plugins
diff --git a/java/broker-plugins/access-control/build.xml b/java/broker-plugins/access-control/build.xml
index df3346788c..4debdcb95a 100644
--- a/java/broker-plugins/access-control/build.xml
+++ b/java/broker-plugins/access-control/build.xml
@@ -18,13 +18,13 @@
-->
<project name="Qpid Broker-Plugins Access Control" default="build">
<property name="module.depends" value="common broker" />
- <property name="module.test.depends" value="test common/test broker/test management/common systests" />
+ <property name="module.test.depends" value="common/tests broker/tests management/common" />
- <property name="module.manifest" value="MANIFEST.MF" />
- <property name="module.plugin" value="true" />
<property name="module.genpom" value="true"/>
<property name="module.genpom.args" value="-Sqpid-common=provided -Sqpid-broker=provided"/>
+ <property name="broker.plugin" value="true"/>
+
<property name="broker-plugins-access-control.libs" value=""/>
<import file="../../module.xml" />
diff --git a/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/AbstractConfiguration.java b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/AbstractConfiguration.java
index f04dd38aca..f87374ac80 100644
--- a/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/AbstractConfiguration.java
+++ b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/AbstractConfiguration.java
@@ -22,13 +22,8 @@ package org.apache.qpid.server.security.access.config;
import java.io.File;
-import org.apache.commons.configuration.ConfigurationException;
-import org.apache.log4j.Logger;
-
public abstract class AbstractConfiguration implements ConfigurationFile
{
- private static final Logger _logger = Logger.getLogger(ConfigurationFile.class);
-
private File _file;
private RuleSet _config;
@@ -42,7 +37,7 @@ public abstract class AbstractConfiguration implements ConfigurationFile
return _file;
}
- public RuleSet load() throws ConfigurationException
+ public RuleSet load()
{
_config = new RuleSet();
return _config;
diff --git a/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/AclAction.java b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/AclAction.java
new file mode 100644
index 0000000000..e4bf21a082
--- /dev/null
+++ b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/AclAction.java
@@ -0,0 +1,102 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.qpid.server.security.access.config;
+
+import org.apache.commons.lang.builder.EqualsBuilder;
+import org.apache.commons.lang.builder.HashCodeBuilder;
+import org.apache.commons.lang.builder.ToStringBuilder;
+import org.apache.commons.lang.builder.ToStringStyle;
+import org.apache.qpid.server.security.access.ObjectProperties;
+import org.apache.qpid.server.security.access.ObjectType;
+import org.apache.qpid.server.security.access.Operation;
+import org.apache.qpid.server.security.access.firewall.FirewallRule;
+
+public class AclAction
+{
+ private Action _action;
+ private FirewallRule _firewallRule;
+
+ public AclAction(Operation operation, ObjectType object, AclRulePredicates predicates)
+ {
+ _action = new Action(operation, object, predicates.getObjectProperties());
+ _firewallRule = predicates.getFirewallRule();
+ }
+
+ public AclAction(Operation operation)
+ {
+ _action = new Action(operation);
+ }
+
+ public AclAction(Operation operation, ObjectType object, ObjectProperties properties)
+ {
+ _action = new Action(operation, object, properties);
+ }
+
+ public FirewallRule getFirewallRule()
+ {
+ return _firewallRule;
+ }
+
+ public Action getAction()
+ {
+ return _action;
+ }
+
+ public boolean isAllowed()
+ {
+ return _action.isAllowed();
+ }
+
+ @Override
+ public int hashCode()
+ {
+ return new HashCodeBuilder()
+ .append(_action)
+ .append(_firewallRule).toHashCode();
+ }
+
+ @Override
+ public boolean equals(Object obj)
+ {
+ if (obj == null)
+ {
+ return false;
+ }
+ if (obj == this)
+ {
+ return true;
+ }
+ if (obj.getClass() != getClass())
+ {
+ return false;
+ }
+ AclAction rhs = (AclAction) obj;
+ return new EqualsBuilder()
+ .append(_action, rhs._action)
+ .append(_firewallRule, rhs._firewallRule).isEquals();
+ }
+
+ @Override
+ public String toString()
+ {
+ return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE)
+ .append(_action)
+ .append(_firewallRule).toString();
+ }
+}
diff --git a/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/AclRulePredicates.java b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/AclRulePredicates.java
new file mode 100644
index 0000000000..45af85be6c
--- /dev/null
+++ b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/AclRulePredicates.java
@@ -0,0 +1,102 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.qpid.server.security.access.config;
+
+import org.apache.commons.lang.builder.ToStringBuilder;
+import org.apache.commons.lang.builder.ToStringStyle;
+import org.apache.log4j.Logger;
+import org.apache.qpid.server.security.access.ObjectProperties;
+import org.apache.qpid.server.security.access.ObjectProperties.Property;
+import org.apache.qpid.server.security.access.firewall.FirewallRule;
+import org.apache.qpid.server.security.access.firewall.FirewallRuleFactory;
+
+/**
+ * Represents the predicates on an ACL rule by combining predicates relating to the object being operated on
+ * (e.g. name=foo) with firewall rules.
+ */
+public class AclRulePredicates
+{
+ private static final Logger _logger = Logger.getLogger(AclRulePredicates.class);
+
+ private static final String SEPARATOR = ",";
+
+ private ObjectProperties _properties = new ObjectProperties();
+
+ private FirewallRule _firewallRule;
+
+ private FirewallRuleFactory _firewallRuleFactory = new FirewallRuleFactory();
+
+ public void parse(String key, String value)
+ {
+ ObjectProperties.Property property = ObjectProperties.Property.parse(key);
+
+ if(property == Property.FROM_HOSTNAME)
+ {
+ checkFirewallRuleNotAlreadyDefined(key, value);
+ _firewallRule = _firewallRuleFactory.createForHostname(value.split(SEPARATOR));
+ }
+ else if(property == Property.FROM_NETWORK)
+ {
+ checkFirewallRuleNotAlreadyDefined(key, value);
+ _firewallRule = _firewallRuleFactory.createForNetwork(value.split(SEPARATOR));
+ }
+ else
+ {
+ _properties.put(property, value);
+ }
+
+ if (_logger.isDebugEnabled())
+ {
+ _logger.debug("Parsed " + property + " with value " + value);
+ }
+ }
+
+ private void checkFirewallRuleNotAlreadyDefined(String key, String value)
+ {
+ if(_firewallRule != null)
+ {
+ throw new IllegalStateException(
+ "Cannot parse " + key + "=" + value
+ + " because firewall rule " + _firewallRule + " has already been defined");
+ }
+ }
+
+ @Override
+ public String toString()
+ {
+ return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE)
+ .append(_properties)
+ .append(_firewallRule).toString();
+ }
+
+ public FirewallRule getFirewallRule()
+ {
+ return _firewallRule;
+ }
+
+ public ObjectProperties getObjectProperties()
+ {
+ return _properties;
+ }
+
+ void setFirewallRuleFactory(FirewallRuleFactory firewallRuleFactory)
+ {
+ _firewallRuleFactory = firewallRuleFactory;
+ }
+}
diff --git a/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/Action.java b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/Action.java
index b887d1e079..4fff0bebf5 100644
--- a/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/Action.java
+++ b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/Action.java
@@ -20,8 +20,6 @@
*/
package org.apache.qpid.server.security.access.config;
-import java.util.Comparator;
-
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ToStringBuilder;
@@ -32,7 +30,7 @@ import org.apache.qpid.server.security.access.Operation;
/**
* An access control v2 rule action.
- *
+ *
* An action consists of an {@link Operation} on an {@link ObjectType} with certain properties, stored in a {@link java.util.Map}.
* The operation and object should be an allowable combination, based on the {@link ObjectType#isAllowed(Operation)}
* method of the object, which is exposed as the {@link #isAllowed()} method here. The internal {@link #propertiesMatch(Map)}
@@ -45,104 +43,96 @@ import org.apache.qpid.server.security.access.Operation;
*/
public class Action
{
- private Operation _operation;
- private ObjectType _object;
- private ObjectProperties _properties;
-
+ private final Operation _operation;
+ private final ObjectType _object;
+ private final ObjectProperties _properties;
+
public Action(Operation operation)
{
this(operation, ObjectType.ALL);
}
-
+
public Action(Operation operation, ObjectType object, String name)
{
this(operation, object, new ObjectProperties(name));
}
-
+
public Action(Operation operation, ObjectType object)
{
this(operation, object, ObjectProperties.EMPTY);
}
-
+
public Action(Operation operation, ObjectType object, ObjectProperties properties)
{
- setOperation(operation);
- setObjectType(object);
- setProperties(properties);
+ _operation = operation;
+ _object = object;
+ _properties = properties;
}
-
+
public Operation getOperation()
{
return _operation;
}
- public void setOperation(Operation operation)
- {
- _operation = operation;
- }
-
public ObjectType getObjectType()
{
return _object;
}
- public void setObjectType(ObjectType object)
- {
- _object = object;
- }
-
public ObjectProperties getProperties()
{
return _properties;
}
-
- public void setProperties(ObjectProperties properties)
- {
- _properties = properties;
- }
-
+
public boolean isAllowed()
{
return _object.isAllowed(_operation);
}
- /** @see Comparable#compareTo(Object) */
public boolean matches(Action a)
{
- return ((Operation.ALL == a.getOperation() || getOperation() == a.getOperation())
- && (ObjectType.ALL == a.getObjectType() || getObjectType() == a.getObjectType())
- && _properties.matches(a.getProperties()));
+ if (!operationsMatch(a))
+ {
+ return false;
+ }
+
+ if (!objectTypesMatch(a))
+ {
+ return false;
+ }
+
+ if (!propertiesMatch(a))
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ private boolean operationsMatch(Action a)
+ {
+ return Operation.ALL == a.getOperation() || getOperation() == a.getOperation();
}
- /**
- * An ordering based on specificity
- *
- * @see Comparator#compare(Object, Object)
- */
- public class Specificity implements Comparator<Action>
+ private boolean objectTypesMatch(Action a)
{
- public int compare(Action a, Action b)
+ return ObjectType.ALL == a.getObjectType() || getObjectType() == a.getObjectType();
+ }
+
+ private boolean propertiesMatch(Action a)
+ {
+ boolean propertiesMatch = false;
+ if (_properties != null)
+ {
+ propertiesMatch = _properties.matches(a.getProperties());
+ }
+ else if (a.getProperties() == null)
{
- if (a.getOperation() == Operation.ALL && b.getOperation() != Operation.ALL)
- {
- return 1; // B is more specific
- }
- else if (b.getOperation() == Operation.ALL && a.getOperation() != Operation.ALL)
- {
- return 1; // A is more specific
- }
- else if (a.getOperation() == b.getOperation())
- {
- return 1; // b is more specific
- }
- else // Different operations
- {
- return a.getOperation().compareTo(b.getOperation()); // Arbitrary
- }
+ propertiesMatch = true;
}
+ return propertiesMatch;
}
- /** @see Object#equals(Object) */
@Override
public boolean equals(Object o)
{
@@ -151,26 +141,24 @@ public class Action
return false;
}
Action a = (Action) o;
-
+
return new EqualsBuilder()
.append(_operation, a.getOperation())
.append(_object, a.getObjectType())
- .appendSuper(_properties.equals(a.getProperties()))
+ .append(_properties, a.getProperties())
.isEquals();
}
- /** @see Object#hashCode() */
@Override
public int hashCode()
{
return new HashCodeBuilder()
.append(_operation)
- .append(_operation)
+ .append(_object)
.append(_properties)
.toHashCode();
}
- /** @see Object#toString() */
@Override
public String toString()
{
diff --git a/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/ClientAction.java b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/ClientAction.java
new file mode 100644
index 0000000000..fed20a56c8
--- /dev/null
+++ b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/ClientAction.java
@@ -0,0 +1,88 @@
+/*
+ * 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.access.config;
+
+import java.net.InetAddress;
+
+import org.apache.commons.lang.builder.ToStringBuilder;
+import org.apache.commons.lang.builder.ToStringStyle;
+import org.apache.qpid.server.security.access.ObjectProperties;
+import org.apache.qpid.server.security.access.ObjectType;
+import org.apache.qpid.server.security.access.Operation;
+import org.apache.qpid.server.security.access.firewall.FirewallRule;
+
+/**
+ * I represent an {@link Action} taken by a client from a known address. The address is used to
+ * determine if I match an {@link AclAction}, which may contain firewall rules.
+ */
+public class ClientAction
+{
+ private Action _clientAction;
+
+ public ClientAction(Action clientAction)
+ {
+ _clientAction = clientAction;
+ }
+
+ public ClientAction(Operation operation, ObjectType objectType, ObjectProperties properties)
+ {
+ _clientAction = new Action(operation, objectType, properties);
+ }
+
+ public boolean matches(AclAction ruleAction, InetAddress addressOfClient)
+ {
+ return _clientAction.matches(ruleAction.getAction())
+ && addressOfClientMatches(ruleAction, addressOfClient);
+ }
+
+ private boolean addressOfClientMatches(AclAction ruleAction, InetAddress addressOfClient)
+ {
+ FirewallRule firewallRule = ruleAction.getFirewallRule();
+ if(firewallRule == null || addressOfClient == null)
+ {
+ return true;
+ }
+ else
+ {
+ return firewallRule.matches(addressOfClient);
+ }
+ }
+
+ public Operation getOperation()
+ {
+ return _clientAction.getOperation();
+ }
+
+ public ObjectType getObjectType()
+ {
+ return _clientAction.getObjectType();
+ }
+
+ public ObjectProperties getProperties()
+ {
+ return _clientAction.getProperties();
+ }
+
+ @Override
+ public String toString()
+ {
+ return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE)
+ .append(_clientAction).toString();
+ }
+}
diff --git a/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/ConfigurationFile.java b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/ConfigurationFile.java
index 8b1a00259b..966c32e24e 100644
--- a/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/ConfigurationFile.java
+++ b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/ConfigurationFile.java
@@ -22,7 +22,7 @@ package org.apache.qpid.server.security.access.config;
import java.io.File;
-import org.apache.commons.configuration.ConfigurationException;
+import org.apache.qpid.server.configuration.IllegalConfigurationException;
public interface ConfigurationFile
{
@@ -33,19 +33,17 @@ public interface ConfigurationFile
/**
* Load this configuration file's contents into a {@link RuleSet}.
- *
- * @throws ConfigurationException if the configuration file has errors.
+ * @throws IllegalConfigurationException if the configuration file has errors.
* @throws IllegalArgumentException if individual tokens cannot be parsed.
*/
- RuleSet load() throws ConfigurationException;
+ RuleSet load() throws IllegalConfigurationException;
/**
* Reload this configuration file's contents.
- *
- * @throws ConfigurationException if the configuration file has errors.
+ * @throws IllegalConfigurationException if the configuration file has errors.
* @throws IllegalArgumentException if individual tokens cannot be parsed.
*/
- RuleSet reload() throws ConfigurationException;
+ RuleSet reload() throws IllegalConfigurationException;
RuleSet getConfiguration();
diff --git a/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/PlainConfiguration.java b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/PlainConfiguration.java
index 9a08eb6499..ab309c54ce 100644
--- a/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/PlainConfiguration.java
+++ b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/PlainConfiguration.java
@@ -1,5 +1,5 @@
/*
- *
+ *
* 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
@@ -7,16 +7,16 @@
* 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.access.config;
@@ -32,55 +32,65 @@ import java.util.List;
import java.util.Map;
import java.util.Stack;
-import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.lang.StringUtils;
-import org.apache.qpid.server.security.access.ObjectProperties;
+import org.apache.log4j.Logger;
+import org.apache.qpid.server.configuration.IllegalConfigurationException;
import org.apache.qpid.server.security.access.ObjectType;
import org.apache.qpid.server.security.access.Operation;
import org.apache.qpid.server.security.access.Permission;
public class PlainConfiguration extends AbstractConfiguration
{
+ private static final Logger _logger = Logger.getLogger(PlainConfiguration.class);
+
public static final Character COMMENT = '#';
public static final Character CONTINUATION = '\\';
- public static final String GROUP = "group";
public static final String ACL = "acl";
public static final String CONFIG = "config";
- public static final String UNRECOGNISED_INITIAL_MSG = "Unrecognised initial token '%s' at line %d";
- public static final String NOT_ENOUGH_TOKENS_MSG = "Not enough tokens at line %d";
- public static final String NUMBER_NOT_ALLOWED_MSG = "Number not allowed before '%s' at line %d";
- public static final String CANNOT_LOAD_MSG = "Cannot load config file %s";
- public static final String PREMATURE_CONTINUATION_MSG = "Premature continuation character at line %d";
- public static final String PREMATURE_EOF_MSG = "Premature end of file reached at line %d";
- public static final String PARSE_TOKEN_FAILED_MSG = "Failed to parse token at line %d";
- public static final String CONFIG_NOT_FOUND_MSG = "Cannot find config file %s";
- public static final String NOT_ENOUGH_GROUP_MSG = "Not enough data for a group at line %d";
- public static final String NOT_ENOUGH_ACL_MSG = "Not enough data for an acl at line %d";
- public static final String NOT_ENOUGH_CONFIG_MSG = "Not enough data for config at line %d";
- public static final String BAD_ACL_RULE_NUMBER_MSG = "Invalid rule number at line %d";
- public static final String PROPERTY_KEY_ONLY_MSG = "Incomplete property (key only) at line %d";
- public static final String PROPERTY_NO_EQUALS_MSG = "Incomplete property (no equals) at line %d";
- public static final String PROPERTY_NO_VALUE_MSG = "Incomplete property (no value) at line %d";
-
+ static final String UNRECOGNISED_INITIAL_MSG = "Unrecognised initial token '%s' at line %d";
+ static final String NOT_ENOUGH_TOKENS_MSG = "Not enough tokens at line %d";
+ static final String NUMBER_NOT_ALLOWED_MSG = "Number not allowed before '%s' at line %d";
+ static final String CANNOT_LOAD_MSG = "Cannot load config file %s";
+ static final String CANNOT_CLOSE_MSG = "Cannot close config file %s";
+ static final String PREMATURE_CONTINUATION_MSG = "Premature continuation character at line %d";
+ static final String PREMATURE_EOF_MSG = "Premature end of file reached at line %d";
+ static final String PARSE_TOKEN_FAILED_MSG = "Failed to parse token at line %d";
+ static final String CONFIG_NOT_FOUND_MSG = "Cannot find config file %s";
+ static final String NOT_ENOUGH_ACL_MSG = "Not enough data for an acl at line %d";
+ static final String NOT_ENOUGH_CONFIG_MSG = "Not enough data for config at line %d";
+ static final String BAD_ACL_RULE_NUMBER_MSG = "Invalid rule number at line %d";
+ static final String PROPERTY_KEY_ONLY_MSG = "Incomplete property (key only) at line %d";
+ static final String PROPERTY_NO_EQUALS_MSG = "Incomplete property (no equals) at line %d";
+ static final String PROPERTY_NO_VALUE_MSG = "Incomplete property (no value) at line %d";
+
private StreamTokenizer _st;
public PlainConfiguration(File file)
{
super(file);
}
-
+
@Override
- public RuleSet load() throws ConfigurationException
+ public RuleSet load()
{
RuleSet ruleSet = super.load();
-
+
+ File file = getFile();
+ FileReader fileReader = null;
+
try
{
- _st = new StreamTokenizer(new BufferedReader(new FileReader(getFile())));
+ if(_logger.isDebugEnabled())
+ {
+ _logger.debug("About to load ACL file " + file);
+ }
+
+ fileReader = new FileReader(file);
+ _st = new StreamTokenizer(new BufferedReader(fileReader));
_st.resetSyntax(); // setup the tokenizer
-
+
_st.commentChar(COMMENT); // single line comments
_st.eolIsSignificant(true); // return EOL as a token
_st.ordinaryChar('='); // equals is a token
@@ -97,7 +107,7 @@ public class PlainConfiguration extends AbstractConfiguration
_st.wordChars('*', '*'); // star
_st.wordChars('@', '@'); // at
_st.wordChars(':', ':'); // colon
-
+
// parse the acl file lines
Stack<String> stack = new Stack<String>();
int current;
@@ -111,21 +121,21 @@ public class PlainConfiguration extends AbstractConfiguration
{
break; // blank line
}
-
+
// pull out the first token from the bottom of the stack and check arguments exist
String first = stack.firstElement();
stack.removeElementAt(0);
if (stack.isEmpty())
{
- throw new ConfigurationException(String.format(NOT_ENOUGH_TOKENS_MSG, getLine()));
+ throw new IllegalConfigurationException(String.format(NOT_ENOUGH_TOKENS_MSG, getLine()));
}
-
+
// check for and parse optional initial number for ACL lines
Integer number = null;
if (StringUtils.isNumeric(first))
{
// set the acl number and get the next element
- number = Integer.valueOf(first);
+ number = Integer.valueOf(first);
first = stack.firstElement();
stack.removeElementAt(0);
}
@@ -136,9 +146,9 @@ public class PlainConfiguration extends AbstractConfiguration
}
else if (number == null)
{
- if (StringUtils.equalsIgnoreCase(GROUP, first))
+ if(StringUtils.equalsIgnoreCase("GROUP", first))
{
- parseGroup(stack);
+ throw new IllegalConfigurationException(String.format("GROUP keyword not supported. Groups should defined via a Group Provider, not in the ACL file.", getLine()));
}
else if (StringUtils.equalsIgnoreCase(CONFIG, first))
{
@@ -146,14 +156,14 @@ public class PlainConfiguration extends AbstractConfiguration
}
else
{
- throw new ConfigurationException(String.format(UNRECOGNISED_INITIAL_MSG, first, getLine()));
+ throw new IllegalConfigurationException(String.format(UNRECOGNISED_INITIAL_MSG, first, getLine()));
}
}
else
{
- throw new ConfigurationException(String.format(NUMBER_NOT_ALLOWED_MSG, first, getLine()));
+ throw new IllegalConfigurationException(String.format(NUMBER_NOT_ALLOWED_MSG, first, getLine()));
}
-
+
// reset stack, start next line
stack.clear();
break;
@@ -171,9 +181,9 @@ public class PlainConfiguration extends AbstractConfiguration
{
break; // continue reading next line
}
-
+
// invalid location for continuation character (add one to line beacuse we ate the EOL)
- throw new ConfigurationException(String.format(PREMATURE_CONTINUATION_MSG, getLine() + 1));
+ throw new IllegalConfigurationException(String.format(PREMATURE_CONTINUATION_MSG, getLine() + 1));
}
else if (_st.ttype == '\'' || _st.ttype == '"')
{
@@ -185,54 +195,59 @@ public class PlainConfiguration extends AbstractConfiguration
}
}
} while (current != StreamTokenizer.TT_EOF);
-
+
if (!stack.isEmpty())
{
- throw new ConfigurationException(String.format(PREMATURE_EOF_MSG, getLine()));
+ throw new IllegalConfigurationException(String.format(PREMATURE_EOF_MSG, getLine()));
}
}
catch (IllegalArgumentException iae)
{
- throw new ConfigurationException(String.format(PARSE_TOKEN_FAILED_MSG, getLine()), iae);
+ throw new IllegalConfigurationException(String.format(PARSE_TOKEN_FAILED_MSG, getLine()), iae);
}
catch (FileNotFoundException fnfe)
{
- throw new ConfigurationException(String.format(CONFIG_NOT_FOUND_MSG, getFile().getName()), fnfe);
+ throw new IllegalConfigurationException(String.format(CONFIG_NOT_FOUND_MSG, file.getName()), fnfe);
}
catch (IOException ioe)
{
- throw new ConfigurationException(String.format(CANNOT_LOAD_MSG, getFile().getName()), ioe);
+ throw new IllegalConfigurationException(String.format(CANNOT_LOAD_MSG, file.getName()), ioe);
}
-
- return ruleSet;
- }
-
- private void parseGroup(List<String> args) throws ConfigurationException
- {
- if (args.size() < 2)
+ finally
{
- throw new ConfigurationException(String.format(NOT_ENOUGH_GROUP_MSG, getLine()));
+ if(fileReader != null)
+ {
+ try
+ {
+ fileReader.close();
+ }
+ catch (IOException e)
+ {
+ throw new IllegalConfigurationException(String.format(CANNOT_CLOSE_MSG, file.getName()), e);
+ }
+ }
}
-
- getConfiguration().addGroup(args.get(0), args.subList(1, args.size()));
+
+
+ return ruleSet;
}
-
- private void parseAcl(Integer number, List<String> args) throws ConfigurationException
+
+ private void parseAcl(Integer number, List<String> args)
{
if (args.size() < 3)
{
- throw new ConfigurationException(String.format(NOT_ENOUGH_ACL_MSG, getLine()));
+ throw new IllegalConfigurationException(String.format(NOT_ENOUGH_ACL_MSG, getLine()));
}
Permission permission = Permission.parse(args.get(0));
String identity = args.get(1);
Operation operation = Operation.parse(args.get(2));
-
+
if (number != null && !getConfiguration().isValidNumber(number))
{
- throw new ConfigurationException(String.format(BAD_ACL_RULE_NUMBER_MSG, getLine()));
+ throw new IllegalConfigurationException(String.format(BAD_ACL_RULE_NUMBER_MSG, getLine()));
}
-
+
if (args.size() == 3)
{
getConfiguration().grant(number, identity, permission, operation);
@@ -240,55 +255,52 @@ public class PlainConfiguration extends AbstractConfiguration
else
{
ObjectType object = ObjectType.parse(args.get(3));
- ObjectProperties properties = toObjectProperties(args.subList(4, args.size()));
+ AclRulePredicates predicates = toRulePredicates(args.subList(4, args.size()));
- getConfiguration().grant(number, identity, permission, operation, object, properties);
+ getConfiguration().grant(number, identity, permission, operation, object, predicates);
}
}
-
- private void parseConfig(List<String> args) throws ConfigurationException
+
+ private void parseConfig(List<String> args)
{
if (args.size() < 3)
{
- throw new ConfigurationException(String.format(NOT_ENOUGH_CONFIG_MSG, getLine()));
+ throw new IllegalConfigurationException(String.format(NOT_ENOUGH_CONFIG_MSG, getLine()));
}
Map<String, Boolean> properties = toPluginProperties(args);
-
+
getConfiguration().configure(properties);
}
-
- /** Converts a {@link List} of "name", "=", "value" tokens into a {@link Map}. */
- protected ObjectProperties toObjectProperties(List<String> args) throws ConfigurationException
+
+ private AclRulePredicates toRulePredicates(List<String> args)
{
- ObjectProperties properties = new ObjectProperties();
+ AclRulePredicates predicates = new AclRulePredicates();
Iterator<String> i = args.iterator();
while (i.hasNext())
{
String key = i.next();
if (!i.hasNext())
{
- throw new ConfigurationException(String.format(PROPERTY_KEY_ONLY_MSG, getLine()));
+ throw new IllegalConfigurationException(String.format(PROPERTY_KEY_ONLY_MSG, getLine()));
}
if (!"=".equals(i.next()))
{
- throw new ConfigurationException(String.format(PROPERTY_NO_EQUALS_MSG, getLine()));
+ throw new IllegalConfigurationException(String.format(PROPERTY_NO_EQUALS_MSG, getLine()));
}
if (!i.hasNext())
{
- throw new ConfigurationException(String.format(PROPERTY_NO_VALUE_MSG, getLine()));
+ throw new IllegalConfigurationException(String.format(PROPERTY_NO_VALUE_MSG, getLine()));
}
String value = i.next();
-
- // parse property key
- ObjectProperties.Property property = ObjectProperties.Property.parse(key);
- properties.put(property, value);
+
+ predicates.parse(key, value);
}
- return properties;
+ return predicates;
}
-
+
/** Converts a {@link List} of "name", "=", "value" tokens into a {@link Map}. */
- protected Map<String, Boolean> toPluginProperties(List<String> args) throws ConfigurationException
+ protected Map<String, Boolean> toPluginProperties(List<String> args)
{
Map<String, Boolean> properties = new HashMap<String, Boolean>();
Iterator<String> i = args.iterator();
@@ -297,24 +309,24 @@ public class PlainConfiguration extends AbstractConfiguration
String key = i.next().toLowerCase();
if (!i.hasNext())
{
- throw new ConfigurationException(String.format(PROPERTY_KEY_ONLY_MSG, getLine()));
+ throw new IllegalConfigurationException(String.format(PROPERTY_KEY_ONLY_MSG, getLine()));
}
if (!"=".equals(i.next()))
{
- throw new ConfigurationException(String.format(PROPERTY_NO_EQUALS_MSG, getLine()));
+ throw new IllegalConfigurationException(String.format(PROPERTY_NO_EQUALS_MSG, getLine()));
}
if (!i.hasNext())
{
- throw new ConfigurationException(String.format(PROPERTY_NO_VALUE_MSG, getLine()));
+ throw new IllegalConfigurationException(String.format(PROPERTY_NO_VALUE_MSG, getLine()));
}
-
+
// parse property value and save
Boolean value = Boolean.valueOf(i.next());
properties.put(key, value);
}
return properties;
}
-
+
protected int getLine()
{
return _st.lineno() - 1;
diff --git a/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/Rule.java b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/Rule.java
index 15d6b67192..cef9a8696b 100644
--- a/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/Rule.java
+++ b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/Rule.java
@@ -29,7 +29,7 @@ import org.apache.qpid.server.security.access.Permission;
/**
* An access control v2 rule.
- *
+ *
* A rule consists of {@link Permission} for a particular identity to perform an {@link Action}. The identity
* may be either a user or a group.
*/
@@ -37,41 +37,41 @@ public class Rule implements Comparable<Rule>
{
/** String indicating all identitied. */
public static final String ALL = "all";
-
+
private Integer _number;
private Boolean _enabled = Boolean.TRUE;
private String _identity;
- private Action _action;
+ private AclAction _action;
private Permission _permission;
-
- public Rule(Integer number, String identity, Action action, Permission permission)
+
+ public Rule(Integer number, String identity, AclAction action, Permission permission)
{
setNumber(number);
setIdentity(identity);
setAction(action);
setPermission(permission);
}
-
- public Rule(String identity, Action action, Permission permission)
+
+ public Rule(String identity, AclAction action, Permission permission)
{
this(null, identity, action, permission);
}
-
+
public boolean isEnabled()
{
return _enabled;
}
-
+
public void setEnabled(boolean enabled)
{
_enabled = enabled;
}
-
+
public void enable()
{
_enabled = Boolean.TRUE;
}
-
+
public void disable()
{
_enabled = Boolean.FALSE;
@@ -96,13 +96,18 @@ public class Rule implements Comparable<Rule>
{
_identity = identity;
}
-
+
public Action getAction()
{
+ return _action.getAction();
+ }
+
+ public AclAction getAclAction()
+ {
return _action;
}
- public void setAction(Action action)
+ public void setAction(AclAction action)
{
_action = action;
}
@@ -117,7 +122,7 @@ public class Rule implements Comparable<Rule>
_permission = permission;
}
- /** @see Comparable#compareTo(Object) */
+ @Override
public int compareTo(Rule r)
{
return new CompareToBuilder()
@@ -127,7 +132,6 @@ public class Rule implements Comparable<Rule>
.toComparison();
}
- /** @see Object#equals(Object) */
@Override
public boolean equals(Object o)
{
@@ -136,33 +140,31 @@ public class Rule implements Comparable<Rule>
return false;
}
Rule r = (Rule) o;
-
+
return new EqualsBuilder()
.append(getIdentity(), r.getIdentity())
- .append(getAction(), r.getAction())
+ .append(getAclAction(), r.getAclAction())
.append(getPermission(), r.getPermission())
.isEquals();
}
- /** @see Object#hashCode() */
@Override
public int hashCode()
{
return new HashCodeBuilder()
.append(getIdentity())
- .append(getAction())
+ .append(getAclAction())
.append(getPermission())
.toHashCode();
}
- /** @see Object#toString() */
@Override
public String toString()
{
return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE)
.append("#", getNumber())
.append("identity", getIdentity())
- .append("action", getAction())
+ .append("action", getAclAction())
.append("permission", getPermission())
.append("enabled", isEnabled())
.toString();
diff --git a/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/RuleSet.java b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/RuleSet.java
index 815df99f80..e61370fced 100644
--- a/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/RuleSet.java
+++ b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/RuleSet.java
@@ -18,8 +18,8 @@
*/
package org.apache.qpid.server.security.access.config;
+import java.net.InetAddress;
import java.security.Principal;
-import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.EnumMap;
@@ -54,7 +54,7 @@ import org.apache.qpid.server.security.access.logging.AccessControlMessages;
*/
public class RuleSet
{
- public static final Logger _logger = Logger.getLogger(RuleSet.class);
+ private static final Logger _logger = Logger.getLogger(RuleSet.class);
private static final String AT = "@";
private static final String SLASH = "/";
@@ -66,7 +66,6 @@ public class RuleSet
private static final Integer _increment = 10;
- private final Map<String, List<String>> _aclGroups = new HashMap<String, List<String>>();
private final SortedMap<Integer, Rule> _rules = new TreeMap<Integer, Rule>();
private final Map<Subject, Map<Operation, Map<ObjectType, List<Rule>>>> _cache =
new WeakHashMap<Subject, Map<Operation, Map<ObjectType, List<Rule>>>>();
@@ -79,14 +78,13 @@ public class RuleSet
}
/**
- * Clear the contents, including acl groups, rules and configuration.
+ * Clear the contents, including acl rules and configuration.
*/
public void clear()
{
_rules.clear();
_cache.clear();
_config.clear();
- _aclGroups.clear();
}
public int getRuleCount()
@@ -157,21 +155,27 @@ public class RuleSet
public void grant(Integer number, String identity, Permission permission, Operation operation)
{
- Action action = new Action(operation);
+ AclAction action = new AclAction(operation);
addRule(number, identity, permission, action);
}
public void grant(Integer number, String identity, Permission permission, Operation operation, ObjectType object, ObjectProperties properties)
{
- Action action = new Action(operation, object, properties);
+ AclAction action = new AclAction(operation, object, properties);
addRule(number, identity, permission, action);
}
- public boolean ruleExists(String identity, Action action)
+ public void grant(Integer number, String identity, Permission permission, Operation operation, ObjectType object, AclRulePredicates predicates)
+ {
+ AclAction aclAction = new AclAction(operation, object, predicates);
+ addRule(number, identity, permission, aclAction);
+ }
+
+ public boolean ruleExists(String identity, AclAction action)
{
for (Rule rule : _rules.values())
{
- if (rule.getIdentity().equals(identity) && rule.getAction().equals(action))
+ if (rule.getIdentity().equals(identity) && rule.getAclAction().equals(action))
{
return true;
}
@@ -179,8 +183,7 @@ public class RuleSet
return false;
}
- // TODO make this work when group membership is not known at file parse time
- public void addRule(Integer number, String identity, Permission permission, Action action)
+ public void addRule(Integer number, String identity, Permission permission, AclAction action)
{
_cache.clear();
@@ -222,53 +225,6 @@ public class RuleSet
_rules.get(Integer.valueOf(ruleNumber)).disable();
}
- public boolean addGroup(String group, List<String> constituents)
- {
- _cache.clear();
-
- if (_aclGroups.containsKey(group))
- {
- // cannot redefine
- return false;
- }
- else
- {
- _aclGroups.put(group, new ArrayList<String>());
- }
-
- for (String name : constituents)
- {
- if (name.equalsIgnoreCase(group))
- {
- // recursive definition
- return false;
- }
-
- if (!checkName(name))
- {
- // invalid name
- return false;
- }
-
- if (_aclGroups.containsKey(name))
- {
- // is a group
- _aclGroups.get(group).addAll(_aclGroups.get(name));
- }
- else
- {
- // is a user
- if (!isvalidUserName(name))
- {
- // invalid username
- return false;
- }
- _aclGroups.get(group).add(name);
- }
- }
- return true;
- }
-
/** Return true if the name is well-formed (contains legal characters). */
protected boolean checkName(String name)
{
@@ -312,11 +268,15 @@ public class RuleSet
return true;
}
- // CPP broker authorise function prototype
- // virtual bool authorise(const std::string& id, const Action& action, const ObjectType& objType,
- // const std::string& name, std::map<Property, std::string>* params=0)
-
- // Possibly add a String name paramater?
+ /**
+ * Checks for the case when the client's address is not known.
+ *
+ * @see #check(Subject, Operation, ObjectType, ObjectProperties, InetAddress)
+ */
+ public Result check(Subject subject, Operation operation, ObjectType objectType, ObjectProperties properties)
+ {
+ return check(subject, operation, objectType, properties, null);
+ }
/**
* Check the authorisation granted to a particular identity for an operation on an object type with
@@ -327,10 +287,9 @@ public class RuleSet
* the first match found, or denies access if there are no matching rules. Normally, it would be expected
* to have a default deny or allow rule at the end of an access configuration however.
*/
- public Result check(Subject subject, Operation operation, ObjectType objectType, ObjectProperties properties)
+ public Result check(Subject subject, Operation operation, ObjectType objectType, ObjectProperties properties, InetAddress addressOfClient)
{
- // Create the action to check
- Action action = new Action(operation, objectType, properties);
+ ClientAction action = new ClientAction(operation, objectType, properties);
if(_logger.isDebugEnabled())
{
@@ -349,27 +308,31 @@ public class RuleSet
}
// Iterate through a filtered set of rules dealing with this identity and operation
- for (Rule current : rules)
+ for (Rule rule : rules)
{
if(_logger.isDebugEnabled())
{
- _logger.debug("Checking against rule: " + current);
+ _logger.debug("Checking against rule: " + rule);
}
- // Check if action matches
- if (action.matches(current.getAction()))
+
+ if (action.matches(rule.getAclAction(), addressOfClient))
{
- Permission permission = current.getPermission();
+ Permission permission = rule.getPermission();
switch (permission)
{
case ALLOW_LOG:
CurrentActor.get().message(AccessControlMessages.ALLOWED(
- action.getOperation().toString(), action.getObjectType().toString(), action.getProperties().toString()));
+ action.getOperation().toString(),
+ action.getObjectType().toString(),
+ action.getProperties().toString()));
case ALLOW:
return Result.ALLOWED;
case DENY_LOG:
CurrentActor.get().message(AccessControlMessages.DENIED(
- action.getOperation().toString(), action.getObjectType().toString(), action.getProperties().toString()));
+ action.getOperation().toString(),
+ action.getObjectType().toString(),
+ action.getProperties().toString()));
case DENY:
return Result.DENIED;
}
@@ -446,8 +409,7 @@ public class RuleSet
{
final Principal principal = iterator.next();
- if (rule.getIdentity().equalsIgnoreCase(principal.getName())
- || (_aclGroups.containsKey(rule.getIdentity()) && _aclGroups.get(rule.getIdentity()).contains(principal.getName())))
+ if (rule.getIdentity().equalsIgnoreCase(principal.getName()))
{
return true;
}
@@ -476,5 +438,4 @@ public class RuleSet
}
return objects;
}
-
}
diff --git a/java/broker-plugins/firewall/src/main/java/org/apache/qpid/server/security/access/config/FirewallException.java b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/firewall/AccessControlFirewallException.java
index a9e3fdc242..d08a052efd 100644
--- a/java/broker-plugins/firewall/src/main/java/org/apache/qpid/server/security/access/config/FirewallException.java
+++ b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/firewall/AccessControlFirewallException.java
@@ -18,29 +18,30 @@
* under the License.
*
*/
-package org.apache.qpid.server.security.access.config;
+package org.apache.qpid.server.security.access.firewall;
-/**
- * Firewall plugin exception.
- */
-public class FirewallException extends Exception
+public class AccessControlFirewallException extends RuntimeException
{
/** serialVersionUID */
private static final long serialVersionUID = 4526157149690917805L;
-
- public FirewallException() {
- super();
+
+ public AccessControlFirewallException()
+ {
+ super();
}
- public FirewallException(String message) {
- super(message);
+ public AccessControlFirewallException(String message)
+ {
+ super(message);
}
- public FirewallException(String message, Throwable cause) {
+ public AccessControlFirewallException(String message, Throwable cause)
+ {
super(message, cause);
}
- public FirewallException(Throwable cause) {
+ public AccessControlFirewallException(Throwable cause)
+ {
super(cause);
}
} \ No newline at end of file
diff --git a/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/AccessControlActivator.java b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/firewall/FirewallRule.java
index 7c83446cf1..482a795693 100644
--- a/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/AccessControlActivator.java
+++ b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/firewall/FirewallRule.java
@@ -1,5 +1,4 @@
/*
- *
* 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
@@ -7,35 +6,21 @@
* 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.access.plugins;
+package org.apache.qpid.server.security.access.firewall;
-import org.apache.qpid.server.configuration.plugins.ConfigurationPluginFactory;
-import org.apache.qpid.server.security.SecurityPluginActivator;
-import org.apache.qpid.server.security.SecurityPluginFactory;
+import java.net.InetAddress;
-/**
- * The OSGi {@link org.osgi.framework.BundleActivator} for {@link AccessControl}.
- */
-public class AccessControlActivator extends SecurityPluginActivator
+public interface FirewallRule
{
- public SecurityPluginFactory getFactory()
- {
- return AccessControl.FACTORY;
- }
-
- public ConfigurationPluginFactory getConfigurationFactory()
- {
- return AccessControlConfiguration.FACTORY;
- }
+ boolean matches(InetAddress addressOfClient);
}
diff --git a/java/broker-plugins/firewall/src/main/java/org/apache/qpid/server/security/access/plugins/FirewallActivator.java b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/firewall/FirewallRuleFactory.java
index 1669352085..64be26c209 100644
--- a/java/broker-plugins/firewall/src/main/java/org/apache/qpid/server/security/access/plugins/FirewallActivator.java
+++ b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/firewall/FirewallRuleFactory.java
@@ -1,5 +1,4 @@
/*
- *
* 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
@@ -7,35 +6,28 @@
* 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.access.plugins;
+package org.apache.qpid.server.security.access.firewall;
-import org.apache.qpid.server.configuration.plugins.ConfigurationPluginFactory;
-import org.apache.qpid.server.security.SecurityPluginActivator;
-import org.apache.qpid.server.security.SecurityPluginFactory;
-
-/**
- * The OSGi {@link org.osgi.framework.BundleActivator} for {@link Firewall}.
- */
-public class FirewallActivator extends SecurityPluginActivator
+public class FirewallRuleFactory
{
- public SecurityPluginFactory getFactory()
+ public FirewallRule createForHostname(String[] hostnames)
{
- return Firewall.FACTORY;
+ return new HostnameFirewallRule(hostnames);
}
- public ConfigurationPluginFactory getConfigurationFactory()
+ public FirewallRule createForNetwork(String[] networks)
{
- return FirewallConfiguration.FACTORY;
+ return new NetworkFirewallRule(networks);
}
+
}
diff --git a/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/firewall/HostnameFirewallRule.java b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/firewall/HostnameFirewallRule.java
new file mode 100644
index 0000000000..fb13426fbb
--- /dev/null
+++ b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/firewall/HostnameFirewallRule.java
@@ -0,0 +1,156 @@
+/*
+ * 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.access.firewall;
+
+import java.net.InetAddress;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.FutureTask;
+import java.util.concurrent.TimeUnit;
+import java.util.regex.Pattern;
+
+import org.apache.commons.lang.builder.EqualsBuilder;
+import org.apache.commons.lang.builder.HashCodeBuilder;
+import org.apache.commons.lang.builder.ToStringBuilder;
+import org.apache.commons.lang.builder.ToStringStyle;
+import org.apache.log4j.Logger;
+
+public class HostnameFirewallRule implements FirewallRule
+{
+ private static final Logger _logger = Logger.getLogger(HostnameFirewallRule.class);
+
+ private static final long DNS_TIMEOUT = 30000;
+ private static final ExecutorService DNS_LOOKUP = Executors.newCachedThreadPool();
+
+ private Pattern[] _hostnamePatterns;
+ private String[] _hostnames;
+
+ public HostnameFirewallRule(String... hostnames)
+ {
+ _hostnames = hostnames;
+
+ int i = 0;
+ _hostnamePatterns = new Pattern[hostnames.length];
+ for (String hostname : hostnames)
+ {
+ _hostnamePatterns[i++] = Pattern.compile(hostname);
+ }
+
+ if(_logger.isDebugEnabled())
+ {
+ _logger.debug("Created " + this);
+ }
+ }
+
+ @Override
+ public boolean matches(InetAddress remote)
+ {
+ String hostname = getHostname(remote);
+ if (hostname == null)
+ {
+ throw new AccessControlFirewallException("DNS lookup failed for address " + remote);
+ }
+ for (Pattern pattern : _hostnamePatterns)
+ {
+ boolean hostnameMatches = pattern.matcher(hostname).matches();
+
+ if (hostnameMatches)
+ {
+ if(_logger.isDebugEnabled())
+ {
+ _logger.debug("Hostname " + hostname + " matches rule " + pattern.toString());
+ }
+ return true;
+ }
+ }
+
+ if(_logger.isDebugEnabled())
+ {
+ _logger.debug("Hostname " + hostname + " matches no configured hostname patterns");
+ }
+
+ return false;
+ }
+
+
+ /**
+ * @param remote
+ * the InetAddress to look up
+ * @return the hostname, null if not found, takes longer than
+ * {@value #DNS_LOOKUP} to find or otherwise fails
+ */
+ private String getHostname(final InetAddress remote) throws AccessControlFirewallException
+ {
+ FutureTask<String> lookup = new FutureTask<String>(new Callable<String>()
+ {
+ public String call()
+ {
+ return remote.getCanonicalHostName();
+ }
+ });
+ DNS_LOOKUP.execute(lookup);
+
+ try
+ {
+ return lookup.get(DNS_TIMEOUT, TimeUnit.MILLISECONDS);
+ }
+ catch (Exception e)
+ {
+ _logger.warn("Unable to look up hostname from address " + remote, e);
+ return null;
+ }
+ finally
+ {
+ lookup.cancel(true);
+ }
+ }
+
+ @Override
+ public int hashCode()
+ {
+ return new HashCodeBuilder().append(_hostnames).toHashCode();
+ }
+
+ @Override
+ public boolean equals(Object obj)
+ {
+ if (obj == null)
+ {
+ return false;
+ }
+ if (obj == this)
+ {
+ return true;
+ }
+ if (obj.getClass() != getClass())
+ {
+ return false;
+ }
+ HostnameFirewallRule rhs = (HostnameFirewallRule) obj;
+ return new EqualsBuilder().append(_hostnames, rhs._hostnames).isEquals();
+ }
+
+ @Override
+ public String toString()
+ {
+ return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE)
+ .append(_hostnames).toString();
+ }
+}
diff --git a/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/firewall/InetNetwork.java b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/firewall/InetNetwork.java
new file mode 100644
index 0000000000..2e979b38f1
--- /dev/null
+++ b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/firewall/InetNetwork.java
@@ -0,0 +1,177 @@
+/*
+ * 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.access.firewall;
+
+import java.net.InetAddress;
+
+class InetNetwork
+{
+ /*
+ * Implements network masking, and is compatible with RFC 1518 and
+ * RFC 1519, which describe CIDR: Classless Inter-Domain Routing.
+ */
+
+ private InetAddress network;
+ private InetAddress netmask;
+
+ public InetNetwork(InetAddress ip, InetAddress netmask)
+ {
+ this.network = maskIP(ip, netmask);
+ this.netmask = netmask;
+ }
+
+ public boolean contains(final String name) throws java.net.UnknownHostException
+ {
+ return network.equals(maskIP(InetAddress.getByName(name), netmask));
+ }
+
+ public boolean contains(final InetAddress ip)
+ {
+ return network.equals(maskIP(ip, netmask));
+ }
+
+ @Override
+ public String toString()
+ {
+ return network.getHostAddress() + "/" + netmask.getHostAddress();
+ }
+
+ @Override
+ public int hashCode()
+ {
+ return maskIP(network, netmask).hashCode();
+ }
+
+ @Override
+ public boolean equals(Object obj)
+ {
+ return (obj != null) &&
+ (obj instanceof InetNetwork) &&
+ ((InetNetwork)obj).network.equals(network) &&
+ ((InetNetwork)obj).netmask.equals(netmask);
+ }
+
+ public static InetNetwork getFromString(String netspec) throws java.net.UnknownHostException
+ {
+ if (netspec.endsWith("*"))
+ {
+ netspec = normalizeFromAsterisk(netspec);
+ }
+ else
+ {
+ int iSlash = netspec.indexOf('/');
+ if (iSlash == -1)
+ {
+ netspec += "/255.255.255.255";
+ }
+ else if (netspec.indexOf('.', iSlash) == -1)
+ {
+ netspec = normalizeFromCIDR(netspec);
+ }
+ }
+
+ return new InetNetwork(
+ InetAddress.getByName(netspec.substring(0, netspec.indexOf('/'))),
+ InetAddress.getByName(netspec.substring(netspec.indexOf('/') + 1)));
+ }
+
+ public static InetAddress maskIP(final byte[] ip, final byte[] mask)
+ {
+ try
+ {
+ return getByAddress(
+ new byte[]
+ {
+ (byte) (mask[0] & ip[0]),
+ (byte) (mask[1] & ip[1]),
+ (byte) (mask[2] & ip[2]),
+ (byte) (mask[3] & ip[3])
+ }
+ );
+ }
+ catch (Exception _)
+ {
+ return null;
+ }
+ }
+
+ public static InetAddress maskIP(final InetAddress ip, final InetAddress mask)
+ {
+ return maskIP(ip.getAddress(), mask.getAddress());
+ }
+
+ /*
+ * This converts from an uncommon "wildcard" CIDR format
+ * to "address + mask" format:
+ *
+ * * => 000.000.000.0/000.000.000.0
+ * xxx.* => xxx.000.000.0/255.000.000.0
+ * xxx.xxx.* => xxx.xxx.000.0/255.255.000.0
+ * xxx.xxx.xxx.* => xxx.xxx.xxx.0/255.255.255.0
+ */
+ static private String normalizeFromAsterisk(final String netspec)
+ {
+ String[] masks = { "0.0.0.0/0.0.0.0", "0.0.0/255.0.0.0", "0.0/255.255.0.0", "0/255.255.255.0" };
+ char[] srcb = netspec.toCharArray();
+ int octets = 0;
+ for (int i = 1; i < netspec.length(); i++)
+ {
+ if (srcb[i] == '.')
+ {
+ octets++;
+ }
+ }
+ return (octets == 0) ? masks[0] : netspec.substring(0, netspec.length() -1 ).concat(masks[octets]);
+ }
+
+ /*
+ * RFC 1518, 1519 - Classless Inter-Domain Routing (CIDR)
+ * This converts from "prefix + prefix-length" format to
+ * "address + mask" format, e.g. from xxx.xxx.xxx.xxx/yy
+ * to xxx.xxx.xxx.xxx/yyy.yyy.yyy.yyy.
+ */
+ static private String normalizeFromCIDR(final String netspec)
+ {
+ final int bits = 32 - Integer.parseInt(netspec.substring(netspec.indexOf('/')+1));
+ final int mask = (bits == 32) ? 0 : 0xFFFFFFFF - ((1 << bits)-1);
+
+ return netspec.substring(0, netspec.indexOf('/') + 1) +
+ Integer.toString(mask >> 24 & 0xFF, 10) + "." +
+ Integer.toString(mask >> 16 & 0xFF, 10) + "." +
+ Integer.toString(mask >> 8 & 0xFF, 10) + "." +
+ Integer.toString(mask >> 0 & 0xFF, 10);
+ }
+
+ private static InetAddress getByAddress(byte[] ip) throws java.net.UnknownHostException
+ {
+ InetAddress addr = InetAddress.getByAddress(ip);
+
+ if (addr == null) {
+ addr = InetAddress.getByName
+ (
+ Integer.toString(ip[0] & 0xFF, 10) + "." +
+ Integer.toString(ip[1] & 0xFF, 10) + "." +
+ Integer.toString(ip[2] & 0xFF, 10) + "." +
+ Integer.toString(ip[3] & 0xFF, 10)
+ );
+ }
+
+ return addr;
+ }
+} \ No newline at end of file
diff --git a/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/firewall/NetworkFirewallRule.java b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/firewall/NetworkFirewallRule.java
new file mode 100644
index 0000000000..ad619a0e0b
--- /dev/null
+++ b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/firewall/NetworkFirewallRule.java
@@ -0,0 +1,117 @@
+/*
+ * 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.access.firewall;
+
+import java.net.InetAddress;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.lang.builder.EqualsBuilder;
+import org.apache.commons.lang.builder.HashCodeBuilder;
+import org.apache.commons.lang.builder.ToStringBuilder;
+import org.apache.commons.lang.builder.ToStringStyle;
+import org.apache.log4j.Logger;
+
+public class NetworkFirewallRule implements FirewallRule
+{
+ private static final Logger _logger = Logger.getLogger(NetworkFirewallRule.class);
+
+ private List<InetNetwork> _networks;
+
+ public NetworkFirewallRule(String... networks)
+ {
+ _networks = new ArrayList<InetNetwork>();
+ for (int i = 0; i < networks.length; i++)
+ {
+ String network = networks[i];
+ try
+ {
+ InetNetwork inetNetwork = InetNetwork.getFromString(network);
+ if (!_networks.contains(inetNetwork))
+ {
+ _networks.add(inetNetwork);
+ }
+ }
+ catch (java.net.UnknownHostException uhe)
+ {
+ _logger.error("Cannot resolve address: " + network, uhe);
+ }
+ }
+
+ if(_logger.isDebugEnabled())
+ {
+ _logger.debug("Created " + this);
+ }
+ }
+
+ @Override
+ public boolean matches(InetAddress ip)
+ {
+ for (InetNetwork network : _networks)
+ {
+ if (network.contains(ip))
+ {
+ if(_logger.isDebugEnabled())
+ {
+ _logger.debug("Client address " + ip + " matches configured network " + network);
+ }
+ return true;
+ }
+ }
+
+ if(_logger.isDebugEnabled())
+ {
+ _logger.debug("Client address " + ip + " does not match any configured networks");
+ }
+
+ return false;
+ }
+
+ @Override
+ public int hashCode()
+ {
+ return new HashCodeBuilder().append(_networks).toHashCode();
+ }
+
+ @Override
+ public boolean equals(Object obj)
+ {
+ if (obj == null)
+ {
+ return false;
+ }
+ if (obj == this)
+ {
+ return true;
+ }
+ if (obj.getClass() != getClass())
+ {
+ return false;
+ }
+ NetworkFirewallRule rhs = (NetworkFirewallRule) obj;
+ return new EqualsBuilder().append(_networks, rhs._networks).isEquals();
+ }
+
+ @Override
+ public String toString()
+ {
+ return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE)
+ .append(_networks).toString();
+ }
+}
diff --git a/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/logging/AccessControl_logmessages.properties b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/logging/AccessControl_logmessages.properties
index bf80df3722..2a5eb7b3be 100644
--- a/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/logging/AccessControl_logmessages.properties
+++ b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/logging/AccessControl_logmessages.properties
@@ -25,4 +25,4 @@
ALLOWED = ACL-1001 : Allowed : {0} {1} {2}
# 'deny-log' rule message
-DENIED = ACL-1002 : Denied : {0} {1} {2} \ No newline at end of file
+DENIED = ACL-1002 : Denied : {0} {1} {2}
diff --git a/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/AccessControlConfiguration.java b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/AccessControlConfiguration.java
deleted file mode 100644
index c4db6db820..0000000000
--- a/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/AccessControlConfiguration.java
+++ /dev/null
@@ -1,83 +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.access.plugins;
-
-import java.io.File;
-import java.util.Arrays;
-import java.util.List;
-
-import org.apache.commons.configuration.Configuration;
-import org.apache.commons.configuration.ConfigurationException;
-import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin;
-import org.apache.qpid.server.configuration.plugins.ConfigurationPluginFactory;
-import org.apache.qpid.server.security.access.config.ConfigurationFile;
-import org.apache.qpid.server.security.access.config.PlainConfiguration;
-import org.apache.qpid.server.security.access.config.RuleSet;
-
-public class AccessControlConfiguration extends ConfigurationPlugin
-{
- public static final ConfigurationPluginFactory FACTORY = new ConfigurationPluginFactory()
- {
- public ConfigurationPlugin newInstance(String path, Configuration config) throws ConfigurationException
- {
- ConfigurationPlugin instance = new AccessControlConfiguration();
- instance.setConfiguration(path, config);
- return instance;
- }
-
- public List<String> getParentPaths()
- {
- return Arrays.asList("security.acl", "virtualhosts.virtualhost.security.acl");
- }
- };
-
- private RuleSet _ruleSet;
-
- public String[] getElementsProcessed()
- {
- return new String[] { "" };
- }
-
- public String getFileName()
- {
- return getConfig().getString("");
- }
-
- public void validateConfiguration() throws ConfigurationException
- {
- String filename = getFileName();
- if (filename == null)
- {
- throw new ConfigurationException("No ACL file name specified");
- }
-
- File aclFile = new File(filename);
-
- ConfigurationFile configFile = new PlainConfiguration(aclFile);
- _ruleSet = configFile.load();
- }
-
- public RuleSet getRuleSet()
- {
- return _ruleSet;
- }
-
-}
diff --git a/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/AccessControl.java b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/DefaultAccessControl.java
index d8a5bd4085..6f7885da94 100644
--- a/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/AccessControl.java
+++ b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/DefaultAccessControl.java
@@ -20,56 +20,47 @@
*/
package org.apache.qpid.server.security.access.plugins;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.io.File;
+
import javax.security.auth.Subject;
import org.apache.commons.configuration.ConfigurationException;
+import org.apache.commons.lang.ObjectUtils;
import org.apache.log4j.Logger;
-import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin;
-import org.apache.qpid.server.security.AbstractPlugin;
import org.apache.qpid.server.security.Result;
import org.apache.qpid.server.security.SecurityManager;
-import org.apache.qpid.server.security.SecurityPluginFactory;
+import org.apache.qpid.server.security.AccessControl;
import org.apache.qpid.server.security.access.ObjectProperties;
import org.apache.qpid.server.security.access.ObjectType;
import org.apache.qpid.server.security.access.Operation;
+import org.apache.qpid.server.security.access.config.ConfigurationFile;
+import org.apache.qpid.server.security.access.config.PlainConfiguration;
import org.apache.qpid.server.security.access.config.RuleSet;
-/**
- * This access control plugin implements version two plain text access control.
- */
-public class AccessControl extends AbstractPlugin
+public class DefaultAccessControl implements AccessControl
{
- public static final Logger _logger = Logger.getLogger(AccessControl.class);
-
+ private static final Logger _logger = Logger.getLogger(DefaultAccessControl.class);
+
private RuleSet _ruleSet;
-
- public static final SecurityPluginFactory<AccessControl> FACTORY = new SecurityPluginFactory<AccessControl>()
- {
- public Class<AccessControl> getPluginClass()
- {
- return AccessControl.class;
- }
- public String getPluginName()
+ public DefaultAccessControl(String fileName)
+ {
+ if (_logger.isDebugEnabled())
{
- return AccessControl.class.getName();
+ _logger.debug("Creating AccessControl instance using file: " + fileName);
}
+ File aclFile = new File(fileName);
- public AccessControl newInstance(ConfigurationPlugin config) throws ConfigurationException
- {
- AccessControlConfiguration configuration = config.getConfiguration(AccessControlConfiguration.class.getName());
-
- // If there is no configuration for this plugin then don't load it.
- if (configuration == null)
- {
- return null;
- }
+ ConfigurationFile configFile = new PlainConfiguration(aclFile);
+ _ruleSet = configFile.load();
+ }
- AccessControl plugin = new AccessControl();
- plugin.configure(configuration);
- return plugin;
- }
- };
+ DefaultAccessControl(RuleSet rs) throws ConfigurationException
+ {
+ _ruleSet = rs;
+ }
public Result getDefault()
{
@@ -82,11 +73,18 @@ public class AccessControl extends AbstractPlugin
* Delegate to the {@link #authorise(Operation, ObjectType, ObjectProperties)} method, with
* the operation set to ACCESS and no object properties.
*/
- public Result access(ObjectType objectType, Object instance)
+ public Result access(ObjectType objectType, Object inetSocketAddress)
{
- return authorise(Operation.ACCESS, objectType, ObjectProperties.EMPTY);
+ InetAddress addressOfClient = null;
+
+ if(inetSocketAddress != null)
+ {
+ addressOfClient = ((InetSocketAddress) inetSocketAddress).getAddress();
+ }
+
+ return authoriseFromAddress(Operation.ACCESS, objectType, ObjectProperties.EMPTY, addressOfClient);
}
-
+
/**
* Check if an operation is authorised by asking the configuration object about the access
* control rules granted to the current thread's {@link Subject}. If there is no current
@@ -94,23 +92,31 @@ public class AccessControl extends AbstractPlugin
*/
public Result authorise(Operation operation, ObjectType objectType, ObjectProperties properties)
{
+ return authoriseFromAddress(operation, objectType, properties, null);
+ }
+
+ public Result authoriseFromAddress(Operation operation, ObjectType objectType, ObjectProperties properties, InetAddress addressOfClient)
+ {
final Subject subject = SecurityManager.getThreadSubject();
// Abstain if there is no subject/principal associated with this thread
if (subject == null || subject.getPrincipals().size() == 0)
{
return Result.ABSTAIN;
}
-
- _logger.debug("Checking " + operation + " " + objectType);
- return _ruleSet.check(subject, operation, objectType, properties);
- }
- public void configure(ConfigurationPlugin config)
- {
- super.configure(config);
-
- AccessControlConfiguration accessConfig = (AccessControlConfiguration) getConfig();
+ if(_logger.isDebugEnabled())
+ {
+ _logger.debug("Checking " + operation + " " + objectType + " " + ObjectUtils.defaultIfNull(addressOfClient, ""));
+ }
- _ruleSet = accessConfig.getRuleSet();
+ try
+ {
+ return _ruleSet.check(subject, operation, objectType, properties, addressOfClient);
+ }
+ catch(Exception e)
+ {
+ _logger.error("Unable to check " + operation + " " + objectType + " " + ObjectUtils.defaultIfNull(addressOfClient, ""), e);
+ return Result.DENIED;
+ }
}
}
diff --git a/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/DefaultAccessControlFactory.java b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/DefaultAccessControlFactory.java
new file mode 100644
index 0000000000..a3d7823caf
--- /dev/null
+++ b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/DefaultAccessControlFactory.java
@@ -0,0 +1,59 @@
+/*
+ *
+ * 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.access.plugins;
+
+import java.io.File;
+import java.util.Map;
+
+import org.apache.qpid.server.configuration.IllegalConfigurationException;
+import org.apache.qpid.server.plugin.AccessControlFactory;
+import org.apache.qpid.server.security.AccessControl;
+
+public class DefaultAccessControlFactory implements AccessControlFactory
+{
+ public static final String ATTRIBUTE_ACL_FILE = "aclFile";
+
+ public AccessControl createInstance(Map<String, Object> aclConfiguration)
+ {
+ if (aclConfiguration != null)
+ {
+ Object aclFile = aclConfiguration.get(ATTRIBUTE_ACL_FILE);
+ if (aclFile != null)
+ {
+ if (aclFile instanceof String)
+ {
+ String aclPath = (String) aclFile;
+ if (!new File(aclPath).exists())
+ {
+ throw new IllegalConfigurationException("ACL file '" + aclPath + "' is not found");
+ }
+ return new DefaultAccessControl(aclPath);
+ }
+ else
+ {
+ throw new IllegalConfigurationException("Expected '" + ATTRIBUTE_ACL_FILE + "' attribute value of type String but was " + aclFile.getClass()
+ + ": " + aclFile);
+ }
+ }
+ }
+ return null;
+ }
+}
diff --git a/java/broker-plugins/access-control/src/main/resources/META-INF/services/org.apache.qpid.server.plugin.AccessControlFactory b/java/broker-plugins/access-control/src/main/resources/META-INF/services/org.apache.qpid.server.plugin.AccessControlFactory
new file mode 100644
index 0000000000..b6c429baab
--- /dev/null
+++ b/java/broker-plugins/access-control/src/main/resources/META-INF/services/org.apache.qpid.server.plugin.AccessControlFactory
@@ -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.
+#
+org.apache.qpid.server.security.access.plugins.DefaultAccessControlFactory
diff --git a/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/config/AclActionTest.java b/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/config/AclActionTest.java
new file mode 100644
index 0000000000..14620cff70
--- /dev/null
+++ b/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/config/AclActionTest.java
@@ -0,0 +1,66 @@
+/*
+ * 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.access.config;
+
+import static org.mockito.Mockito.*;
+
+import org.apache.qpid.server.security.access.ObjectProperties;
+import org.apache.qpid.server.security.access.ObjectType;
+import org.apache.qpid.server.security.access.Operation;
+import org.apache.qpid.server.security.access.firewall.FirewallRule;
+
+import junit.framework.TestCase;
+
+public class AclActionTest extends TestCase
+{
+ public void testEqualsAndHashCode()
+ {
+ AclRulePredicates predicates = createAclRulePredicates();
+ ObjectType objectType = ObjectType.EXCHANGE;
+ Operation operation = Operation.ACCESS;
+
+ AclAction aclAction = new AclAction(operation, objectType, predicates);
+ AclAction equalAclAction = new AclAction(operation, objectType, predicates);
+
+ assertTrue(aclAction.equals(aclAction));
+ assertTrue(aclAction.equals(equalAclAction));
+ assertTrue(equalAclAction.equals(aclAction));
+
+ assertTrue(aclAction.hashCode() == equalAclAction.hashCode());
+
+ assertFalse("Different operation should cause aclActions to be unequal",
+ aclAction.equals(new AclAction(Operation.BIND, objectType, predicates)));
+
+ assertFalse("Different operation type should cause aclActions to be unequal",
+ aclAction.equals(new AclAction(operation, ObjectType.GROUP, predicates)));
+
+ assertFalse("Different predicates should cause aclActions to be unequal",
+ aclAction.equals(new AclAction(operation, objectType, createAclRulePredicates())));
+
+ }
+
+ private AclRulePredicates createAclRulePredicates()
+ {
+ AclRulePredicates predicates = mock(AclRulePredicates.class);
+ when(predicates.getFirewallRule()).thenReturn(mock(FirewallRule.class));
+ when(predicates.getObjectProperties()).thenReturn(mock(ObjectProperties.class));
+ return predicates;
+ }
+
+}
diff --git a/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/config/AclRulePredicatesTest.java b/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/config/AclRulePredicatesTest.java
new file mode 100644
index 0000000000..93b765d0fb
--- /dev/null
+++ b/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/config/AclRulePredicatesTest.java
@@ -0,0 +1,87 @@
+/*
+ * 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.access.config;
+
+import static org.apache.qpid.server.security.access.ObjectProperties.Property.*;
+
+import org.apache.qpid.server.security.access.firewall.FirewallRule;
+import org.apache.qpid.server.security.access.firewall.FirewallRuleFactory;
+
+import static org.mockito.Mockito.*;
+
+import junit.framework.TestCase;
+
+public class AclRulePredicatesTest extends TestCase
+{
+ private AclRulePredicates _aclRulePredicates = new AclRulePredicates();
+ private FirewallRuleFactory _firewallRuleFactory = mock(FirewallRuleFactory.class);
+
+ @Override
+ protected void setUp() throws Exception
+ {
+ _aclRulePredicates.setFirewallRuleFactory(_firewallRuleFactory);
+
+ when(_firewallRuleFactory.createForHostname((String[]) any())).thenReturn(mock(FirewallRule.class));
+ when(_firewallRuleFactory.createForNetwork((String[]) any())).thenReturn(mock(FirewallRule.class));
+ }
+
+ public void testParse()
+ {
+ String name = "name";
+ String className = "class";
+
+ _aclRulePredicates.parse(NAME.name(), name);
+ _aclRulePredicates.parse(CLASS.name(), className);
+
+ assertEquals(name, _aclRulePredicates.getObjectProperties().get(NAME));
+ assertEquals(className, _aclRulePredicates.getObjectProperties().get(CLASS));
+ }
+
+ public void testParseHostnameFirewallRule()
+ {
+ String hostname = "hostname1,hostname2";
+ _aclRulePredicates.parse(FROM_HOSTNAME.name(), hostname);
+
+ verify(_firewallRuleFactory).createForHostname(new String[] {"hostname1", "hostname2"});
+ }
+
+ public void testParseNetworkFirewallRule()
+ {
+ _aclRulePredicates.setFirewallRuleFactory(_firewallRuleFactory);
+
+ String networks = "network1,network2";
+ _aclRulePredicates.parse(FROM_NETWORK.name(), networks);
+
+ verify(_firewallRuleFactory).createForNetwork(new String[] {"network1", "network2"});
+ }
+
+ public void testParseThrowsExceptionIfBothHostnameAndNetworkSpecified()
+ {
+ _aclRulePredicates.parse(FROM_NETWORK.name(), "network1,network2");
+ try
+ {
+ _aclRulePredicates.parse(FROM_HOSTNAME.name(), "hostname1,hostname2");
+ fail("Exception not thrown");
+ }
+ catch(IllegalStateException e)
+ {
+ // pass
+ }
+ }
+}
diff --git a/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/config/ActionTest.java b/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/config/ActionTest.java
new file mode 100644
index 0000000000..00e06106bf
--- /dev/null
+++ b/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/config/ActionTest.java
@@ -0,0 +1,95 @@
+/*
+ * 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.access.config;
+
+import static org.mockito.Mockito.*;
+
+import org.apache.qpid.server.security.access.ObjectProperties;
+import org.apache.qpid.server.security.access.ObjectType;
+import org.apache.qpid.server.security.access.Operation;
+
+import junit.framework.TestCase;
+
+public class ActionTest extends TestCase
+{
+ private ObjectProperties _properties1 = mock(ObjectProperties.class);
+ private ObjectProperties _properties2 = mock(ObjectProperties.class);
+
+ public void testMatchesReturnsTrueForMatchingActions()
+ {
+ when(_properties1.matches(_properties2)).thenReturn(true);
+
+ assertMatches(
+ new Action(Operation.CONSUME, ObjectType.QUEUE, _properties1),
+ new Action(Operation.CONSUME, ObjectType.QUEUE, _properties2));
+ }
+
+ public void testMatchesReturnsFalseWhenOperationsDiffer()
+ {
+ assertDoesntMatch(
+ new Action(Operation.CONSUME, ObjectType.QUEUE, _properties1),
+ new Action(Operation.CREATE, ObjectType.QUEUE, _properties1));
+ }
+
+ public void testMatchesReturnsFalseWhenOperationTypesDiffer()
+ {
+ assertDoesntMatch(
+ new Action(Operation.CREATE, ObjectType.QUEUE, _properties1),
+ new Action(Operation.CREATE, ObjectType.EXCHANGE, _properties1));
+ }
+
+ public void testMatchesReturnsFalseWhenOperationPropertiesDiffer()
+ {
+ assertDoesntMatch(
+ new Action(Operation.CREATE, ObjectType.QUEUE, _properties1),
+ new Action(Operation.CREATE, ObjectType.QUEUE, _properties2));
+ }
+
+ public void testMatchesReturnsFalseWhenMyOperationPropertiesIsNull()
+ {
+ assertDoesntMatch(
+ new Action(Operation.CREATE, ObjectType.QUEUE, (ObjectProperties)null),
+ new Action(Operation.CREATE, ObjectType.QUEUE, _properties1));
+ }
+
+ public void testMatchesReturnsFalseWhenOtherOperationPropertiesIsNull()
+ {
+ assertDoesntMatch(
+ new Action(Operation.CREATE, ObjectType.QUEUE, _properties1),
+ new Action(Operation.CREATE, ObjectType.QUEUE, (ObjectProperties)null));
+ }
+
+ public void testMatchesReturnsTrueWhenBothOperationPropertiesAreNull()
+ {
+ assertMatches(
+ new Action(Operation.CREATE, ObjectType.QUEUE, (ObjectProperties)null),
+ new Action(Operation.CREATE, ObjectType.QUEUE, (ObjectProperties)null));
+ }
+
+ private void assertMatches(Action action1, Action action2)
+ {
+ assertTrue(action1 + " should match " + action2, action1.matches(action2));
+ }
+
+ private void assertDoesntMatch(Action action1, Action action2)
+ {
+ assertFalse(action1 + " should not match " + action2, action1.matches(action2));
+ }
+
+}
diff --git a/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/config/ClientActionTest.java b/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/config/ClientActionTest.java
new file mode 100644
index 0000000000..ae5d3fda74
--- /dev/null
+++ b/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/config/ClientActionTest.java
@@ -0,0 +1,79 @@
+/*
+ * 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.access.config;
+
+import static org.mockito.Mockito.*;
+
+import java.net.InetAddress;
+
+import org.apache.qpid.server.security.access.firewall.FirewallRule;
+
+import junit.framework.TestCase;
+
+public class ClientActionTest extends TestCase
+{
+ private Action _action = mock(Action.class);
+ private AclAction _ruleAction = mock(AclAction.class);
+ private InetAddress _addressOfClient = mock(InetAddress.class);
+
+ private ClientAction _clientAction = new ClientAction(_action);
+
+ public void testMatches_returnsTrueWhenActionsMatchAndNoFirewallRule()
+ {
+ when(_action.matches(any(Action.class))).thenReturn(true);
+ when(_ruleAction.getFirewallRule()).thenReturn(null);
+
+ assertTrue(_clientAction.matches(_ruleAction, _addressOfClient));
+ }
+
+ public void testMatches_returnsFalseWhenActionsDontMatch()
+ {
+ FirewallRule firewallRule = mock(FirewallRule.class);
+ when(firewallRule.matches(_addressOfClient)).thenReturn(true);
+
+ when(_action.matches(any(Action.class))).thenReturn(false);
+ when(_ruleAction.getFirewallRule()).thenReturn(firewallRule);
+
+ assertFalse(_clientAction.matches(_ruleAction, _addressOfClient));
+ }
+
+ public void testMatches_returnsTrueWhenActionsAndFirewallRuleMatch()
+ {
+ FirewallRule firewallRule = mock(FirewallRule.class);
+ when(firewallRule.matches(_addressOfClient)).thenReturn(true);
+
+ when(_action.matches(any(Action.class))).thenReturn(true);
+ when(_ruleAction.getFirewallRule()).thenReturn(firewallRule);
+
+ assertTrue(_clientAction.matches(_ruleAction, _addressOfClient));
+ }
+
+ public void testMatches_ignoresFirewallRuleIfClientAddressIsNull()
+ {
+ FirewallRule firewallRule = mock(FirewallRule.class);
+
+ when(_action.matches(any(Action.class))).thenReturn(true);
+ when(_ruleAction.getFirewallRule()).thenReturn(firewallRule);
+
+ assertTrue(_clientAction.matches(_ruleAction, null));
+
+ verifyZeroInteractions(firewallRule);
+ }
+
+}
diff --git a/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/PlainConfigurationTest.java b/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/config/PlainConfigurationTest.java
index c2282694fb..cbfc9003c8 100644
--- a/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/PlainConfigurationTest.java
+++ b/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/config/PlainConfigurationTest.java
@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.qpid.server.security.access.plugins;
+package org.apache.qpid.server.security.access.config;
import java.io.File;
import java.io.FileNotFoundException;
@@ -26,7 +26,7 @@ import java.util.Map;
import junit.framework.TestCase;
-import org.apache.commons.configuration.ConfigurationException;
+import org.apache.qpid.server.configuration.IllegalConfigurationException;
import org.apache.qpid.server.security.access.ObjectProperties;
import org.apache.qpid.server.security.access.ObjectProperties.Property;
import org.apache.qpid.server.security.access.ObjectType;
@@ -73,7 +73,7 @@ public class PlainConfigurationTest extends TestCase
fail("fail");
}
- catch (ConfigurationException ce)
+ catch (IllegalConfigurationException ce)
{
assertEquals(String.format(PlainConfiguration.CONFIG_NOT_FOUND_MSG, "doesnotexist"), ce.getMessage());
assertTrue(ce.getCause() instanceof FileNotFoundException);
@@ -87,7 +87,7 @@ public class PlainConfigurationTest extends TestCase
writeACLConfig("ACL ALLOW ALL \\ ALL");
fail("fail");
}
- catch (ConfigurationException ce)
+ catch (IllegalConfigurationException ce)
{
assertEquals(String.format(PlainConfiguration.PREMATURE_CONTINUATION_MSG, 1), ce.getMessage());
}
@@ -100,7 +100,7 @@ public class PlainConfigurationTest extends TestCase
writeACLConfig("ACL unparsed ALL ALL");
fail("fail");
}
- catch (ConfigurationException ce)
+ catch (IllegalConfigurationException ce)
{
assertEquals(String.format(PlainConfiguration.PARSE_TOKEN_FAILED_MSG, 1), ce.getMessage());
assertTrue(ce.getCause() instanceof IllegalArgumentException);
@@ -108,19 +108,6 @@ public class PlainConfigurationTest extends TestCase
}
}
- public void testACLFileSyntaxNotEnoughGroup() throws Exception
- {
- try
- {
- writeACLConfig("GROUP blah");
- fail("fail");
- }
- catch (ConfigurationException ce)
- {
- assertEquals(String.format(PlainConfiguration.NOT_ENOUGH_GROUP_MSG, 1), ce.getMessage());
- }
- }
-
public void testACLFileSyntaxNotEnoughACL() throws Exception
{
try
@@ -128,7 +115,7 @@ public class PlainConfigurationTest extends TestCase
writeACLConfig("ACL ALLOW");
fail("fail");
}
- catch (ConfigurationException ce)
+ catch (IllegalConfigurationException ce)
{
assertEquals(String.format(PlainConfiguration.NOT_ENOUGH_ACL_MSG, 1), ce.getMessage());
}
@@ -141,7 +128,7 @@ public class PlainConfigurationTest extends TestCase
writeACLConfig("CONFIG");
fail("fail");
}
- catch (ConfigurationException ce)
+ catch (IllegalConfigurationException ce)
{
assertEquals(String.format(PlainConfiguration.NOT_ENOUGH_TOKENS_MSG, 1), ce.getMessage());
}
@@ -154,7 +141,7 @@ public class PlainConfigurationTest extends TestCase
writeACLConfig("INVALID");
fail("fail");
}
- catch (ConfigurationException ce)
+ catch (IllegalConfigurationException ce)
{
assertEquals(String.format(PlainConfiguration.NOT_ENOUGH_TOKENS_MSG, 1), ce.getMessage());
}
@@ -167,7 +154,7 @@ public class PlainConfigurationTest extends TestCase
writeACLConfig("ACL ALLOW adk CREATE QUEUE name");
fail("fail");
}
- catch (ConfigurationException ce)
+ catch (IllegalConfigurationException ce)
{
assertEquals(String.format(PlainConfiguration.PROPERTY_KEY_ONLY_MSG, 1), ce.getMessage());
}
@@ -180,7 +167,7 @@ public class PlainConfigurationTest extends TestCase
writeACLConfig("ACL ALLOW adk CREATE QUEUE name test");
fail("fail");
}
- catch (ConfigurationException ce)
+ catch (IllegalConfigurationException ce)
{
assertEquals(String.format(PlainConfiguration.PROPERTY_NO_EQUALS_MSG, 1), ce.getMessage());
}
@@ -193,7 +180,7 @@ public class PlainConfigurationTest extends TestCase
writeACLConfig("ACL ALLOW adk CREATE QUEUE name =");
fail("fail");
}
- catch (ConfigurationException ce)
+ catch (IllegalConfigurationException ce)
{
assertEquals(String.format(PlainConfiguration.PROPERTY_NO_VALUE_MSG, 1), ce.getMessage());
}
@@ -391,4 +378,86 @@ public class PlainConfigurationTest extends TestCase
assertEquals("Rule has unexpected object properties", ObjectProperties.EMPTY, rule.getAction().getProperties());
}
+ public void testUserRuleParsing() throws Exception
+ {
+ validateRule(writeACLConfig("ACL ALLOW user1 CREATE USER"),
+ "user1", Operation.CREATE, ObjectType.USER, ObjectProperties.EMPTY);
+ validateRule(writeACLConfig("ACL ALLOW user1 CREATE USER name=\"otherUser\""),
+ "user1", Operation.CREATE, ObjectType.USER, new ObjectProperties("otherUser"));
+
+ validateRule(writeACLConfig("ACL ALLOW user1 DELETE USER"),
+ "user1", Operation.DELETE, ObjectType.USER, ObjectProperties.EMPTY);
+ validateRule(writeACLConfig("ACL ALLOW user1 DELETE USER name=\"otherUser\""),
+ "user1", Operation.DELETE, ObjectType.USER, new ObjectProperties("otherUser"));
+
+ validateRule(writeACLConfig("ACL ALLOW user1 UPDATE USER"),
+ "user1", Operation.UPDATE, ObjectType.USER, ObjectProperties.EMPTY);
+ validateRule(writeACLConfig("ACL ALLOW user1 UPDATE USER name=\"otherUser\""),
+ "user1", Operation.UPDATE, ObjectType.USER, new ObjectProperties("otherUser"));
+
+ validateRule(writeACLConfig("ACL ALLOW user1 ALL USER"),
+ "user1", Operation.ALL, ObjectType.USER, ObjectProperties.EMPTY);
+ validateRule(writeACLConfig("ACL ALLOW user1 ALL USER name=\"otherUser\""),
+ "user1", Operation.ALL, ObjectType.USER, new ObjectProperties("otherUser"));
+ }
+
+ public void testGroupRuleParsing() throws Exception
+ {
+ validateRule(writeACLConfig("ACL ALLOW user1 CREATE GROUP"),
+ "user1", Operation.CREATE, ObjectType.GROUP, ObjectProperties.EMPTY);
+ validateRule(writeACLConfig("ACL ALLOW user1 CREATE GROUP name=\"groupName\""),
+ "user1", Operation.CREATE, ObjectType.GROUP, new ObjectProperties("groupName"));
+
+ validateRule(writeACLConfig("ACL ALLOW user1 DELETE GROUP"),
+ "user1", Operation.DELETE, ObjectType.GROUP, ObjectProperties.EMPTY);
+ validateRule(writeACLConfig("ACL ALLOW user1 DELETE GROUP name=\"groupName\""),
+ "user1", Operation.DELETE, ObjectType.GROUP, new ObjectProperties("groupName"));
+
+ validateRule(writeACLConfig("ACL ALLOW user1 UPDATE GROUP"),
+ "user1", Operation.UPDATE, ObjectType.GROUP, ObjectProperties.EMPTY);
+ validateRule(writeACLConfig("ACL ALLOW user1 UPDATE GROUP name=\"groupName\""),
+ "user1", Operation.UPDATE, ObjectType.GROUP, new ObjectProperties("groupName"));
+
+ validateRule(writeACLConfig("ACL ALLOW user1 ALL GROUP"),
+ "user1", Operation.ALL, ObjectType.GROUP, ObjectProperties.EMPTY);
+ validateRule(writeACLConfig("ACL ALLOW user1 ALL GROUP name=\"groupName\""),
+ "user1", Operation.ALL, ObjectType.GROUP, new ObjectProperties("groupName"));
+ }
+
+ /** explicitly test for exception indicating that this functionality has been moved to Group Providers */
+ public void testGroupDefinitionThrowsException() throws Exception
+ {
+ try
+ {
+ writeACLConfig("GROUP group1 bob alice");
+ fail("Expected exception not thrown");
+ }
+ catch(IllegalConfigurationException e)
+ {
+ assertTrue(e.getMessage().contains("GROUP keyword not supported"));
+ }
+ }
+
+ public void testManagementRuleParsing() throws Exception
+ {
+ validateRule(writeACLConfig("ACL ALLOW user1 ALL MANAGEMENT"),
+ "user1", Operation.ALL, ObjectType.MANAGEMENT, ObjectProperties.EMPTY);
+
+ validateRule(writeACLConfig("ACL ALLOW user1 ACCESS MANAGEMENT"),
+ "user1", Operation.ACCESS, ObjectType.MANAGEMENT, ObjectProperties.EMPTY);
+ }
+
+ private void validateRule(final PlainConfiguration config, String username, Operation operation, ObjectType objectType, ObjectProperties objectProperties)
+ {
+ final RuleSet rs = config.getConfiguration();
+ assertEquals(1, rs.getRuleCount());
+
+ final Map<Integer, Rule> rules = rs.getAllRules();
+ assertEquals(1, rules.size());
+ final Rule rule = rules.get(0);
+ assertEquals("Rule has unexpected identity", username, rule.getIdentity());
+ assertEquals("Rule has unexpected operation", operation, rule.getAction().getOperation());
+ assertEquals("Rule has unexpected operation", objectType, rule.getAction().getObjectType());
+ assertEquals("Rule has unexpected object properties", objectProperties, rule.getAction().getProperties());
+ }
}
diff --git a/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/config/RuleTest.java b/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/config/RuleTest.java
new file mode 100644
index 0000000000..2ae7759679
--- /dev/null
+++ b/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/config/RuleTest.java
@@ -0,0 +1,53 @@
+/*
+ * 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.access.config;
+
+import static org.mockito.Mockito.*;
+
+import org.apache.qpid.server.security.access.Permission;
+
+import junit.framework.TestCase;
+
+public class RuleTest extends TestCase
+{
+ public void testEqualsAndHashCode()
+ {
+ AclAction aclAction = mock(AclAction.class);
+ String identity = "identity";
+ Permission allow = Permission.ALLOW;
+
+ Rule rule = new Rule(identity, aclAction, allow);
+ Rule equalRule = new Rule(identity, aclAction, allow);
+
+ assertTrue(rule.equals(rule));
+ assertTrue(rule.equals(equalRule));
+ assertTrue(equalRule.equals(rule));
+
+ assertTrue(rule.hashCode() == equalRule.hashCode());
+
+ assertFalse("Different identity should cause rules to be unequal",
+ rule.equals(new Rule("identity2", aclAction, allow)));
+
+ assertFalse("Different action should cause rules to be unequal",
+ rule.equals(new Rule(identity, mock(AclAction.class), allow)));
+
+ assertFalse("Different permission should cause rules to be unequal",
+ rule.equals(new Rule(identity, aclAction, Permission.DENY)));
+ }
+}
diff --git a/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/firewall/HostnameFirewallRuleTest.java b/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/firewall/HostnameFirewallRuleTest.java
new file mode 100644
index 0000000000..be82cb294a
--- /dev/null
+++ b/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/firewall/HostnameFirewallRuleTest.java
@@ -0,0 +1,99 @@
+/*
+ * 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.access.firewall;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.net.InetAddress;
+
+import org.apache.qpid.server.security.access.firewall.HostnameFirewallRule;
+
+import junit.framework.TestCase;
+
+public class HostnameFirewallRuleTest extends TestCase
+{
+ private InetAddress _addressNotInRule;
+
+ private HostnameFirewallRule _HostnameFirewallRule;
+
+ @Override
+ protected void setUp() throws Exception
+ {
+ _addressNotInRule = InetAddress.getByName("127.0.0.1");
+ }
+
+ public void testSingleHostname() throws Exception
+ {
+ String hostnameInRule = "hostnameInRule";
+ InetAddress addressWithMatchingHostname = mock(InetAddress.class);
+ when(addressWithMatchingHostname.getCanonicalHostName()).thenReturn(hostnameInRule);
+
+ _HostnameFirewallRule = new HostnameFirewallRule(hostnameInRule);
+
+ assertFalse(_HostnameFirewallRule.matches(_addressNotInRule));
+ assertTrue(_HostnameFirewallRule.matches(addressWithMatchingHostname));
+ }
+
+ public void testSingleHostnameWilcard() throws Exception
+ {
+ String hostnameInRule = ".*FOO.*";
+ InetAddress addressWithMatchingHostname = mock(InetAddress.class);
+ when(addressWithMatchingHostname.getCanonicalHostName()).thenReturn("xxFOOxx");
+
+ _HostnameFirewallRule = new HostnameFirewallRule(hostnameInRule);
+
+ assertFalse(_HostnameFirewallRule.matches(_addressNotInRule));
+ assertTrue(_HostnameFirewallRule.matches(addressWithMatchingHostname));
+ }
+
+ public void testMultipleHostnames() throws Exception
+ {
+ String[] hostnamesInRule = new String[] {"hostnameInRule1", "hostnameInRule2"};
+
+ _HostnameFirewallRule = new HostnameFirewallRule(hostnamesInRule);
+
+ assertFalse(_HostnameFirewallRule.matches(_addressNotInRule));
+ for (String hostnameInRule : hostnamesInRule)
+ {
+ InetAddress addressWithMatchingHostname = mock(InetAddress.class);
+ when(addressWithMatchingHostname.getCanonicalHostName()).thenReturn(hostnameInRule);
+
+ assertTrue(_HostnameFirewallRule.matches(addressWithMatchingHostname));
+ }
+ }
+
+ public void testEqualsAndHashCode()
+ {
+ String hostname1 = "hostname1";
+ String hostname2 = "hostname2";
+
+ HostnameFirewallRule rule = new HostnameFirewallRule(hostname1, hostname2);
+ HostnameFirewallRule equalRule = new HostnameFirewallRule(hostname1, hostname2);
+
+ assertTrue(rule.equals(rule));
+ assertTrue(rule.equals(equalRule));
+ assertTrue(equalRule.equals(rule));
+
+ assertTrue(rule.hashCode() == equalRule.hashCode());
+
+ assertFalse("Different hostnames should cause rules to be unequal",
+ rule.equals(new HostnameFirewallRule(hostname1, "different-hostname")));
+ }
+}
diff --git a/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/firewall/NetworkFirewallRuleTest.java b/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/firewall/NetworkFirewallRuleTest.java
new file mode 100644
index 0000000000..e521039db2
--- /dev/null
+++ b/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/firewall/NetworkFirewallRuleTest.java
@@ -0,0 +1,115 @@
+/*
+ * 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.access.firewall;
+
+import java.net.InetAddress;
+
+import org.apache.qpid.server.security.access.firewall.NetworkFirewallRule;
+
+import junit.framework.TestCase;
+
+public class NetworkFirewallRuleTest extends TestCase
+{
+ private static final String LOCALHOST_IP = "127.0.0.1";
+ private static final String OTHER_IP_1 = "192.168.23.1";
+ private static final String OTHER_IP_2 = "192.168.23.2";
+
+ private InetAddress _addressNotInRule;
+
+ private NetworkFirewallRule _networkFirewallRule;
+
+ @Override
+ protected void setUp() throws Exception
+ {
+ _addressNotInRule = InetAddress.getByName(LOCALHOST_IP);
+ }
+
+ public void testIpRule() throws Exception
+ {
+ String ipAddressInRule = OTHER_IP_1;
+
+ _networkFirewallRule = new NetworkFirewallRule(ipAddressInRule);
+
+ assertFalse(_networkFirewallRule.matches(_addressNotInRule));
+ assertTrue(_networkFirewallRule.matches(InetAddress.getByName(ipAddressInRule)));
+ }
+
+ public void testNetMask() throws Exception
+ {
+ String ipAddressInRule = "192.168.23.0/24";
+ _networkFirewallRule = new NetworkFirewallRule(ipAddressInRule);
+
+ assertFalse(_networkFirewallRule.matches(InetAddress.getByName("192.168.24.1")));
+ assertTrue(_networkFirewallRule.matches(InetAddress.getByName("192.168.23.0")));
+ assertTrue(_networkFirewallRule.matches(InetAddress.getByName("192.168.23.255")));
+ }
+
+ public void testWildcard() throws Exception
+ {
+ // Test xxx.xxx.*
+
+ assertFalse(new NetworkFirewallRule("192.168.*")
+ .matches(InetAddress.getByName("192.169.1.0")));
+
+ assertTrue(new NetworkFirewallRule("192.168.*")
+ .matches(InetAddress.getByName("192.168.1.0")));
+
+ assertTrue(new NetworkFirewallRule("192.168.*")
+ .matches(InetAddress.getByName("192.168.255.255")));
+
+ // Test xxx.xxx.xxx.*
+
+ assertFalse(new NetworkFirewallRule("192.168.1.*")
+ .matches(InetAddress.getByName("192.169.2.0")));
+
+ assertTrue(new NetworkFirewallRule("192.168.1.*")
+ .matches(InetAddress.getByName("192.168.1.0")));
+
+ assertTrue(new NetworkFirewallRule("192.168.1.*")
+ .matches(InetAddress.getByName("192.168.1.255")));
+ }
+
+ public void testMultipleNetworks() throws Exception
+ {
+ String[] ipAddressesInRule = new String[] {OTHER_IP_1, OTHER_IP_2};
+
+ _networkFirewallRule = new NetworkFirewallRule(ipAddressesInRule);
+
+ assertFalse(_networkFirewallRule.matches(_addressNotInRule));
+ for (String ipAddressInRule : ipAddressesInRule)
+ {
+ assertTrue(_networkFirewallRule.matches(InetAddress.getByName(ipAddressInRule)));
+ }
+ }
+
+ public void testEqualsAndHashCode()
+ {
+ NetworkFirewallRule rule = new NetworkFirewallRule(LOCALHOST_IP, OTHER_IP_1);
+ NetworkFirewallRule equalRule = new NetworkFirewallRule(LOCALHOST_IP, OTHER_IP_1);
+
+ assertTrue(rule.equals(rule));
+ assertTrue(rule.equals(equalRule));
+ assertTrue(equalRule.equals(rule));
+
+ assertTrue(rule.hashCode() == equalRule.hashCode());
+
+ assertFalse("Different networks should cause rules to be unequal",
+ rule.equals(new NetworkFirewallRule(LOCALHOST_IP, OTHER_IP_2)));
+ }
+}
diff --git a/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/DefaultAccessControlFactoryTest.java b/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/DefaultAccessControlFactoryTest.java
new file mode 100644
index 0000000000..ca1f19098f
--- /dev/null
+++ b/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/DefaultAccessControlFactoryTest.java
@@ -0,0 +1,69 @@
+package org.apache.qpid.server.security.access.plugins;
+
+import java.io.File;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.regex.Pattern;
+
+import org.apache.qpid.server.configuration.IllegalConfigurationException;
+import org.apache.qpid.server.security.AccessControl;
+import org.apache.qpid.test.utils.QpidTestCase;
+import org.apache.qpid.test.utils.TestFileUtils;
+
+public class DefaultAccessControlFactoryTest extends QpidTestCase
+{
+ public void testCreateInstanceWhenAclFileIsNotPresent()
+ {
+ DefaultAccessControlFactory factory = new DefaultAccessControlFactory();
+ Map<String, Object> attributes = new HashMap<String, Object>();
+ AccessControl acl = factory.createInstance(attributes);
+ assertNull("ACL was created without a configuration file", acl);
+ }
+
+ public void testCreateInstanceWhenAclFileIsSpecified()
+ {
+ File aclFile = TestFileUtils.createTempFile(this, ".acl", "ACL ALLOW all all");
+ DefaultAccessControlFactory factory = new DefaultAccessControlFactory();
+ Map<String, Object> attributes = new HashMap<String, Object>();
+ attributes.put(DefaultAccessControlFactory.ATTRIBUTE_ACL_FILE, aclFile.getAbsolutePath());
+ AccessControl acl = factory.createInstance(attributes);
+
+ assertNotNull("ACL was not created from acl file: " + aclFile.getAbsolutePath(), acl);
+ }
+
+ public void testCreateInstanceWhenAclFileIsSpecifiedButDoesNotExist()
+ {
+ File aclFile = new File(TMP_FOLDER, "my-non-existing-acl-" + System.currentTimeMillis());
+ assertFalse("ACL file " + aclFile.getAbsolutePath() + " actually exists but should not", aclFile.exists());
+ DefaultAccessControlFactory factory = new DefaultAccessControlFactory();
+ Map<String, Object> attributes = new HashMap<String, Object>();
+ attributes.put(DefaultAccessControlFactory.ATTRIBUTE_ACL_FILE, aclFile.getAbsolutePath());
+ try
+ {
+ factory.createInstance(attributes);
+ fail("It should not be possible to create ACL from non existing file");
+ }
+ catch (IllegalConfigurationException e)
+ {
+ assertTrue("Unexpected exception message", Pattern.matches("ACL file '.*' is not found", e.getMessage()));
+ }
+ }
+
+ public void testCreateInstanceWhenAclFileIsSpecifiedAsNonString()
+ {
+ DefaultAccessControlFactory factory = new DefaultAccessControlFactory();
+ Map<String, Object> attributes = new HashMap<String, Object>();
+ Integer aclFile = new Integer(0);
+ attributes.put(DefaultAccessControlFactory.ATTRIBUTE_ACL_FILE, aclFile);
+ try
+ {
+ factory.createInstance(attributes);
+ fail("It should not be possible to create ACL from Integer");
+ }
+ catch (IllegalConfigurationException e)
+ {
+ assertEquals("Unexpected exception message", "Expected '" + DefaultAccessControlFactory.ATTRIBUTE_ACL_FILE
+ + "' attribute value of type String but was " + Integer.class + ": " + aclFile, e.getMessage());
+ }
+ }
+}
diff --git a/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/AccessControlTest.java b/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/DefaultAccessControlTest.java
index 5db02d10ce..a8406308c0 100644
--- a/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/AccessControlTest.java
+++ b/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/DefaultAccessControlTest.java
@@ -20,12 +20,16 @@
*/
package org.apache.qpid.server.security.access.plugins;
-import java.util.Arrays;
+import static org.mockito.Mockito.*;
+
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+
+import javax.security.auth.Subject;
import junit.framework.TestCase;
import org.apache.commons.configuration.ConfigurationException;
-import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin;
import org.apache.qpid.server.logging.UnitTestMessageLogger;
import org.apache.qpid.server.logging.actors.CurrentActor;
import org.apache.qpid.server.logging.actors.TestLogActor;
@@ -37,20 +41,19 @@ import org.apache.qpid.server.security.access.Operation;
import org.apache.qpid.server.security.access.Permission;
import org.apache.qpid.server.security.access.config.Rule;
import org.apache.qpid.server.security.access.config.RuleSet;
-import org.apache.qpid.server.security.auth.sasl.TestPrincipalUtils;
+import org.apache.qpid.server.security.auth.TestPrincipalUtils;
/**
- * Unit test for ACL V2 plugin.
- *
- * This unit test tests the AccessControl class and it collaboration with {@link RuleSet},
- * {@link SecurityManager} and {@link CurrentActor}. The ruleset is configured programmatically,
- * rather than from an external file.
- *
+ * In these tests, the ruleset is configured programmatically rather than from an external file.
+ *
* @see RuleSetTest
*/
-public class AccessControlTest extends TestCase
+public class DefaultAccessControlTest extends TestCase
{
- private AccessControl _plugin = null; // Class under test
+ private static final String ALLOWED_GROUP = "allowed_group";
+ private static final String DENIED_GROUP = "denied_group";
+
+ private DefaultAccessControl _plugin = null; // Class under test
private final UnitTestMessageLogger messageLogger = new UnitTestMessageLogger();
private void setUpGroupAccessControl() throws ConfigurationException
@@ -60,7 +63,7 @@ public class AccessControlTest extends TestCase
private void configureAccessControl(final RuleSet rs) throws ConfigurationException
{
- _plugin = (AccessControl) AccessControl.FACTORY.newInstance(createConfiguration(rs));
+ _plugin = new DefaultAccessControl(rs);
SecurityManager.setThreadSubject(null);
CurrentActor.set(new TestLogActor(messageLogger));
}
@@ -68,14 +71,12 @@ public class AccessControlTest extends TestCase
private RuleSet createGroupRuleSet()
{
final RuleSet rs = new RuleSet();
- rs.addGroup("aclGroup1", Arrays.asList(new String[] {"member1", "Member2"}));
// Rule expressed with username
rs.grant(0, "user1", Permission.ALLOW, Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY);
- // Rule expressed with a acl group
- rs.grant(1, "aclGroup1", Permission.ALLOW, Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY);
- // Rule expressed with an external group
- rs.grant(2, "extGroup1", Permission.DENY, Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY);
+ // Rules expressed with groups
+ rs.grant(1, ALLOWED_GROUP, Permission.ALLOW, Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY);
+ rs.grant(2, DENIED_GROUP, Permission.DENY, Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY);
// Catch all rule
rs.grant(3, Rule.ALL, Permission.DENY_LOG, Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY);
@@ -117,31 +118,23 @@ public class AccessControlTest extends TestCase
* Tests that an allow rule expressed with an <b>ACL groupname</b> allows an operation performed by a thread running
* by a user who belongs to the same group..
*/
- public void testAclGroupMembershipAllowsOperation() throws ConfigurationException
+ public void testGroupMembershipAllowsOperation() throws ConfigurationException
{
setUpGroupAccessControl();
- SecurityManager.setThreadSubject(TestPrincipalUtils.createTestSubject("member1"));
- Result result = _plugin.authorise(Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY);
- assertEquals(Result.ALLOWED, result);
-
- SecurityManager.setThreadSubject(TestPrincipalUtils.createTestSubject("Member2"));
-
- result = _plugin.authorise(Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY);
- assertEquals(Result.ALLOWED, result);
+ authoriseAndAssertResult(Result.ALLOWED, "member of allowed group", ALLOWED_GROUP);
+ authoriseAndAssertResult(Result.DENIED, "member of denied group", DENIED_GROUP);
+ authoriseAndAssertResult(Result.ALLOWED, "another member of allowed group", ALLOWED_GROUP);
}
/**
- * Tests that a deny rule expressed with an <b>External groupname</b> denies an operation performed by a thread running
+ * Tests that a deny rule expressed with a <b>groupname</b> denies an operation performed by a thread running
* by a user who belongs to the same group.
*/
- public void testExternalGroupMembershipDeniesOperation() throws ConfigurationException
+ public void testGroupMembershipDeniesOperation() throws ConfigurationException
{
setUpGroupAccessControl();
- SecurityManager.setThreadSubject(TestPrincipalUtils.createTestSubject("user3", "extGroup1"));
-
- final Result result = _plugin.authorise(Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY);
- assertEquals(Result.DENIED, result);
+ authoriseAndAssertResult(Result.DENIED, "user3", DENIED_GROUP);
}
/**
@@ -203,6 +196,46 @@ public class AccessControlTest extends TestCase
assertEquals(Result.DEFER, result);
}
+ public void testAccess() throws Exception
+ {
+ Subject subject = TestPrincipalUtils.createTestSubject("user1");
+ SecurityManager.setThreadSubject(subject);
+
+ RuleSet mockRuleSet = mock(RuleSet.class);
+
+ InetAddress inetAddress = InetAddress.getLocalHost();
+ InetSocketAddress inetSocketAddress = new InetSocketAddress(inetAddress, 1);
+
+ DefaultAccessControl accessControl = new DefaultAccessControl(mockRuleSet);
+
+ accessControl.access(ObjectType.VIRTUALHOST, inetSocketAddress);
+
+ verify(mockRuleSet).check(subject, Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY, inetAddress);
+ }
+
+ public void testAccessIsDeniedIfRuleThrowsException() throws Exception
+ {
+ Subject subject = TestPrincipalUtils.createTestSubject("user1");
+ SecurityManager.setThreadSubject(subject);
+
+ InetAddress inetAddress = InetAddress.getLocalHost();
+ InetSocketAddress inetSocketAddress = new InetSocketAddress(inetAddress, 1);
+
+ RuleSet mockRuleSet = mock(RuleSet.class);
+ when(mockRuleSet.check(
+ subject,
+ Operation.ACCESS,
+ ObjectType.VIRTUALHOST,
+ ObjectProperties.EMPTY,
+ inetAddress)).thenThrow(new RuntimeException());
+
+ DefaultAccessControl accessControl = new DefaultAccessControl(mockRuleSet);
+ Result result = accessControl.access(ObjectType.VIRTUALHOST, inetSocketAddress);
+
+ assertEquals(Result.DENIED, result);
+ }
+
+
/**
* Tests that a grant access method rule allows any access operation to be performed on a specified component
*/
@@ -325,31 +358,11 @@ public class AccessControlTest extends TestCase
assertEquals(Result.DEFER, result);
}
- /**
- * Creates a configuration plugin for the {@link AccessControl} plugin.
- */
- private ConfigurationPlugin createConfiguration(final RuleSet rs)
+ private void authoriseAndAssertResult(Result expectedResult, String userName, String... groups)
{
- final ConfigurationPlugin cp = new ConfigurationPlugin()
- {
- @SuppressWarnings("unchecked")
- public AccessControlConfiguration getConfiguration(final String plugin)
- {
- return new AccessControlConfiguration()
- {
- public RuleSet getRuleSet()
- {
- return rs;
- }
- };
- }
-
- public String[] getElementsProcessed()
- {
- throw new UnsupportedOperationException();
- }
- };
-
- return cp;
+ SecurityManager.setThreadSubject(TestPrincipalUtils.createTestSubject(userName, groups));
+
+ Result result = _plugin.authorise(Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY);
+ assertEquals(expectedResult, result);
}
}
diff --git a/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/RuleSetTest.java b/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/RuleSetTest.java
index f7cc60543d..181d693614 100644
--- a/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/RuleSetTest.java
+++ b/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/RuleSetTest.java
@@ -22,7 +22,6 @@
package org.apache.qpid.server.security.access.plugins;
import java.security.Principal;
-import java.util.Arrays;
import javax.security.auth.Subject;
@@ -34,8 +33,7 @@ import org.apache.qpid.server.security.access.Operation;
import org.apache.qpid.server.security.access.Permission;
import org.apache.qpid.server.security.access.config.Rule;
import org.apache.qpid.server.security.access.config.RuleSet;
-import org.apache.qpid.server.security.auth.sasl.TestPrincipalUtils;
-import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal;
+import org.apache.qpid.server.security.auth.TestPrincipalUtils;
import org.apache.qpid.test.utils.QpidTestCase;
/**
@@ -46,10 +44,7 @@ import org.apache.qpid.test.utils.QpidTestCase;
* access control mechanism is validated by checking whether operations would be authorised by calling the
* {@link RuleSet#check(Principal, Operation, ObjectType, ObjectProperties)} method.
*
- * It ensure that permissions can be granted correctly on users directly, ACL groups (that is those
- * groups declared directly in the ACL itself), and External groups (that is a group from an External
- * Authentication Provider, such as an LDAP).
-
+ * It ensure that permissions can be granted correctly on users directly and on groups.
*/
public class RuleSetTest extends QpidTestCase
{
@@ -316,63 +311,36 @@ public class RuleSetTest extends QpidTestCase
assertEquals(Result.ALLOWED, _ruleSet.check(TestPrincipalUtils.createTestSubject("userb"),Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY));
}
- /**
- * Tests support for ACL groups (i.e. inline groups declared in the ACL file itself).
- */
- public void testAclGroupsSupported()
+ public void testGroupsSupported()
{
- assertTrue(_ruleSet.addGroup("aclgroup", Arrays.asList(new String[] {"usera", "userb"})));
-
- _ruleSet.grant(1, "aclgroup", Permission.ALLOW, Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY);
- assertEquals(1, _ruleSet.getRuleCount());
-
- assertEquals(Result.ALLOWED, _ruleSet.check(TestPrincipalUtils.createTestSubject("usera"),Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY));
- assertEquals(Result.ALLOWED, _ruleSet.check(TestPrincipalUtils.createTestSubject("userb"),Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY));
- assertEquals(Result.DEFER, _ruleSet.check(TestPrincipalUtils.createTestSubject("userc"),Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY));
- }
-
- /**
- * Tests support for nested ACL groups.
- */
- public void testNestedAclGroupsSupported()
- {
- assertTrue(_ruleSet.addGroup("aclgroup1", Arrays.asList(new String[] {"userb"})));
- assertTrue(_ruleSet.addGroup("aclgroup2", Arrays.asList(new String[] {"usera", "aclgroup1"})));
-
- _ruleSet.grant(1, "aclgroup2", Permission.ALLOW, Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY);
- assertEquals(1, _ruleSet.getRuleCount());
+ String allowGroup = "allowGroup";
+ String deniedGroup = "deniedGroup";
- assertEquals(Result.ALLOWED, _ruleSet.check(TestPrincipalUtils.createTestSubject("usera"),Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY));
- assertEquals(Result.ALLOWED, _ruleSet.check(TestPrincipalUtils.createTestSubject("userb"),Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY));
- }
+ _ruleSet.grant(1, allowGroup, Permission.ALLOW, Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY);
+ _ruleSet.grant(2, deniedGroup, Permission.DENY, Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY);
- /**
- * Tests support for nested External groups (i.e. those groups coming from an external source such as an LDAP).
- */
- public void testExternalGroupsSupported()
- {
- _ruleSet.grant(1, "extgroup1", Permission.ALLOW, Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY);
- _ruleSet.grant(2, "extgroup2", Permission.DENY, Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY);
assertEquals(2, _ruleSet.getRuleCount());
- assertEquals(Result.ALLOWED, _ruleSet.check(TestPrincipalUtils.createTestSubject("usera", "extgroup1"),Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY));
- assertEquals(Result.DENIED, _ruleSet.check(TestPrincipalUtils.createTestSubject("userb", "extgroup2"),Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY));
+ assertEquals(Result.ALLOWED, _ruleSet.check(TestPrincipalUtils.createTestSubject("usera", allowGroup),Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY));
+ assertEquals(Result.DENIED, _ruleSet.check(TestPrincipalUtils.createTestSubject("userb", deniedGroup),Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY));
+ assertEquals(Result.DEFER, _ruleSet.check(TestPrincipalUtils.createTestSubject("user", "group not mentioned in acl"),Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY));
}
/**
* Rule order in the ACL determines the outcome of the check. This test ensures that a user who is
- * granted explicit permission on an object, is granted that access even although late a group
+ * granted explicit permission on an object, is granted that access even though a group
* to which the user belongs is later denied the permission.
*/
public void testAllowDeterminedByRuleOrder()
{
- assertTrue(_ruleSet.addGroup("aclgroup", Arrays.asList(new String[] {"usera"})));
+ String group = "group";
+ String user = "user";
- _ruleSet.grant(1, "usera", Permission.ALLOW, Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY);
- _ruleSet.grant(2, "aclgroup", Permission.DENY, Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY);
+ _ruleSet.grant(1, user, Permission.ALLOW, Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY);
+ _ruleSet.grant(2, group, Permission.DENY, Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY);
assertEquals(2, _ruleSet.getRuleCount());
- assertEquals(Result.ALLOWED, _ruleSet.check(TestPrincipalUtils.createTestSubject("usera"),Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY));
+ assertEquals(Result.ALLOWED, _ruleSet.check(TestPrincipalUtils.createTestSubject(user, group),Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY));
}
/**
@@ -381,13 +349,33 @@ public class RuleSetTest extends QpidTestCase
*/
public void testDenyDeterminedByRuleOrder()
{
- assertTrue(_ruleSet.addGroup("aclgroup", Arrays.asList(new String[] {"usera"})));
+ String group = "aclgroup";
+ String user = "usera";
- _ruleSet.grant(1, "aclgroup", Permission.DENY, Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY);
- _ruleSet.grant(2, "usera", Permission.ALLOW, Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY);
+ _ruleSet.grant(1, group, Permission.DENY, Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY);
+ _ruleSet.grant(2, user, Permission.ALLOW, Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY);
assertEquals(2, _ruleSet.getRuleCount());
- assertEquals(Result.DENIED, _ruleSet.check(TestPrincipalUtils.createTestSubject("usera"),Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY));
+ assertEquals(Result.DENIED, _ruleSet.check(TestPrincipalUtils.createTestSubject(user, group),Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY));
+ }
+
+ public void testUserInMultipleGroups()
+ {
+ String allowedGroup = "group1";
+ String deniedGroup = "group2";
+
+ _ruleSet.grant(1, allowedGroup, Permission.ALLOW, Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY);
+ _ruleSet.grant(2, deniedGroup, Permission.DENY, Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY);
+
+ Subject subjectInBothGroups = TestPrincipalUtils.createTestSubject("user", allowedGroup, deniedGroup);
+ Subject subjectInDeniedGroupAndOneOther = TestPrincipalUtils.createTestSubject("user", deniedGroup, "some other group");
+ Subject subjectInAllowedGroupAndOneOther = TestPrincipalUtils.createTestSubject("user", allowedGroup, "some other group");
+
+ assertEquals(Result.ALLOWED, _ruleSet.check(subjectInBothGroups,Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY));
+
+ assertEquals(Result.DENIED, _ruleSet.check(subjectInDeniedGroupAndOneOther,Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY));
+
+ assertEquals(Result.ALLOWED, _ruleSet.check(subjectInAllowedGroupAndOneOther,Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY));
}
}
diff --git a/java/broker-plugins/firewall/MANIFEST.MF b/java/broker-plugins/firewall/MANIFEST.MF
deleted file mode 100644
index a302921d03..0000000000
--- a/java/broker-plugins/firewall/MANIFEST.MF
+++ /dev/null
@@ -1,34 +0,0 @@
-Manifest-Version: 1.0
-Bundle-ManifestVersion: 2
-Bundle-Name: Qpid Broker-Plugins Firewall
-Bundle-SymbolicName: broker-plugins-firewall
-Bundle-Description: Firewall plugin for Qpid.
-Bundle-License: http://www.apache.org/licenses/LICENSE-2.0.txt
-Bundle-DocURL: http://www.apache.org/
-Bundle-Version: 1.0.0
-Bundle-Activator: org.apache.qpid.server.security.access.plugins.FirewallActivator
-Bundle-RequiredExecutionEnvironment: JavaSE-1.6
-Bundle-ClassPath: .
-Bundle-ActivationPolicy: lazy
-Import-Package: org.apache.qpid,
- org.apache.qpid.framing,
- org.apache.qpid.protocol,
- org.apache.qpid.server.configuration,
- org.apache.qpid.server.configuration.plugins,
- org.apache.qpid.server.exchange,
- org.apache.qpid.server.plugins,
- org.apache.qpid.server.queue,
- org.apache.qpid.server.security,
- org.apache.qpid.server.security.access,
- org.apache.qpid.server.virtualhost,
- org.apache.qpid.util,
- org.apache.commons.configuration;version=1.0.0,
- org.apache.commons.lang;version=1.0.0,
- org.apache.commons.lang.builder;version=1.0.0,
- org.apache.log4j;version=1.0.0,
- javax.management;version=1.0.0,
- javax.management.openmbean;version=1.0.0,
- org.osgi.util.tracker;version=1.0.0,
- org.osgi.framework;version=1.3
-Private-Package: org.apache.qpid.server.security.access.config
-Export-Package: org.apache.qpid.server.security.access.plugins;uses:="org.osgi.framework"
diff --git a/java/broker-plugins/firewall/src/main/java/org/apache/qpid/server/security/access/config/FirewallRule.java b/java/broker-plugins/firewall/src/main/java/org/apache/qpid/server/security/access/config/FirewallRule.java
deleted file mode 100644
index ecec4b0cec..0000000000
--- a/java/broker-plugins/firewall/src/main/java/org/apache/qpid/server/security/access/config/FirewallRule.java
+++ /dev/null
@@ -1,136 +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.access.config;
-
-import org.apache.qpid.server.security.Result;
-import org.apache.qpid.util.NetMatcher;
-
-import java.net.InetAddress;
-import java.util.List;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.FutureTask;
-import java.util.concurrent.TimeUnit;
-import java.util.regex.Pattern;
-
-public class FirewallRule
-{
- public static final String ALLOW = "ALLOW";
- public static final String DENY = "DENY";
-
- private static final long DNS_TIMEOUT = 30000;
- private static final ExecutorService DNS_LOOKUP = Executors.newCachedThreadPool();
-
- private Result _access;
- private NetMatcher _network;
- private Pattern[] _hostnamePatterns;
-
- public FirewallRule(String access, List networks, List hostnames)
- {
- _access = (access.equalsIgnoreCase(ALLOW)) ? Result.ALLOWED : Result.DENIED;
-
- if (networks != null && networks.size() > 0)
- {
- String[] networkStrings = objListToStringArray(networks);
- _network = new NetMatcher(networkStrings);
- }
-
- if (hostnames != null && hostnames.size() > 0)
- {
- int i = 0;
- _hostnamePatterns = new Pattern[hostnames.size()];
- for (String hostname : objListToStringArray(hostnames))
- {
- _hostnamePatterns[i++] = Pattern.compile(hostname);
- }
- }
- }
-
- private String[] objListToStringArray(List objList)
- {
- String[] networkStrings = new String[objList.size()];
- int i = 0;
- for (Object network : objList)
- {
- networkStrings[i++] = (String) network;
- }
- return networkStrings;
- }
-
- public boolean match(InetAddress remote) throws FirewallException
- {
- if (_hostnamePatterns != null)
- {
- String hostname = getHostname(remote);
- if (hostname == null)
- {
- throw new FirewallException("DNS lookup failed");
- }
- for (Pattern pattern : _hostnamePatterns)
- {
- if (pattern.matcher(hostname).matches())
- {
- return true;
- }
- }
- return false;
- }
- else
- {
- return _network.matchInetNetwork(remote);
- }
- }
-
- /**
- * @param remote the InetAddress to look up
- * @return the hostname, null if not found, takes longer than 30s to find or otherwise fails
- */
- private String getHostname(final InetAddress remote) throws FirewallException
- {
- FutureTask<String> lookup = new FutureTask<String>(new Callable<String>()
- {
- public String call()
- {
- return remote.getCanonicalHostName();
- }
- });
- DNS_LOOKUP.execute(lookup);
-
- try
- {
- return lookup.get(DNS_TIMEOUT, TimeUnit.MILLISECONDS);
- }
- catch (Exception e)
- {
- return null;
- }
- finally
- {
- lookup.cancel(true);
- }
- }
-
- public Result getAccess()
- {
- return _access;
- }
-} \ No newline at end of file
diff --git a/java/broker-plugins/firewall/src/main/java/org/apache/qpid/server/security/access/plugins/Firewall.java b/java/broker-plugins/firewall/src/main/java/org/apache/qpid/server/security/access/plugins/Firewall.java
deleted file mode 100644
index 40a65fddba..0000000000
--- a/java/broker-plugins/firewall/src/main/java/org/apache/qpid/server/security/access/plugins/Firewall.java
+++ /dev/null
@@ -1,137 +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.access.plugins;
-
-import org.apache.commons.configuration.Configuration;
-import org.apache.commons.configuration.ConfigurationException;
-
-import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin;
-import org.apache.qpid.server.security.AbstractPlugin;
-import org.apache.qpid.server.security.Result;
-import org.apache.qpid.server.security.SecurityPluginFactory;
-import org.apache.qpid.server.security.access.ObjectProperties;
-import org.apache.qpid.server.security.access.ObjectType;
-import org.apache.qpid.server.security.access.Operation;
-import org.apache.qpid.server.security.access.config.FirewallException;
-import org.apache.qpid.server.security.access.config.FirewallRule;
-
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-
-public class Firewall extends AbstractPlugin
-{
- public static final SecurityPluginFactory<Firewall> FACTORY = new SecurityPluginFactory<Firewall>()
- {
- public Firewall newInstance(ConfigurationPlugin config) throws ConfigurationException
- {
- FirewallConfiguration configuration = config.getConfiguration(FirewallConfiguration.class.getName());
-
- // If there is no configuration for this plugin then don't load it.
- if (configuration == null)
- {
- return null;
- }
-
- Firewall plugin = new Firewall();
- plugin.configure(configuration);
- return plugin;
- }
-
- public Class<Firewall> getPluginClass()
- {
- return Firewall.class;
- }
-
- public String getPluginName()
- {
- return Firewall.class.getName();
- }
- };
-
- private Result _default = Result.ABSTAIN;
- private FirewallRule[] _rules;
-
- public Result getDefault()
- {
- return _default;
- }
-
- public Result authorise(Operation operation, ObjectType objectType, ObjectProperties properties)
- {
- return Result.ABSTAIN; // We only deal with access requests
- }
-
- public Result access(ObjectType objectType, Object instance)
- {
- if (objectType != ObjectType.VIRTUALHOST)
- {
- return Result.ABSTAIN; // We are only interested in access to virtualhosts
- }
-
- if (!(instance instanceof InetSocketAddress))
- {
- return Result.ABSTAIN; // We need an internet address
- }
-
- InetAddress address = ((InetSocketAddress) instance).getAddress();
-
- try
- {
- for (FirewallRule rule : _rules)
- {
- boolean match = rule.match(address);
- if (match)
- {
- return rule.getAccess();
- }
- }
- return getDefault();
- }
- catch (FirewallException fe)
- {
- return Result.DENIED;
- }
- }
-
-
- public void configure(ConfigurationPlugin config)
- {
- super.configure(config);
- FirewallConfiguration firewallConfiguration = (FirewallConfiguration) getConfig();
-
- // Get default action
- _default = firewallConfiguration.getDefaultAction();
-
- Configuration finalConfig = firewallConfiguration.getConfiguration();
-
- // all rules must have an access attribute
- int numRules = finalConfig.getList("rule[@access]").size();
- _rules = new FirewallRule[numRules];
- for (int i = 0; i < numRules; i++)
- {
- FirewallRule rule = new FirewallRule(finalConfig.getString("rule(" + i + ")[@access]"),
- finalConfig.getList("rule(" + i + ")[@network]"),
- finalConfig.getList("rule(" + i + ")[@hostname]"));
- _rules[i] = rule;
- }
-
- }
-}
diff --git a/java/broker-plugins/firewall/src/main/java/org/apache/qpid/server/security/access/plugins/FirewallConfiguration.java b/java/broker-plugins/firewall/src/main/java/org/apache/qpid/server/security/access/plugins/FirewallConfiguration.java
deleted file mode 100644
index 010d1652f0..0000000000
--- a/java/broker-plugins/firewall/src/main/java/org/apache/qpid/server/security/access/plugins/FirewallConfiguration.java
+++ /dev/null
@@ -1,103 +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.access.plugins;
-
-import org.apache.commons.configuration.CompositeConfiguration;
-import org.apache.commons.configuration.Configuration;
-import org.apache.commons.configuration.ConfigurationException;
-import org.apache.commons.configuration.XMLConfiguration;
-
-import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin;
-import org.apache.qpid.server.configuration.plugins.ConfigurationPluginFactory;
-import org.apache.qpid.server.security.Result;
-import org.apache.qpid.server.security.access.config.FirewallRule;
-
-import java.util.Arrays;
-import java.util.List;
-
-public class FirewallConfiguration extends ConfigurationPlugin
-{
- private CompositeConfiguration _finalConfig;
-
- public static final ConfigurationPluginFactory FACTORY = new ConfigurationPluginFactory()
- {
- public ConfigurationPlugin newInstance(String path, Configuration config) throws ConfigurationException
- {
- ConfigurationPlugin instance = new FirewallConfiguration();
- instance.setConfiguration(path, config);
- return instance;
- }
-
- public List<String> getParentPaths()
- {
- return Arrays.asList("security.firewall", "virtualhosts.virtualhost.security.firewall");
- }
- };
-
- public String[] getElementsProcessed()
- {
- return new String[] { "" };
- }
-
- public Configuration getConfiguration()
- {
- return _finalConfig;
- }
-
- public Result getDefaultAction()
- {
- String defaultAction = getConfig().getString("[@default-action]");
- if (defaultAction == null)
- {
- return Result.ABSTAIN;
- }
- else if (defaultAction.equalsIgnoreCase(FirewallRule.ALLOW))
- {
- return Result.ALLOWED;
- }
- else
- {
- return Result.DENIED;
- }
- }
-
-
-
- @Override
- public void validateConfiguration() throws ConfigurationException
- {
- // Valid Configuration either has xml links to new files
- _finalConfig = new CompositeConfiguration(getConfig());
- List subFiles = getConfig().getList("xml[@fileName]");
- for (Object subFile : subFiles)
- {
- _finalConfig.addConfiguration(new XMLConfiguration((String) subFile));
- }
-
- // all rules must have an access attribute or a default value
- if (_finalConfig.getList("rule[@access]").size() == 0 &&
- getConfig().getString("[@default-action]") == null)
- {
- throw new ConfigurationException("No rules or default-action found in firewall configuration.");
- }
- }
-
-}
diff --git a/java/broker-plugins/firewall/src/test/java/org/apache/qpid/server/security/access/FirewallConfigurationTest.java b/java/broker-plugins/firewall/src/test/java/org/apache/qpid/server/security/access/FirewallConfigurationTest.java
deleted file mode 100644
index 8969363979..0000000000
--- a/java/broker-plugins/firewall/src/test/java/org/apache/qpid/server/security/access/FirewallConfigurationTest.java
+++ /dev/null
@@ -1,322 +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.access;
-
-import org.apache.qpid.server.registry.ApplicationRegistry;
-import org.apache.qpid.server.registry.ConfigurationFileApplicationRegistry;
-import org.apache.qpid.server.virtualhost.VirtualHost;
-import org.apache.qpid.server.virtualhost.VirtualHostRegistry;
-import org.apache.qpid.test.utils.QpidTestCase;
-
-import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.RandomAccessFile;
-import java.net.InetSocketAddress;
-
-public class FirewallConfigurationTest extends QpidTestCase
-{
- @Override
- protected void tearDown() throws Exception
- {
- super.tearDown();
- ApplicationRegistry.remove();
- }
-
- public void testFirewallConfiguration() throws Exception
- {
- // Write out config
- File mainFile = File.createTempFile(getClass().getName(), null);
- mainFile.deleteOnExit();
- writeConfigFile(mainFile, false);
-
- // Load config
- ApplicationRegistry reg = new ConfigurationFileApplicationRegistry(mainFile);
- ApplicationRegistry.initialise(reg);
-
- // Test config
- assertFalse(reg.getSecurityManager().accessVirtualhost("test", new InetSocketAddress("127.0.0.1", 65535)));
- assertTrue(reg.getSecurityManager().accessVirtualhost("test", new InetSocketAddress("127.1.2.3", 65535)));
- }
-
- public void testCombinedConfigurationFirewall() throws Exception
- {
- // Write out config
- File mainFile = File.createTempFile(getClass().getName(), null);
- File fileA = File.createTempFile(getClass().getName(), null);
- File fileB = File.createTempFile(getClass().getName(), null);
-
- mainFile.deleteOnExit();
- fileA.deleteOnExit();
- fileB.deleteOnExit();
-
- FileWriter out = new FileWriter(mainFile);
- out.write("<configuration><system/>");
- out.write("<xml fileName=\"" + fileA.getAbsolutePath() + "\"/>");
- out.write("</configuration>");
- out.close();
-
- out = new FileWriter(fileA);
- out.write("<broker>\n");
- out.write("\t<plugin-directory>${QPID_HOME}/lib/plugins</plugin-directory>\n");
- out.write("\t<cache-directory>${QPID_WORK}/cache</cache-directory>\n");
- out.write("\t<management><enabled>false</enabled></management>\n");
- out.write("\t<security>\n");
- out.write("\t\t<pd-auth-manager>\n");
- out.write("\t\t\t<principal-database>\n");
- out.write("\t\t\t\t<class>org.apache.qpid.server.security.auth.database.PlainPasswordFilePrincipalDatabase</class>\n");
- out.write("\t\t\t\t<attributes>\n");
- out.write("\t\t\t\t\t<attribute>\n");
- out.write("\t\t\t\t\t\t<name>passwordFile</name>\n");
- out.write("\t\t\t\t\t\t<value>/dev/null</value>\n");
- out.write("\t\t\t\t\t</attribute>\n");
- out.write("\t\t\t\t</attributes>\n");
- out.write("\t\t\t</principal-database>\n");
- out.write("\t\t</pd-auth-manager>\n");
- out.write("\t\t<firewall>\n");
- out.write("\t\t\t<xml fileName=\"" + fileB.getAbsolutePath() + "\"/>");
- out.write("\t\t</firewall>\n");
- out.write("\t</security>\n");
- out.write("\t<virtualhosts>\n");
- out.write("\t\t<virtualhost>\n");
- out.write("\t\t\t<name>test</name>\n");
- out.write("\t\t</virtualhost>\n");
- out.write("\t</virtualhosts>\n");
- out.write("</broker>\n");
- out.close();
-
- out = new FileWriter(fileB);
- out.write("<firewall>\n");
- out.write("\t<rule access=\"deny\" network=\"127.0.0.1\"/>");
- out.write("</firewall>\n");
- out.close();
-
- // Load config
- ApplicationRegistry reg = new ConfigurationFileApplicationRegistry(mainFile);
- ApplicationRegistry.initialise(reg);
-
- // Test config
- assertFalse(reg.getSecurityManager().accessVirtualhost("test", new InetSocketAddress("127.0.0.1", 65535)));
- }
-
- public void testConfigurationFirewallReload() throws Exception
- {
- // Write out config
- File mainFile = File.createTempFile(getClass().getName(), null);
-
- mainFile.deleteOnExit();
- writeConfigFile(mainFile, false);
-
- // Load config
- ApplicationRegistry reg = new ConfigurationFileApplicationRegistry(mainFile);
- ApplicationRegistry.initialise(reg);
-
- // Test config
- assertFalse(reg.getSecurityManager().accessVirtualhost("test", new InetSocketAddress("127.0.0.1", 65535)));
-
- // Switch to deny the connection
- writeConfigFile(mainFile, true);
-
- reg.getConfiguration().reparseConfigFileSecuritySections();
-
- assertTrue(reg.getSecurityManager().accessVirtualhost("test", new InetSocketAddress("127.0.0.1", 65535)));
- }
-
- public void testCombinedConfigurationFirewallReload() throws Exception
- {
- // Write out config
- File mainFile = File.createTempFile(getClass().getName(), null);
- File fileA = File.createTempFile(getClass().getName(), null);
- File fileB = File.createTempFile(getClass().getName(), null);
-
- mainFile.deleteOnExit();
- fileA.deleteOnExit();
- fileB.deleteOnExit();
-
- FileWriter out = new FileWriter(mainFile);
- out.write("<configuration><system/>");
- out.write("<xml fileName=\"" + fileA.getAbsolutePath() + "\"/>");
- out.write("</configuration>");
- out.close();
-
- out = new FileWriter(fileA);
- out.write("<broker>\n");
- out.write("\t<plugin-directory>${QPID_HOME}/lib/plugins</plugin-directory>\n");
- out.write("\t<management><enabled>false</enabled></management>\n");
- out.write("\t<security>\n");
- out.write("\t\t<pd-auth-manager>\n");
- out.write("\t\t\t<principal-database>\n");
- out.write("\t\t\t\t<class>org.apache.qpid.server.security.auth.database.PlainPasswordFilePrincipalDatabase</class>\n");
- out.write("\t\t\t\t<attributes>\n");
- out.write("\t\t\t\t\t<attribute>\n");
- out.write("\t\t\t\t\t\t<name>passwordFile</name>\n");
- out.write("\t\t\t\t\t\t<value>/dev/null</value>\n");
- out.write("\t\t\t\t\t</attribute>\n");
- out.write("\t\t\t\t</attributes>\n");
- out.write("\t\t\t</principal-database>\n");
- out.write("\t\t</pd-auth-manager>\n");
- out.write("\t\t<firewall>\n");
- out.write("\t\t\t<xml fileName=\"" + fileB.getAbsolutePath() + "\"/>");
- out.write("\t\t</firewall>\n");
- out.write("\t</security>\n");
- out.write("\t<virtualhosts>\n");
- out.write("\t\t<virtualhost>\n");
- out.write("\t\t\t<name>test</name>\n");
- out.write("\t\t</virtualhost>\n");
- out.write("\t</virtualhosts>\n");
- out.write("</broker>\n");
- out.close();
-
- out = new FileWriter(fileB);
- out.write("<firewall>\n");
- out.write("\t<rule access=\"deny\" network=\"127.0.0.1\"/>");
- out.write("</firewall>\n");
- out.close();
-
- // Load config
- ApplicationRegistry reg = new ConfigurationFileApplicationRegistry(mainFile);
- ApplicationRegistry.initialise(reg);
-
- // Test config
- assertFalse(reg.getSecurityManager().accessVirtualhost("test", new InetSocketAddress("127.0.0.1", 65535)));
-
- RandomAccessFile fileBRandom = new RandomAccessFile(fileB, "rw");
- fileBRandom.setLength(0);
- fileBRandom.seek(0);
- fileBRandom.close();
-
- out = new FileWriter(fileB);
- out.write("<firewall>\n");
- out.write("\t<rule access=\"allow\" network=\"127.0.0.1\"/>");
- out.write("</firewall>\n");
- out.close();
-
- reg.getConfiguration().reparseConfigFileSecuritySections();
-
- assertTrue(reg.getSecurityManager().accessVirtualhost("test", new InetSocketAddress("127.0.0.1", 65535)));
-
- fileBRandom = new RandomAccessFile(fileB, "rw");
- fileBRandom.setLength(0);
- fileBRandom.seek(0);
- fileBRandom.close();
-
- out = new FileWriter(fileB);
- out.write("<firewall>\n");
- out.write("\t<rule access=\"deny\" network=\"127.0.0.1\"/>");
- out.write("</firewall>\n");
- out.close();
-
- reg.getConfiguration().reparseConfigFileSecuritySections();
-
- assertFalse(reg.getSecurityManager().accessVirtualhost("test", new InetSocketAddress("127.0.0.1", 65535)));
- }
-
- private void writeFirewallVhostsFile(File vhostsFile, boolean allow) throws IOException
- {
- FileWriter out = new FileWriter(vhostsFile);
- String ipAddr = "127.0.0.1"; // FIXME: get this from InetAddress.getLocalHost().getAddress() ?
- out.write("<virtualhosts><virtualhost>");
- out.write("<name>test</name>");
- out.write("<test>");
- out.write("<security><firewall>");
- out.write("<rule access=\""+((allow) ? "allow" : "deny")+"\" network=\""+ipAddr +"\"/>");
- out.write("</firewall></security>");
- out.write("</test>");
- out.write("</virtualhost></virtualhosts>");
- out.close();
- }
-
- private void writeConfigFile(File mainFile, boolean allow) throws IOException {
- writeConfigFile(mainFile, allow, true, null, "test");
- }
-
- /*
- XMLConfiguration config = new XMLConfiguration(mainFile);
- PluginManager pluginManager = new MockPluginManager("");
- SecurityManager manager = new SecurityManager(config, pluginManager, Firewall.FACTORY);
-
- */
- private void writeConfigFile(File mainFile, boolean allow, boolean includeVhosts, File vhostsFile, String name) throws IOException {
- FileWriter out = new FileWriter(mainFile);
- out.write("<broker>\n");
- out.write("\t<plugin-directory>${QPID_HOME}/lib/plugins</plugin-directory>\n");
- out.write("\t<management><enabled>false</enabled></management>\n");
- out.write("\t<security>\n");
- out.write("\t\t<pd-auth-manager>\n");
- out.write("\t\t\t<principal-database>\n");
- out.write("\t\t\t\t<class>org.apache.qpid.server.security.auth.database.PlainPasswordFilePrincipalDatabase</class>\n");
- out.write("\t\t\t\t<attributes>\n");
- out.write("\t\t\t\t\t<attribute>\n");
- out.write("\t\t\t\t\t\t<name>passwordFile</name>\n");
- out.write("\t\t\t\t\t\t<value>/dev/null</value>\n");
- out.write("\t\t\t\t\t</attribute>\n");
- out.write("\t\t\t\t</attributes>\n");
- out.write("\t\t\t</principal-database>\n");
- out.write("\t\t</pd-auth-manager>\n");
- out.write("\t\t<firewall>\n");
- out.write("\t\t\t<rule access=\""+ ((allow) ? "allow" : "deny") +"\" network=\"127.0.0.1\"/>");
- out.write("\t\t</firewall>\n");
- out.write("\t</security>\n");
- if (includeVhosts)
- {
- out.write("\t<virtualhosts>\n");
- out.write("\t\t<default>test</default>\n");
- out.write("\t\t<virtualhost>\n");
- out.write(String.format("\t\t\t<name>%s</name>\n", name));
- out.write("\t\t</virtualhost>\n");
- out.write("\t</virtualhosts>\n");
- }
- if (vhostsFile != null)
- {
- out.write("\t<virtualhosts>"+vhostsFile.getAbsolutePath()+"</virtualhosts>\n");
- }
- out.write("</broker>\n");
- out.close();
- }
-
- /**
- * Test that configuration loads correctly when virtual hosts are specified in an external
- * configuration file only.
- * <p>
- * Test for QPID-2360
- */
- public void testExternalFirewallVirtualhostXMLFile() throws Exception
- {
- // Write out config
- File mainFile = File.createTempFile(getClass().getName(), "config");
- mainFile.deleteOnExit();
- File vhostsFile = File.createTempFile(getClass().getName(), "vhosts");
- vhostsFile.deleteOnExit();
- writeConfigFile(mainFile, false, false, vhostsFile, null);
- writeFirewallVhostsFile(vhostsFile, false);
-
- // Load config
- ApplicationRegistry reg = new ConfigurationFileApplicationRegistry(mainFile);
- ApplicationRegistry.initialise(reg);
-
- // Test config
- VirtualHostRegistry virtualHostRegistry = reg.getVirtualHostRegistry();
- VirtualHost virtualHost = virtualHostRegistry.getVirtualHost("test");
-
- assertEquals("Incorrect virtualhost count", 1, virtualHostRegistry.getVirtualHosts().size());
- assertEquals("Incorrect virtualhost name", "test", virtualHost.getName());
- }
-}
diff --git a/java/broker-plugins/firewall/src/test/java/org/apache/qpid/server/security/access/FirewallPluginTest.java b/java/broker-plugins/firewall/src/test/java/org/apache/qpid/server/security/access/FirewallPluginTest.java
deleted file mode 100644
index 2004852c48..0000000000
--- a/java/broker-plugins/firewall/src/test/java/org/apache/qpid/server/security/access/FirewallPluginTest.java
+++ /dev/null
@@ -1,294 +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.access;
-
-import org.apache.commons.configuration.ConfigurationException;
-import org.apache.commons.configuration.XMLConfiguration;
-
-import org.apache.qpid.server.configuration.ServerConfiguration;
-import org.apache.qpid.server.registry.ApplicationRegistry;
-import org.apache.qpid.server.security.Result;
-import org.apache.qpid.server.security.access.plugins.Firewall;
-import org.apache.qpid.server.security.access.plugins.FirewallConfiguration;
-import org.apache.qpid.server.util.TestApplicationRegistry;
-import org.apache.qpid.test.utils.QpidTestCase;
-
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.net.InetSocketAddress;
-import java.net.SocketAddress;
-
-public class FirewallPluginTest extends QpidTestCase
-{
- public class RuleInfo
- {
- private String _access;
- private String _network;
- private String _hostname;
-
- public void setAccess(String _access)
- {
- this._access = _access;
- }
-
- public String getAccess()
- {
- return _access;
- }
-
- public void setNetwork(String _network)
- {
- this._network = _network;
- }
-
- public String getNetwork()
- {
- return _network;
- }
-
- public void setHostname(String _hostname)
- {
- this._hostname = _hostname;
- }
-
- public String getHostname()
- {
- return _hostname;
- }
- }
-
- // IP address
- private SocketAddress _address;
- private ServerConfiguration _serverConfig;
-
- @Override
- protected void setUp() throws Exception
- {
- super.setUp();
- _serverConfig = new ServerConfiguration(new XMLConfiguration());
- ApplicationRegistry.initialise(new TestApplicationRegistry(_serverConfig));
- _address = new InetSocketAddress("127.0.0.1", 65535);
- }
-
- @Override
- protected void tearDown() throws Exception
- {
- super.tearDown();
- ApplicationRegistry.remove();
- }
- private Firewall initialisePlugin(String defaultAction, RuleInfo[] rules) throws IOException, ConfigurationException
- {
- // Create sample config file
- File confFile = File.createTempFile(getClass().getSimpleName()+"conffile", null);
- confFile.deleteOnExit();
- BufferedWriter buf = new BufferedWriter(new FileWriter(confFile));
- buf.write("<firewall default-action=\""+defaultAction+"\">\n");
- if (rules != null)
- {
- for (RuleInfo rule : rules)
- {
- buf.write("<rule");
- buf.write(" access=\""+rule.getAccess()+"\"");
- if (rule.getHostname() != null)
- {
- buf.write(" hostname=\""+rule.getHostname()+"\"");
- }
- if (rule.getNetwork() != null)
- {
- buf.write(" network=\""+rule.getNetwork()+"\"");
- }
- buf.write("/>\n");
- }
- }
- buf.write("</firewall>");
- buf.close();
-
- // Configure plugin
- FirewallConfiguration config = new FirewallConfiguration();
- config.setConfiguration("", new XMLConfiguration(confFile));
- Firewall plugin = new Firewall();
- plugin.configure(config);
- return plugin;
- }
-
- private Firewall initialisePlugin(String string) throws ConfigurationException, IOException
- {
- return initialisePlugin(string, null);
- }
-
- public void testDefaultAction() throws Exception
- {
- // Test simple deny
- Firewall plugin = initialisePlugin("deny");
- assertEquals(Result.DENIED, plugin.access(ObjectType.VIRTUALHOST, _address));
-
- // Test simple allow
- plugin = initialisePlugin("allow");
- assertEquals(Result.ALLOWED, plugin.access(ObjectType.VIRTUALHOST, _address));
- }
-
-
- public void testSingleIPRule() throws Exception
- {
- RuleInfo rule = new RuleInfo();
- rule.setAccess("allow");
- rule.setNetwork("192.168.23.23");
-
- Firewall plugin = initialisePlugin("deny", new RuleInfo[]{rule});
-
- assertEquals(Result.DENIED, plugin.access(ObjectType.VIRTUALHOST, _address));
-
- // Set IP so that we're connected from the right address
- _address = new InetSocketAddress("192.168.23.23", 65535);
- assertEquals(Result.ALLOWED, plugin.access(ObjectType.VIRTUALHOST, _address));
- }
-
- public void testSingleNetworkRule() throws Exception
- {
- RuleInfo rule = new RuleInfo();
- rule.setAccess("allow");
- rule.setNetwork("192.168.23.0/24");
-
- Firewall plugin = initialisePlugin("deny", new RuleInfo[]{rule});
-
- assertEquals(Result.DENIED, plugin.access(ObjectType.VIRTUALHOST, _address));
-
- // Set IP so that we're connected from the right address
- _address = new InetSocketAddress("192.168.23.23", 65535);
- assertEquals(Result.ALLOWED, plugin.access(ObjectType.VIRTUALHOST, _address));
- }
-
- public void testSingleHostRule() throws Exception
- {
- RuleInfo rule = new RuleInfo();
- rule.setAccess("allow");
- rule.setHostname(new InetSocketAddress("127.0.0.1", 5672).getHostName());
-
- Firewall plugin = initialisePlugin("deny", new RuleInfo[]{rule});
-
- // Set IP so that we're connected from the right address
- _address = new InetSocketAddress("127.0.0.1", 65535);
- assertEquals(Result.ALLOWED, plugin.access(ObjectType.VIRTUALHOST, _address));
- }
-
- public void testSingleHostWilcardRule() throws Exception
- {
- RuleInfo rule = new RuleInfo();
- rule.setAccess("allow");
- String hostname = new InetSocketAddress("127.0.0.1", 0).getHostName();
- rule.setHostname(".*"+hostname.subSequence(hostname.length() - 1, hostname.length())+"*");
- Firewall plugin = initialisePlugin("deny", new RuleInfo[]{rule});
-
- // Set IP so that we're connected from the right address
- _address = new InetSocketAddress("127.0.0.1", 65535);
- assertEquals(Result.ALLOWED, plugin.access(ObjectType.VIRTUALHOST, _address));
- }
-
- public void testSeveralFirstAllowsAccess() throws Exception
- {
- RuleInfo firstRule = new RuleInfo();
- firstRule.setAccess("allow");
- firstRule.setNetwork("192.168.23.23");
-
- RuleInfo secondRule = new RuleInfo();
- secondRule.setAccess("deny");
- secondRule.setNetwork("192.168.42.42");
-
- RuleInfo thirdRule = new RuleInfo();
- thirdRule.setAccess("deny");
- thirdRule.setHostname("localhost");
-
- Firewall plugin = initialisePlugin("deny", new RuleInfo[]{firstRule, secondRule, thirdRule});
-
- assertEquals(Result.DENIED, plugin.access(ObjectType.VIRTUALHOST, _address));
-
- // Set IP so that we're connected from the right address
- _address = new InetSocketAddress("192.168.23.23", 65535);
- assertEquals(Result.ALLOWED, plugin.access(ObjectType.VIRTUALHOST, _address));
- }
-
- public void testSeveralLastAllowsAccess() throws Exception
- {
- RuleInfo firstRule = new RuleInfo();
- firstRule.setAccess("deny");
- firstRule.setHostname("localhost");
-
- RuleInfo secondRule = new RuleInfo();
- secondRule.setAccess("deny");
- secondRule.setNetwork("192.168.42.42");
-
- RuleInfo thirdRule = new RuleInfo();
- thirdRule.setAccess("allow");
- thirdRule.setNetwork("192.168.23.23");
-
- Firewall plugin = initialisePlugin("deny", new RuleInfo[]{firstRule, secondRule, thirdRule});
-
- assertEquals(Result.DENIED, plugin.access(ObjectType.VIRTUALHOST, _address));
-
- // Set IP so that we're connected from the right address
- _address = new InetSocketAddress("192.168.23.23", 65535);
- assertEquals(Result.ALLOWED, plugin.access(ObjectType.VIRTUALHOST, _address));
- }
-
- public void testNetmask() throws Exception
- {
- RuleInfo firstRule = new RuleInfo();
- firstRule.setAccess("allow");
- firstRule.setNetwork("192.168.23.0/24");
- Firewall plugin = initialisePlugin("deny", new RuleInfo[]{firstRule});
-
- assertEquals(Result.DENIED, plugin.access(ObjectType.VIRTUALHOST, _address));
-
- // Set IP so that we're connected from the right address
- _address = new InetSocketAddress("192.168.23.23", 65535);
- assertEquals(Result.ALLOWED, plugin.access(ObjectType.VIRTUALHOST, _address));
- }
-
- public void testCommaSeperatedNetmask() throws Exception
- {
- RuleInfo firstRule = new RuleInfo();
- firstRule.setAccess("allow");
- firstRule.setNetwork("10.1.1.1/8, 192.168.23.0/24");
- Firewall plugin = initialisePlugin("deny", new RuleInfo[]{firstRule});
-
- assertEquals(Result.DENIED, plugin.access(ObjectType.VIRTUALHOST, _address));
-
- // Set IP so that we're connected from the right address
- _address = new InetSocketAddress("192.168.23.23", 65535);
- assertEquals(Result.ALLOWED, plugin.access(ObjectType.VIRTUALHOST, _address));
- }
-
- public void testCommaSeperatedHostnames() throws Exception
- {
- RuleInfo firstRule = new RuleInfo();
- firstRule.setAccess("allow");
- firstRule.setHostname("foo, bar, "+new InetSocketAddress("127.0.0.1", 5672).getHostName());
- Firewall plugin = initialisePlugin("deny", new RuleInfo[]{firstRule});
-
- // Set IP so that we're connected from the right address
- _address = new InetSocketAddress("10.0.0.1", 65535);
- assertEquals(Result.DENIED, plugin.access(ObjectType.VIRTUALHOST, _address));
-
- // Set IP so that we're connected from the right address
- _address = new InetSocketAddress("127.0.0.1", 65535);
- assertEquals(Result.ALLOWED, plugin.access(ObjectType.VIRTUALHOST, _address));
- }
-}
diff --git a/java/broker-plugins/management-http/MANIFEST.MF b/java/broker-plugins/management-http/MANIFEST.MF
deleted file mode 100644
index cca10d3f89..0000000000
--- a/java/broker-plugins/management-http/MANIFEST.MF
+++ /dev/null
@@ -1,70 +0,0 @@
-Manifest-Version: 1.0
-Bundle-ManifestVersion: 2
-Bundle-Name: Qpid Broker-Plugins Management HTTP
-Bundle-SymbolicName: broker-plugins-management-http
-Bundle-Description: HTTP management plugin for Qpid.
-Bundle-License: http://www.apache.org/licenses/LICENSE-2.0.txt
-Bundle-DocURL: http://www.apache.org/
-Bundle-Version: 1.0.0
-Bundle-Activator: org.apache.qpid.server.management.plugin.ManagementActivator
-Bundle-RequiredExecutionEnvironment: JavaSE-1.6
-Bundle-ClassPath: .
-Bundle-ActivationPolicy: lazy
-Import-Package: org.apache.qpid,
- org.apache.qpid.framing,
- org.apache.qpid.protocol,
- org.apache.qpid.common,
- org.apache.qpid.server.security.auth,
- org.apache.qpid.server.security.auth.manager,
- org.apache.qpid.server.security.auth.sasl,
- org.apache.qpid.server.binding,
- org.apache.qpid.server.exchange,
- org.apache.qpid.server.logging,
- org.apache.qpid.server.message,
- org.apache.qpid.server.model,
- org.apache.qpid.server.model.adapter,
- org.apache.qpid.server.model.impl,
- org.apache.qpid.server.configuration,
- org.apache.qpid.server.configuration.plugins,
- org.apache.qpid.server.connection,
- org.apache.qpid.server.plugins,
- org.apache.qpid.server.protocol,
- org.apache.qpid.server.queue,
- org.apache.qpid.server.subscription,
- org.apache.qpid.server.registry,
- org.apache.qpid.server.security,
- org.apache.qpid.server.security.access,
- org.apache.qpid.server.stats,
- org.apache.qpid.server.virtualhost,
- org.apache.qpid.util,
- org.eclipse.jetty.server;version=7.6.3,
- org.eclipse.jetty.server.session;version=7.6.3,
- org.eclipse.jetty.server.ssl;version=7.6.3,
- org.eclipse.jetty.server.nio;version=7.6.3,
- org.eclipse.jetty.security;version=7.6.3,
- org.eclipse.jetty.http;version=7.6.3,
- org.eclipse.jetty.io;version=7.6.3,
- org.eclipse.jetty.io.nio;version=7.6.3,
- org.eclipse.jetty.servlet;version=7.6.3,
- org.eclipse.jetty.util.ssl;version=7.6.3,
- org.apache.commons.codec;version=1.3.0,
- org.apache.commons.codec.binary;version=1.3.0,
- org.apache.commons.configuration;version=1.0.0,
- org.apache.commons.lang;version=1.0.0,
- org.apache.commons.lang.builder;version=1.0.0,
- org.apache.log4j;version=1.0.0,
- org.codehaus.jackson;version=1.9.0,
- org.codehaus.jackson.map;version=1.9.0,
- javax.crypto,
- javax.crypto.spec,
- javax.security.auth,
- javax.security.auth.callback,
- javax.security.sasl,
- javax.servlet,
- javax.servlet.http,
- javax.management;version=1.0.0,
- javax.management.openmbean;version=1.0.0,
- org.osgi.util.tracker;version=1.0.0,
- org.osgi.framework;version=1.3
-Private-Package: org.apache.qpid.server.management.plugin.impl
-Export-Package: org.apache.qpid.server.management.plugin;uses:="org.osgi.framework"
diff --git a/java/broker-plugins/management-http/build.xml b/java/broker-plugins/management-http/build.xml
index b792cb292e..abf35d9c88 100644
--- a/java/broker-plugins/management-http/build.xml
+++ b/java/broker-plugins/management-http/build.xml
@@ -18,39 +18,36 @@
-->
<project name="Qpid Broker-Plugins Management HTTP" default="build">
- <condition property="systests.optional.depends" value="bdbstore" else="">
- <or>
- <and>
- <contains string="${modules.opt}" substring="bdbstore"/>
- <contains string="${profile}" substring="bdb"/>
- </and>
- <and>
- <istrue value="${optional}"/>
- <contains string="${profile}" substring="bdb"/>
- </and>
- </or>
- </condition>
-
<property name="module.depends" value="common broker" />
- <property name="module.test.depends" value="systests test broker/test common/test management/common client ${systests.optional.depends}" />
+ <property name="module.test.depends" value="broker/tests common/tests management/common client" />
+
+ <property name="module.genpom" value="true" />
+ <property name="module.genpom.args" value="-Sqpid-common=provided -Sqpid-broker=provided" />
- <property name="module.manifest" value="MANIFEST.MF" />
- <property name="module.plugin" value="true" />
- <property name="module.genpom" value="true"/>
- <property name="module.genpom.args" value="-Sqpid-common=provided -Sqpid-broker=provided"/>
+ <property name="broker.plugin" value="true"/>
- <property name="broker-plugins-management-http.libs" value=""/>
+ <property name="broker-plugins-management-http.libs" value="" />
<import file="../../module.xml" />
- <target name="precompile">
- <unwar src="${project.root}/${dojo}" dest="${module.classes}/resources/dojo">
- <patternset>
- <exclude name="META-INF/**"/>
- <exclude name="WEB-INF/**"/>
- <exclude name="**/*.uncompressed.js"/>
- </patternset>
- </unwar>
+ <!-- Flagfile used to determine if uwar needs to be done. ._ is part of Ant's defaultexcludes so wont appear bundles -->
+ <property name="dojo.uptodate.flagfile" value="${module.classes}/resources/dojo/._dojouptodate.timestamp" />
+
+ <target name="precompile" depends="unwardojo" />
+
+ <target name="unwardojo" depends="check-unwardojo.done" unless="unwardojo.done">
+ <unwar src="${project.root}/${dojo}" dest="${module.classes}/resources/dojo">
+ <patternset>
+ <exclude name="META-INF/**" />
+ <exclude name="WEB-INF/**" />
+ <exclude name="**/*.uncompressed.js" />
+ </patternset>
+ </unwar>
+ <touch file="${dojo.uptodate.flagfile}" />
+ </target>
+
+ <target name="check-unwardojo.done">
+ <uptodate property="unwardojo.done" targetfile="${dojo.uptodate.flagfile}" srcfile="${project.root}/${dojo}" />
</target>
<target name="bundle" depends="bundle-tasks" />
diff --git a/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagement.java b/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagement.java
new file mode 100644
index 0000000000..c2ac675e20
--- /dev/null
+++ b/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagement.java
@@ -0,0 +1,416 @@
+/*
+ *
+ * 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.management.plugin;
+
+import java.io.File;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.UUID;
+
+import org.apache.log4j.Logger;
+import org.apache.qpid.server.configuration.IllegalConfigurationException;
+import org.apache.qpid.server.logging.actors.CurrentActor;
+import org.apache.qpid.server.logging.messages.ManagementConsoleMessages;
+import org.apache.qpid.server.management.plugin.servlet.DefinedFileServlet;
+import org.apache.qpid.server.management.plugin.servlet.FileServlet;
+import org.apache.qpid.server.management.plugin.servlet.rest.AbstractServlet;
+import org.apache.qpid.server.management.plugin.servlet.rest.LogRecordsServlet;
+import org.apache.qpid.server.management.plugin.servlet.rest.LogoutServlet;
+import org.apache.qpid.server.management.plugin.servlet.rest.MessageContentServlet;
+import org.apache.qpid.server.management.plugin.servlet.rest.MessageServlet;
+import org.apache.qpid.server.management.plugin.servlet.rest.RestServlet;
+import org.apache.qpid.server.management.plugin.servlet.rest.SaslServlet;
+import org.apache.qpid.server.management.plugin.servlet.rest.StructureServlet;
+import org.apache.qpid.server.model.AuthenticationProvider;
+import org.apache.qpid.server.model.Binding;
+import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.model.ConfiguredObject;
+import org.apache.qpid.server.model.Connection;
+import org.apache.qpid.server.model.Exchange;
+import org.apache.qpid.server.model.Group;
+import org.apache.qpid.server.model.GroupMember;
+import org.apache.qpid.server.model.GroupProvider;
+import org.apache.qpid.server.model.KeyStore;
+import org.apache.qpid.server.model.Plugin;
+import org.apache.qpid.server.model.Port;
+import org.apache.qpid.server.model.Protocol;
+import org.apache.qpid.server.model.Queue;
+import org.apache.qpid.server.model.Session;
+import org.apache.qpid.server.model.State;
+import org.apache.qpid.server.model.User;
+import org.apache.qpid.server.model.VirtualHost;
+import org.apache.qpid.server.model.adapter.AbstractPluginAdapter;
+import org.apache.qpid.server.plugin.PluginFactory;
+import org.apache.qpid.server.util.MapValueConverter;
+import org.eclipse.jetty.server.Connector;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.server.SessionManager;
+import org.eclipse.jetty.server.nio.SelectChannelConnector;
+import org.eclipse.jetty.server.ssl.SslSocketConnector;
+import org.eclipse.jetty.servlet.ServletContextHandler;
+import org.eclipse.jetty.servlet.ServletHolder;
+import org.eclipse.jetty.util.ssl.SslContextFactory;
+
+public class HttpManagement extends AbstractPluginAdapter
+{
+ private final Logger _logger = Logger.getLogger(HttpManagement.class);
+
+ // 10 minutes by default
+ public static final int DEFAULT_TIMEOUT_IN_SECONDS = 60 * 10;
+ public static final boolean DEFAULT_HTTP_BASIC_AUTHENTICATION_ENABLED = false;
+ public static final boolean DEFAULT_HTTPS_BASIC_AUTHENTICATION_ENABLED = true;
+ public static final boolean DEFAULT_HTTP_SASL_AUTHENTICATION_ENABLED = true;
+ public static final boolean DEFAULT_HTTPS_SASL_AUTHENTICATION_ENABLED = true;
+ public static final String DEFAULT_NAME = "httpManagement";
+
+ public static final String TIME_OUT = "sessionTimeout";
+ public static final String HTTP_BASIC_AUTHENTICATION_ENABLED = "httpBasicAuthenticationEnabled";
+ public static final String HTTPS_BASIC_AUTHENTICATION_ENABLED = "httpsBasicAuthenticationEnabled";
+ public static final String HTTP_SASL_AUTHENTICATION_ENABLED = "httpSaslAuthenticationEnabled";
+ public static final String HTTPS_SASL_AUTHENTICATION_ENABLED = "httpsSaslAuthenticationEnabled";
+
+ public static final String PLUGIN_TYPE = "MANAGEMENT-HTTP";
+
+ @SuppressWarnings("serial")
+ private static final Collection<String> AVAILABLE_ATTRIBUTES = Collections.unmodifiableSet(new HashSet<String>(Plugin.AVAILABLE_ATTRIBUTES)
+ {{
+ add(HTTP_BASIC_AUTHENTICATION_ENABLED);
+ add(HTTPS_BASIC_AUTHENTICATION_ENABLED);
+ add(HTTP_SASL_AUTHENTICATION_ENABLED);
+ add(HTTPS_SASL_AUTHENTICATION_ENABLED);
+ add(TIME_OUT);
+ add(PluginFactory.PLUGIN_TYPE);
+ }});
+
+ public static final String ENTRY_POINT_PATH = "/management";
+
+ private static final String OPERATIONAL_LOGGING_NAME = "Web";
+
+
+ @SuppressWarnings("serial")
+ public static final Map<String, Object> DEFAULTS = Collections.unmodifiableMap(new HashMap<String, Object>()
+ {{
+ put(HTTP_BASIC_AUTHENTICATION_ENABLED, DEFAULT_HTTP_BASIC_AUTHENTICATION_ENABLED);
+ put(HTTPS_BASIC_AUTHENTICATION_ENABLED, DEFAULT_HTTPS_BASIC_AUTHENTICATION_ENABLED);
+ put(HTTP_SASL_AUTHENTICATION_ENABLED, DEFAULT_HTTP_SASL_AUTHENTICATION_ENABLED);
+ put(HTTPS_SASL_AUTHENTICATION_ENABLED, DEFAULT_HTTPS_SASL_AUTHENTICATION_ENABLED);
+ put(TIME_OUT, DEFAULT_TIMEOUT_IN_SECONDS);
+ put(NAME, DEFAULT_NAME);
+ }});
+
+ @SuppressWarnings("serial")
+ private static final Map<String, Class<?>> ATTRIBUTE_TYPES = Collections.unmodifiableMap(new HashMap<String, Class<?>>(){{
+ put(HTTP_BASIC_AUTHENTICATION_ENABLED, Boolean.class);
+ put(HTTPS_BASIC_AUTHENTICATION_ENABLED, Boolean.class);
+ put(HTTP_SASL_AUTHENTICATION_ENABLED, Boolean.class);
+ put(HTTPS_SASL_AUTHENTICATION_ENABLED, Boolean.class);
+ put(NAME, String.class);
+ put(TIME_OUT, Integer.class);
+ put(PluginFactory.PLUGIN_TYPE, String.class);
+ }});
+
+ private final Broker _broker;
+
+ private Server _server;
+
+ public HttpManagement(UUID id, Broker broker, Map<String, Object> attributes)
+ {
+ super(id, DEFAULTS, MapValueConverter.convert(attributes, ATTRIBUTE_TYPES), broker.getTaskExecutor());
+ _broker = broker;
+ addParent(Broker.class, broker);
+ }
+
+ @Override
+ protected boolean setState(State currentState, State desiredState)
+ {
+ if(desiredState == State.ACTIVE)
+ {
+ start();
+ return true;
+ }
+ else if(desiredState == State.STOPPED)
+ {
+ stop();
+ return true;
+ }
+ return false;
+ }
+
+ private void start()
+ {
+ CurrentActor.get().message(ManagementConsoleMessages.STARTUP(OPERATIONAL_LOGGING_NAME));
+
+ Collection<Port> httpPorts = getHttpPorts(_broker.getPorts());
+ _server = createServer(httpPorts);
+ try
+ {
+ _server.start();
+ logOperationalListenMessages(_server);
+ }
+ catch (Exception e)
+ {
+ throw new RuntimeException("Failed to start http management on ports " + httpPorts);
+ }
+
+ CurrentActor.get().message(ManagementConsoleMessages.READY(OPERATIONAL_LOGGING_NAME));
+ }
+
+ private void stop()
+ {
+ if (_server != null)
+ {
+ try
+ {
+ _server.stop();
+ logOperationalShutdownMessage(_server);
+ }
+ catch (Exception e)
+ {
+ throw new RuntimeException("Failed to stop http management on port " + getHttpPorts(_broker.getPorts()));
+ }
+ }
+
+ CurrentActor.get().message(ManagementConsoleMessages.STOPPED(OPERATIONAL_LOGGING_NAME));
+ }
+
+ /** Added for testing purposes */
+ Broker getBroker()
+ {
+ return _broker;
+ }
+
+ /** Added for testing purposes */
+ int getSessionTimeout()
+ {
+ return (Integer)getAttribute(TIME_OUT);
+ }
+
+ private boolean isManagementHttp(Port port)
+ {
+ return port.getProtocols().contains(Protocol.HTTP) || port.getProtocols().contains(Protocol.HTTPS);
+ }
+
+ @SuppressWarnings("unchecked")
+ private Server createServer(Collection<Port> ports)
+ {
+ if (_logger.isInfoEnabled())
+ {
+ _logger.info("Starting up web server on " + ports);
+ }
+
+ Server server = new Server();
+ for (Port port : ports)
+ {
+ if (State.QUIESCED.equals(port.getActualState()))
+ {
+ continue;
+ }
+ final Collection<Protocol> protocols = port.getProtocols();
+ Connector connector = null;
+
+ //TODO: what to do if protocol HTTP and transport SSL?
+ if (protocols.contains(Protocol.HTTP))
+ {
+ connector = new SelectChannelConnector();
+ }
+ else if (protocols.contains(Protocol.HTTPS))
+ {
+ KeyStore keyStore = _broker.getDefaultKeyStore();
+ if (keyStore == null)
+ {
+ throw new IllegalConfigurationException("Key store is not configured. Cannot start management on HTTPS port without keystore");
+ }
+ String keyStorePath = (String)keyStore.getAttribute(KeyStore.PATH);
+ String keyStorePassword = keyStore.getPassword();
+ validateKeystoreParameters(keyStorePath, keyStorePassword);
+
+ SslContextFactory factory = new SslContextFactory();
+ factory.setKeyStorePath(keyStorePath);
+ factory.setKeyStorePassword(keyStorePassword);
+
+ connector = new SslSocketConnector(factory);
+ }
+ else
+ {
+ throw new IllegalArgumentException("Unexpected protocol " + protocols);
+ }
+ connector.setPort(port.getPort());
+ server.addConnector(connector);
+ }
+
+ ServletContextHandler root = new ServletContextHandler(ServletContextHandler.SESSIONS);
+ root.setContextPath("/");
+ server.setHandler(root);
+
+ // set servlet context attributes for broker and configuration
+ root.getServletContext().setAttribute(AbstractServlet.ATTR_BROKER, _broker);
+ root.getServletContext().setAttribute(AbstractServlet.ATTR_MANAGEMENT, this);
+
+ addRestServlet(root, "broker");
+ addRestServlet(root, "virtualhost", VirtualHost.class);
+ addRestServlet(root, "authenticationprovider", AuthenticationProvider.class);
+ addRestServlet(root, "user", AuthenticationProvider.class, User.class);
+ addRestServlet(root, "groupprovider", GroupProvider.class);
+ addRestServlet(root, "group", GroupProvider.class, Group.class);
+ addRestServlet(root, "groupmember", GroupProvider.class, Group.class, GroupMember.class);
+ addRestServlet(root, "exchange", VirtualHost.class, Exchange.class);
+ addRestServlet(root, "queue", VirtualHost.class, Queue.class);
+ addRestServlet(root, "connection", VirtualHost.class, Connection.class);
+ addRestServlet(root, "binding", VirtualHost.class, Exchange.class, Queue.class, Binding.class);
+ addRestServlet(root, "port", Port.class);
+ addRestServlet(root, "session", VirtualHost.class, Connection.class, Session.class);
+
+ root.addServlet(new ServletHolder(new StructureServlet()), "/rest/structure");
+ root.addServlet(new ServletHolder(new MessageServlet()), "/rest/message/*");
+ root.addServlet(new ServletHolder(new MessageContentServlet()), "/rest/message-content/*");
+
+ root.addServlet(new ServletHolder(new LogRecordsServlet()), "/rest/logrecords");
+
+ root.addServlet(new ServletHolder(new SaslServlet()), "/rest/sasl");
+
+ root.addServlet(new ServletHolder(new DefinedFileServlet("index.html")), ENTRY_POINT_PATH);
+ root.addServlet(new ServletHolder(new LogoutServlet()), "/logout");
+
+ root.addServlet(new ServletHolder(FileServlet.INSTANCE), "*.js");
+ root.addServlet(new ServletHolder(FileServlet.INSTANCE), "*.css");
+ root.addServlet(new ServletHolder(FileServlet.INSTANCE), "*.html");
+ root.addServlet(new ServletHolder(FileServlet.INSTANCE), "*.png");
+ root.addServlet(new ServletHolder(FileServlet.INSTANCE), "*.gif");
+ root.addServlet(new ServletHolder(FileServlet.INSTANCE), "*.jpg");
+ root.addServlet(new ServletHolder(FileServlet.INSTANCE), "*.jpeg");
+ root.addServlet(new ServletHolder(FileServlet.INSTANCE), "*.json");
+ root.addServlet(new ServletHolder(FileServlet.INSTANCE), "*.txt");
+ root.addServlet(new ServletHolder(FileServlet.INSTANCE), "*.xsl");
+
+ final SessionManager sessionManager = root.getSessionHandler().getSessionManager();
+
+ sessionManager.setMaxInactiveInterval((Integer)getAttribute(TIME_OUT));
+
+ return server;
+ }
+
+ private void addRestServlet(ServletContextHandler root, String name, Class<? extends ConfiguredObject>... hierarchy)
+ {
+ root.addServlet(new ServletHolder(new RestServlet(hierarchy)), "/rest/" + name + "/*");
+ }
+
+ private void validateKeystoreParameters(String keyStorePath, String password)
+ {
+ if (keyStorePath == null)
+ {
+ throw new RuntimeException("Management SSL keystore path not defined, unable to start SSL protected HTTP connector");
+ }
+ if (password == null)
+ {
+ throw new RuntimeException("Management SSL keystore password, unable to start SSL protected HTTP connector");
+ }
+ File ksf = new File(keyStorePath);
+ if (!ksf.exists())
+ {
+ throw new RuntimeException("Cannot find management SSL keystore file: " + ksf);
+ }
+ if (!ksf.canRead())
+ {
+ throw new RuntimeException("Cannot read management SSL keystore file: " + ksf + ". Check permissions.");
+ }
+ }
+
+ private void logOperationalListenMessages(Server server)
+ {
+ Connector[] connectors = server.getConnectors();
+ for (Connector connector : connectors)
+ {
+ CurrentActor.get().message(ManagementConsoleMessages.LISTENING(stringifyConnectorScheme(connector), connector.getPort()));
+ if (connector instanceof SslSocketConnector)
+ {
+ SslContextFactory sslContextFactory = ((SslSocketConnector)connector).getSslContextFactory();
+ if (sslContextFactory != null && sslContextFactory.getKeyStorePath() != null)
+ {
+ CurrentActor.get().message(ManagementConsoleMessages.SSL_KEYSTORE(sslContextFactory.getKeyStorePath()));
+ }
+ }
+ }
+ }
+
+ private void logOperationalShutdownMessage(Server server)
+ {
+ Connector[] connectors = server.getConnectors();
+ for (Connector connector : connectors)
+ {
+ CurrentActor.get().message(ManagementConsoleMessages.SHUTTING_DOWN(stringifyConnectorScheme(connector), connector.getPort()));
+ }
+ }
+
+ private String stringifyConnectorScheme(Connector connector)
+ {
+ return connector instanceof SslSocketConnector ? "HTTPS" : "HTTP";
+ }
+
+ private Collection<Port> getHttpPorts(Collection<Port> ports)
+ {
+ Collection<Port> httpPorts = new HashSet<Port>();
+ for (Port port : ports)
+ {
+ if (isManagementHttp(port))
+ {
+ httpPorts.add(port);
+ }
+ }
+ return httpPorts;
+ }
+
+
+ @Override
+ public String getName()
+ {
+ return (String)getAttribute(NAME);
+ }
+
+ @Override
+ public Collection<String> getAttributeNames()
+ {
+ return Collections.unmodifiableCollection(AVAILABLE_ATTRIBUTES);
+ }
+
+ public boolean isHttpsSaslAuthenticationEnabled()
+ {
+ return (Boolean)getAttribute(HTTPS_SASL_AUTHENTICATION_ENABLED);
+ }
+
+ public boolean isHttpSaslAuthenticationEnabled()
+ {
+ return (Boolean)getAttribute(HTTP_SASL_AUTHENTICATION_ENABLED);
+ }
+
+ public boolean isHttpsBasicAuthenticationEnabled()
+ {
+ return (Boolean)getAttribute(HTTPS_BASIC_AUTHENTICATION_ENABLED);
+ }
+
+ public boolean isHttpBasicAuthenticationEnabled()
+ {
+ return (Boolean)getAttribute(HTTP_BASIC_AUTHENTICATION_ENABLED);
+ }
+
+}
diff --git a/java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/systest/management/jmx/UserManagementWithBase64MD5PasswordsTest.java b/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagementFactory.java
index 84a66232ce..ccf5373234 100644
--- a/java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/systest/management/jmx/UserManagementWithBase64MD5PasswordsTest.java
+++ b/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagementFactory.java
@@ -16,24 +16,26 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.qpid.systest.management.jmx;
+package org.apache.qpid.server.management.plugin;
-import org.apache.qpid.server.security.auth.database.Base64MD5PasswordFilePrincipalDatabase;
-import org.apache.qpid.server.security.auth.database.PrincipalDatabase;
-import org.apache.qpid.tools.security.Passwd;
+import java.util.Map;
+import java.util.UUID;
-public class UserManagementWithBase64MD5PasswordsTest extends UserManagementTest
+import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.model.Plugin;
+import org.apache.qpid.server.plugin.PluginFactory;
+
+public class HttpManagementFactory implements PluginFactory
{
- @Override
- protected Passwd createPasswordEncodingUtility()
- {
- return new Passwd();
- }
@Override
- protected Class<? extends PrincipalDatabase> getPrincipalDatabaseImplClass()
+ public Plugin createInstance(UUID id, Map<String, Object> attributes, Broker broker)
{
- return Base64MD5PasswordFilePrincipalDatabase.class;
- }
+ if (!HttpManagement.PLUGIN_TYPE.equals(attributes.get(PLUGIN_TYPE)))
+ {
+ return null;
+ }
+ return new HttpManagement(id, broker, attributes);
+ }
}
diff --git a/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/Management.java b/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/Management.java
deleted file mode 100644
index c2f9b73b54..0000000000
--- a/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/Management.java
+++ /dev/null
@@ -1,248 +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.management.plugin;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collection;
-
-import org.apache.commons.configuration.ConfigurationException;
-import org.apache.log4j.Logger;
-import org.apache.qpid.server.management.plugin.servlet.DefinedFileServlet;
-import org.apache.qpid.server.management.plugin.servlet.FileServlet;
-import org.apache.qpid.server.management.plugin.servlet.api.ExchangesServlet;
-import org.apache.qpid.server.management.plugin.servlet.api.VhostsServlet;
-import org.apache.qpid.server.management.plugin.servlet.rest.LogRecordsServlet;
-import org.apache.qpid.server.management.plugin.servlet.rest.MessageContentServlet;
-import org.apache.qpid.server.management.plugin.servlet.rest.MessageServlet;
-import org.apache.qpid.server.management.plugin.servlet.rest.RestServlet;
-import org.apache.qpid.server.management.plugin.servlet.rest.SaslServlet;
-import org.apache.qpid.server.management.plugin.servlet.rest.StructureServlet;
-import org.apache.qpid.server.model.AuthenticationProvider;
-import org.apache.qpid.server.model.Binding;
-import org.apache.qpid.server.model.Broker;
-import org.apache.qpid.server.model.ConfiguredObject;
-import org.apache.qpid.server.model.Connection;
-import org.apache.qpid.server.model.Exchange;
-import org.apache.qpid.server.model.Port;
-import org.apache.qpid.server.model.Protocol;
-import org.apache.qpid.server.model.Queue;
-import org.apache.qpid.server.model.Session;
-import org.apache.qpid.server.model.Transport;
-import org.apache.qpid.server.model.User;
-import org.apache.qpid.server.model.VirtualHost;
-import org.apache.qpid.server.registry.ApplicationRegistry;
-import org.apache.qpid.server.registry.IApplicationRegistry;
-import org.eclipse.jetty.server.Server;
-import org.eclipse.jetty.server.SessionManager;
-import org.eclipse.jetty.server.nio.SelectChannelConnector;
-import org.eclipse.jetty.server.ssl.SslSocketConnector;
-import org.eclipse.jetty.servlet.ServletContextHandler;
-import org.eclipse.jetty.servlet.ServletHolder;
-import org.eclipse.jetty.util.ssl.SslContextFactory;
-
-public class Management
-{
-
- private final Logger _logger = Logger.getLogger(Management.class);
-
- private Broker _broker;
-
- private Collection<Server> _servers = new ArrayList<Server>();
-
- public Management() throws ConfigurationException, IOException
- {
- _broker = ApplicationRegistry.getInstance().getBroker();
-
- Collection<Port> ports = _broker.getPorts();
- int httpPort = -1, httpsPort = -1;
- for (Port port : ports)
- {
- if (port.getProtocols().contains(Protocol.HTTP))
- {
- if (port.getTransports().contains(Transport.TCP))
- {
- httpPort = port.getPort();
- }
- }
- if (port.getProtocols().contains(Protocol.HTTPS))
- {
- if (port.getTransports().contains(Transport.SSL))
- {
- httpsPort = port.getPort();
- }
- }
- }
-
- if (httpPort != -1 || httpsPort != -1)
- {
- _servers.add(createServer(httpPort, httpsPort));
- if (_logger.isDebugEnabled())
- {
- _logger.debug(_servers.size() + " server(s) defined");
- }
- }
- else
- {
- if (_logger.isInfoEnabled())
- {
- _logger.info("Cannot create web server as neither HTTP nor HTTPS port specified");
- }
- }
- }
-
- @SuppressWarnings("unchecked")
- private Server createServer(int port, int sslPort) throws IOException, ConfigurationException
- {
- if (_logger.isInfoEnabled())
- {
- _logger.info("Starting up web server on" + (port == -1 ? "" : " HTTP port " + port)
- + (sslPort == -1 ? "" : " HTTPS port " + sslPort));
- }
-
- Server server = new Server();
-
- if (port != -1)
- {
- SelectChannelConnector connector = new SelectChannelConnector();
- connector.setPort(port);
- if (sslPort != -1)
- {
- connector.setConfidentialPort(sslPort);
- }
- server.addConnector(connector);
- }
-
- if (sslPort != -1)
- {
- IApplicationRegistry appRegistry = ApplicationRegistry.getInstance();
- String keyStorePath = getKeyStorePath(appRegistry);
-
- SslContextFactory factory = new SslContextFactory();
- factory.setKeyStorePath(keyStorePath);
- factory.setKeyStorePassword(appRegistry.getConfiguration().getManagementKeyStorePassword());
-
- SslSocketConnector connector = new SslSocketConnector(factory);
- connector.setPort(sslPort);
- server.addConnector(connector);
- }
-
- ServletContextHandler root = new ServletContextHandler(ServletContextHandler.SESSIONS);
- root.setContextPath("/");
- server.setHandler(root);
-
- root.addServlet(new ServletHolder(new VhostsServlet(_broker)), "/api/vhosts/*");
- root.addServlet(new ServletHolder(new ExchangesServlet(_broker)), "/api/exchanges/*");
-
- addRestServlet(root, "broker");
- addRestServlet(root, "virtualhost", VirtualHost.class);
- addRestServlet(root, "authenticationprovider", AuthenticationProvider.class);
- addRestServlet(root, "user", AuthenticationProvider.class, User.class);
- addRestServlet(root, "exchange", VirtualHost.class, Exchange.class);
- addRestServlet(root, "queue", VirtualHost.class, Queue.class);
- addRestServlet(root, "connection", VirtualHost.class, Connection.class);
- addRestServlet(root, "binding", VirtualHost.class, Exchange.class, Queue.class, Binding.class);
- addRestServlet(root, "port", Port.class);
- addRestServlet(root, "session", VirtualHost.class, Connection.class, Session.class);
-
- root.addServlet(new ServletHolder(new StructureServlet(_broker)), "/rest/structure");
- root.addServlet(new ServletHolder(new MessageServlet(_broker)), "/rest/message/*");
- root.addServlet(new ServletHolder(new MessageContentServlet(_broker)), "/rest/message-content/*");
-
- root.addServlet(new ServletHolder(new LogRecordsServlet(_broker)), "/rest/logrecords");
-
- root.addServlet(new ServletHolder(new SaslServlet(_broker)), "/rest/sasl");
-
- root.addServlet(new ServletHolder(new DefinedFileServlet("management.html")), "/management");
-
- root.addServlet(new ServletHolder(FileServlet.INSTANCE), "*.js");
- root.addServlet(new ServletHolder(FileServlet.INSTANCE), "*.css");
- root.addServlet(new ServletHolder(FileServlet.INSTANCE), "*.html");
- root.addServlet(new ServletHolder(FileServlet.INSTANCE), "*.png");
- root.addServlet(new ServletHolder(FileServlet.INSTANCE), "*.gif");
- root.addServlet(new ServletHolder(FileServlet.INSTANCE), "*.jpg");
- root.addServlet(new ServletHolder(FileServlet.INSTANCE), "*.jpeg");
- root.addServlet(new ServletHolder(FileServlet.INSTANCE), "*.json");
- root.addServlet(new ServletHolder(FileServlet.INSTANCE), "*.txt");
- root.addServlet(new ServletHolder(FileServlet.INSTANCE), "*.xsl");
-
- final SessionManager sessionManager = root.getSessionHandler().getSessionManager();
-
- sessionManager.setMaxInactiveInterval(60 * 15);
-
- return server;
- }
-
- private void addRestServlet(ServletContextHandler root, String name, Class<? extends ConfiguredObject>... hierarchy)
- {
- root.addServlet(new ServletHolder(new RestServlet(_broker, hierarchy)), "/rest/" + name + "/*");
- }
-
- public void start() throws Exception
- {
- for (Server server : _servers)
- {
- server.start();
- }
- }
-
- public void stop() throws Exception
- {
- for (Server server : _servers)
- {
- server.stop();
- }
- }
-
- private String getKeyStorePath(IApplicationRegistry appRegistry) throws ConfigurationException, FileNotFoundException
- {
- String keyStorePath = null;
- if (System.getProperty("javax.net.ssl.keyStore") != null)
- {
- keyStorePath = System.getProperty("javax.net.ssl.keyStore");
- }
- else
- {
- keyStorePath = appRegistry.getConfiguration().getManagementKeyStorePath();
- }
-
- if (keyStorePath == null)
- {
- throw new ConfigurationException("Management SSL keystore path not defined, unable to start SSL protected HTTP connector");
- }
- else
- {
- File ksf = new File(keyStorePath);
- if (!ksf.exists())
- {
- throw new FileNotFoundException("Cannot find management SSL keystore file: " + ksf);
- }
- if (!ksf.canRead())
- {
- throw new FileNotFoundException("Cannot read management SSL keystore file: " + ksf + ". Check permissions.");
- }
- }
- return keyStorePath;
- }
-
-}
diff --git a/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/ManagementActivator.java b/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/ManagementActivator.java
deleted file mode 100644
index 09b7e08bfb..0000000000
--- a/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/ManagementActivator.java
+++ /dev/null
@@ -1,73 +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.management.plugin;
-
-import org.apache.log4j.Logger;
-import org.apache.qpid.server.configuration.plugins.ConfigurationPluginFactory;
-import org.apache.qpid.server.registry.ApplicationRegistry;
-import org.osgi.framework.BundleActivator;
-import org.osgi.framework.BundleContext;
-
-public class ManagementActivator implements BundleActivator
-{
- private static final Logger _logger = Logger.getLogger(ManagementActivator.class);
-
-
- private BundleContext _ctx;
- private String _bundleName;
- private Management _managementService;
-
-
- public void start(final BundleContext ctx) throws Exception
- {
- _ctx = ctx;
- if (!ApplicationRegistry.getInstance().getConfiguration().getHTTPManagementEnabled()
- && !ApplicationRegistry.getInstance().getConfiguration().getHTTPSManagementEnabled())
- {
- _logger.info("Management plugin is disabled!");
- ctx.getBundle().uninstall();
- return;
- }
- _managementService = new Management();
- _managementService.start();
- _bundleName = ctx.getBundle().getSymbolicName();
-
- // register the service
- _logger.info("Registering management plugin: " + _bundleName);
- _ctx.registerService(Management.class.getName(), _managementService, null);
- _ctx.registerService(ConfigurationPluginFactory.class.getName(), ManagementConfiguration.FACTORY, null);
- }
-
- public void stop(final BundleContext bundleContext) throws Exception
- {
- if (_managementService != null)
- {
- _logger.info("Stopping management plugin: " + _bundleName);
-
- _managementService.stop();
-
- // null object references
- _managementService = null;
- }
- _ctx = null;
- }
-
-}
diff --git a/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/ManagementConfiguration.java b/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/ManagementConfiguration.java
deleted file mode 100644
index 3866da8f89..0000000000
--- a/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/ManagementConfiguration.java
+++ /dev/null
@@ -1,77 +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.management.plugin;
-
-import org.apache.commons.configuration.CompositeConfiguration;
-import org.apache.commons.configuration.Configuration;
-import org.apache.commons.configuration.ConfigurationException;
-import org.apache.commons.configuration.XMLConfiguration;
-
-import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin;
-import org.apache.qpid.server.configuration.plugins.ConfigurationPluginFactory;
-
-import java.util.Arrays;
-import java.util.List;
-
-public class ManagementConfiguration extends ConfigurationPlugin
-{
- CompositeConfiguration _finalConfig;
-
- public static final ConfigurationPluginFactory FACTORY = new ConfigurationPluginFactory()
- {
- public ConfigurationPlugin newInstance(String path, Configuration config) throws ConfigurationException
- {
- ConfigurationPlugin instance = new ManagementConfiguration();
- instance.setConfiguration(path, config);
- return instance;
- }
-
- public List<String> getParentPaths()
- {
- return Arrays.asList("management");
- }
- };
-
- public String[] getElementsProcessed()
- {
- return new String[] { "" };
- }
-
- public Configuration getConfiguration()
- {
- return _finalConfig;
- }
-
-
- @Override
- public void validateConfiguration() throws ConfigurationException
- {
- // Valid Configuration either has xml links to new files
- _finalConfig = new CompositeConfiguration(getConfig());
- List subFiles = getConfig().getList("xml[@fileName]");
- for (Object subFile : subFiles)
- {
- _finalConfig.addConfiguration(new XMLConfiguration((String) subFile));
- }
-
- }
-
-}
diff --git a/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/DefinedFileServlet.java b/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/DefinedFileServlet.java
index d8a8395550..e6ae47dcff 100644
--- a/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/DefinedFileServlet.java
+++ b/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/DefinedFileServlet.java
@@ -73,7 +73,7 @@ public class DefinedFileServlet extends HttpServlet
}
else
{
- response.sendError(404, "unknown file: "+ _filename);
+ response.sendError(HttpServletResponse.SC_NOT_FOUND, "unknown file: "+ _filename);
}
}
}
diff --git a/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/FileServlet.java b/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/FileServlet.java
index f8ca082d79..24e5e7c049 100644
--- a/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/FileServlet.java
+++ b/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/FileServlet.java
@@ -20,11 +20,8 @@
*/
package org.apache.qpid.server.management.plugin.servlet;
-import java.io.File;
import java.io.IOException;
import java.io.InputStream;
-import java.net.URI;
-import java.net.URISyntaxException;
import java.net.URL;
import java.util.Collections;
import java.util.HashMap;
@@ -101,7 +98,7 @@ public class FileServlet extends HttpServlet
}
else
{
- response.sendError(404, "unknown file: "+ filename);
+ response.sendError(HttpServletResponse.SC_NOT_FOUND, "unknown file: "+ filename);
}
}
diff --git a/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/api/ExchangesServlet.java b/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/api/ExchangesServlet.java
deleted file mode 100644
index a3c5ec68a2..0000000000
--- a/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/api/ExchangesServlet.java
+++ /dev/null
@@ -1,208 +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.management.plugin.servlet.api;
-
-import org.codehaus.jackson.map.ObjectMapper;
-import org.codehaus.jackson.map.ObjectReader;
-
-import org.apache.qpid.server.model.Broker;
-import org.apache.qpid.server.model.Exchange;
-import org.apache.qpid.server.model.LifetimePolicy;
-import org.apache.qpid.server.model.State;
-import org.apache.qpid.server.model.VirtualHost;
-import org.apache.qpid.server.registry.ApplicationRegistry;
-
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServlet;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-
-public class ExchangesServlet extends HttpServlet
-{
-
-
- private Broker _broker;
-
- public ExchangesServlet()
- {
- super();
- _broker = ApplicationRegistry.getInstance().getBroker();
- }
-
- public ExchangesServlet(Broker broker)
- {
- _broker = broker;
- }
-
- protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
- {
- response.setContentType("application/json");
- response.setStatus(HttpServletResponse.SC_OK);
-
- Collection<VirtualHost> vhosts = _broker.getVirtualHosts();
- Collection<Exchange> exchanges = new ArrayList<Exchange>();
- Collection<Map<String,Object>> outputObject = new ArrayList<Map<String,Object>>();
-
- final PrintWriter writer = response.getWriter();
-
- ObjectMapper mapper = new ObjectMapper();
- String vhostName = null;
- String exchangeName = null;
-
- if(request.getPathInfo() != null && request.getPathInfo().length()>0)
- {
- String path = request.getPathInfo().substring(1);
- String[] parts = path.split("/");
- vhostName = parts.length == 0 ? "" : parts[0];
- if(parts.length > 1)
- {
- exchangeName = parts[1];
- }
- }
-
- for(VirtualHost vhost : vhosts)
- {
- if(vhostName == null || vhostName.equals(vhost.getName()))
- {
- for(Exchange exchange : vhost.getExchanges())
- {
- if(exchangeName == null || exchangeName.equals(exchange.getName()))
- {
- outputObject.add(convertToObject(exchange));
- if(exchangeName != null)
- {
- break;
- }
- }
- }
- if(vhostName != null)
- {
- break;
- }
- }
- }
-
- mapper.writeValue(writer, outputObject);
-
- }
-
- private Map<String,Object> convertToObject(final Exchange exchange)
- {
- Map<String, Object> object = new LinkedHashMap<String, Object>();
- object.put("name",exchange.getName());
- object.put("type", exchange.getExchangeType());
- object.put("durable", exchange.isDurable());
- object.put("auto-delete", exchange.getLifetimePolicy() == LifetimePolicy.AUTO_DELETE);
-
- Map<String,Object> arguments = new HashMap<String, Object>();
- for(String key : exchange.getAttributeNames())
- {
- if(!key.equals(Exchange.TYPE))
- {
- arguments.put(key, exchange.getAttribute(key));
- }
- }
- object.put("arguments", arguments);
- return object;
- }
-
- protected void doPut(final HttpServletRequest request, final HttpServletResponse response)
- throws ServletException, IOException
- {
-
- response.setContentType("application/json");
-
-
- String vhostName = null;
- String exchangeName = null;
- if(request.getPathInfo() != null && request.getPathInfo().length()>0)
- {
- String path = request.getPathInfo().substring(1);
- String[] parts = path.split("/");
- vhostName = parts.length == 0 ? "" : parts[0];
- if(parts.length > 1)
- {
- exchangeName = parts[1];
- }
- }
- if(vhostName == null)
- {
- response.setStatus(HttpServletResponse.SC_PRECONDITION_FAILED);
- }
- else if (exchangeName == null)
- {
- response.setStatus(HttpServletResponse.SC_PRECONDITION_FAILED);
- }
- else
- {
- VirtualHost vhost = null;
- for(VirtualHost host : _broker.getVirtualHosts())
- {
- if(host.getName().equals(vhostName))
- {
- vhost = host;
- }
- }
- if(vhost == null)
- {
- response.setStatus(HttpServletResponse.SC_PRECONDITION_FAILED);
- }
- else
- {
- response.setStatus(HttpServletResponse.SC_NO_CONTENT);
- ObjectMapper mapper = new ObjectMapper();
- Map<String,Object> exchangeObject = mapper.readValue(request.getInputStream(), LinkedHashMap.class);
-
- final boolean isDurable = exchangeObject.get("durable") instanceof Boolean
- && ((Boolean)exchangeObject.get("durable"));
- final boolean isAutoDelete = exchangeObject.get("auto_delete") instanceof Boolean
- && ((Boolean)exchangeObject.get("auto_delete"));
-
- final String type = (String) exchangeObject.get("type");
- final Map<String, Object> attributes = new HashMap<String, Object>(exchangeObject);
- attributes.remove("durable");
- attributes.remove("auto_delete");
- attributes.remove("type");
-
- vhost.createExchange(exchangeName, State.ACTIVE, isDurable,
- isAutoDelete ? LifetimePolicy.AUTO_DELETE : LifetimePolicy.PERMANENT,
- 0l,
- type,
- attributes);
- }
-
-
-
- }
-
-
-
- }
-}
diff --git a/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/api/VhostsServlet.java b/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/api/VhostsServlet.java
deleted file mode 100644
index b2c0fcfe52..0000000000
--- a/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/api/VhostsServlet.java
+++ /dev/null
@@ -1,118 +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.management.plugin.servlet.api;
-
-import org.codehaus.jackson.map.ObjectMapper;
-
-import org.apache.qpid.common.QpidProperties;
-import org.apache.qpid.server.model.Broker;
-import org.apache.qpid.server.model.LifetimePolicy;
-import org.apache.qpid.server.model.State;
-import org.apache.qpid.server.model.VirtualHost;
-import org.apache.qpid.server.protocol.AMQConnectionModel;
-import org.apache.qpid.server.registry.ApplicationRegistry;
-
-
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServlet;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.util.*;
-
-public class VhostsServlet extends HttpServlet
-{
-
-
- private Broker _broker;
-
- public VhostsServlet()
- {
- super();
- _broker = ApplicationRegistry.getInstance().getBroker();
- }
-
- public VhostsServlet(Broker broker)
- {
- _broker = broker;
- }
-
- protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
- {
-System.out.println("Get /api/vhosts");
- response.setContentType("application/json");
- response.setStatus(HttpServletResponse.SC_OK);
-
- Collection<VirtualHost> vhosts = _broker.getVirtualHosts();
-
-
-
- final PrintWriter writer = response.getWriter();
-
- ObjectMapper mapper = new ObjectMapper();
-
- if(request.getPathInfo() == null || request.getPathInfo().length()==0)
- {
-
- LinkedHashMap<String, Object> vhostObject = new LinkedHashMap<String, Object>();
- List<Map> vhostList = new ArrayList<Map>();
-
- for(VirtualHost vhost : vhosts)
- {
- vhostList.add(Collections.singletonMap("name", vhost.getName()));
- }
- mapper.writeValue(writer, vhostList);
- }
- else
- {
- LinkedHashMap<String, Object> vhostObject = new LinkedHashMap<String, Object>();
- String vhostName = request.getPathInfo().substring(1);
-
- for(VirtualHost vhost : vhosts)
- {
- if(vhostName.equals(vhost.getName()))
- {
- vhostObject.put("name", vhost.getName());
- break;
- }
- }
- mapper.writeValue(writer, vhostObject);
- }
- }
-
-
- protected void doPut(final HttpServletRequest request, final HttpServletResponse response)
- throws ServletException, IOException
- {
-
- response.setContentType("application/json");
- response.setStatus(HttpServletResponse.SC_NO_CONTENT);
-
- if(request.getPathInfo() != null && request.getPathInfo().length()>0)
- {
- String vhostName = request.getPathInfo().substring(1);
- _broker.createVirtualHost(vhostName, State.ACTIVE, true, LifetimePolicy.PERMANENT, 0L, Collections.EMPTY_MAP);
- }
-
-
- }
-}
diff --git a/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/AbstractServlet.java b/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/AbstractServlet.java
index a76bd98179..689bdb50d8 100644
--- a/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/AbstractServlet.java
+++ b/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/AbstractServlet.java
@@ -18,191 +18,456 @@
* under the License.
*
*/
-
package org.apache.qpid.server.management.plugin.servlet.rest;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
-import java.security.Principal;
-import java.util.Collections;
+import java.security.AccessControlException;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+
import javax.security.auth.Subject;
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.apache.commons.codec.binary.Base64;
+import org.apache.log4j.Logger;
+import org.apache.qpid.framing.AMQShortString;
+import org.apache.qpid.server.logging.LogActor;
+import org.apache.qpid.server.logging.RootMessageLogger;
+import org.apache.qpid.server.logging.actors.CurrentActor;
+import org.apache.qpid.server.logging.actors.HttpManagementActor;
+import org.apache.qpid.server.management.plugin.HttpManagement;
+import org.apache.qpid.server.management.plugin.session.LoginLogoutReporter;
import org.apache.qpid.server.model.Broker;
-import org.apache.qpid.server.registry.ApplicationRegistry;
-import org.apache.qpid.server.security.auth.AuthenticationResult;
+import org.apache.qpid.server.security.SecurityManager;
+import org.apache.qpid.server.security.SubjectCreator;
+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.AnonymousAuthenticationManager;
-import org.apache.qpid.server.security.auth.manager.AuthenticationManager;
public abstract class AbstractServlet extends HttpServlet
{
- private final Broker _broker;
+ private static final Logger LOGGER = Logger.getLogger(AbstractServlet.class);
+
+ /**
+ * Servlet context attribute holding a reference to a broker instance
+ */
+ public static final String ATTR_BROKER = "Qpid.broker";
+
+ /**
+ * Servlet context attribute holding a reference to plugin configuration
+ */
+ public static final String ATTR_MANAGEMENT = "Qpid.management";
+
+ private static final String ATTR_LOGIN_LOGOUT_REPORTER = "AbstractServlet.loginLogoutReporter";
+ private static final String ATTR_SUBJECT = "AbstractServlet.subject";
+ private static final String ATTR_LOG_ACTOR = "AbstractServlet.logActor";
+
+ private Broker _broker;
+ private RootMessageLogger _rootLogger;
+ private HttpManagement _httpManagement;
protected AbstractServlet()
{
super();
- _broker = ApplicationRegistry.getInstance().getBroker();
}
- protected AbstractServlet(Broker broker)
+ @Override
+ public void init() throws ServletException
{
- _broker = broker;
+ ServletConfig servletConfig = getServletConfig();
+ ServletContext servletContext = servletConfig.getServletContext();
+ _broker = (Broker)servletContext.getAttribute(ATTR_BROKER);
+ _rootLogger = _broker.getRootMessageLogger();
+ _httpManagement = (HttpManagement)servletContext.getAttribute(ATTR_MANAGEMENT);
+ super.init();
}
@Override
- protected final void doGet(HttpServletRequest request, HttpServletResponse resp) throws ServletException, IOException
+ protected final void doGet(final HttpServletRequest request, final HttpServletResponse resp)
{
- setAuthorizedSubject(request);
- try
- {
- onGet(request, resp);
- }
- finally
- {
- clearAuthorizedSubject();
- }
+ doWithSubjectAndActor(
+ new PrivilegedExceptionAction<Void>()
+ {
+ @Override
+ public Void run() throws Exception
+ {
+ doGetWithSubjectAndActor(request, resp);
+ return null;
+ }
+ },
+ request,
+ resp
+ );
+ }
+
+ /**
+ * Performs the GET action as the logged-in {@link Subject}.
+ * The {@link LogActor} is set before this method is called.
+ * Subclasses commonly override this method
+ */
+ protected void doGetWithSubjectAndActor(HttpServletRequest request, HttpServletResponse resp) throws ServletException, IOException
+ {
+ throw new UnsupportedOperationException("GET not supported by this servlet");
+ }
+
+
+ @Override
+ protected final void doPost(final HttpServletRequest request, final HttpServletResponse resp)
+ {
+ doWithSubjectAndActor(
+ new PrivilegedExceptionAction<Void>()
+ {
+ @Override
+ public Void run() throws Exception
+ {
+ doPostWithSubjectAndActor(request, resp);
+ return null;
+ }
+ },
+ request,
+ resp
+ );
+ }
+
+ /**
+ * Performs the POST action as the logged-in {@link Subject}.
+ * The {@link LogActor} is set before this method is called.
+ * Subclasses commonly override this method
+ */
+ protected void doPostWithSubjectAndActor(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
+ {
+ throw new UnsupportedOperationException("POST not supported by this servlet");
+ }
+
+ @Override
+ protected final void doPut(final HttpServletRequest request, final HttpServletResponse resp)
+ {
+ doWithSubjectAndActor(
+ new PrivilegedExceptionAction<Void>()
+ {
+ @Override
+ public Void run() throws Exception
+ {
+ doPutWithSubjectAndActor(request, resp);
+ return null;
+ }
+ },
+ request,
+ resp
+ );
}
- protected void onGet(HttpServletRequest request, HttpServletResponse resp) throws IOException, ServletException
+ /**
+ * Performs the PUT action as the logged-in {@link Subject}.
+ * The {@link LogActor} is set before this method is called.
+ * Subclasses commonly override this method
+ */
+ protected void doPutWithSubjectAndActor(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
{
- super.doGet(request, resp);
+ throw new UnsupportedOperationException("PUT not supported by this servlet");
}
- private void clearAuthorizedSubject()
+ @Override
+ protected final void doDelete(final HttpServletRequest request, final HttpServletResponse resp)
+ throws ServletException, IOException
{
- org.apache.qpid.server.security.SecurityManager.setThreadSubject(null);
+ doWithSubjectAndActor(
+ new PrivilegedExceptionAction<Void>()
+ {
+ @Override
+ public Void run() throws Exception
+ {
+ doDeleteWithSubjectAndActor(request, resp);
+ return null;
+ }
+ },
+ request,
+ resp
+ );
}
+ /**
+ * Performs the PUT action as the logged-in {@link Subject}.
+ * The {@link LogActor} is set before this method is called.
+ * Subclasses commonly override this method
+ */
+ protected void doDeleteWithSubjectAndActor(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
+ {
+ throw new UnsupportedOperationException("DELETE not supported by this servlet");
+ }
- private void setAuthorizedSubject(HttpServletRequest request)
+ private void doWithSubjectAndActor(
+ PrivilegedExceptionAction<Void> privilegedExceptionAction,
+ final HttpServletRequest request,
+ final HttpServletResponse resp)
{
- HttpSession session = request.getSession(true);
- Subject subject = (Subject) session.getAttribute("subject");
+ Subject subject;
+ try
+ {
+ subject = getAndCacheAuthorizedSubject(request);
+ }
+ catch (AccessControlException e)
+ {
+ sendError(resp, HttpServletResponse.SC_FORBIDDEN);
+ return;
+ }
- if(subject == null)
+ SecurityManager.setThreadSubject(subject);
+ try
{
- Principal principal = request.getUserPrincipal();
- if(principal != null)
+ HttpManagementActor logActor = getLogActorAndCacheInSession(request);
+ CurrentActor.set(logActor);
+ try
+ {
+ Subject.doAs(subject, privilegedExceptionAction);
+ }
+ catch(RuntimeException e)
{
- subject = new Subject(false, Collections.singleton(principal),Collections.emptySet(),
- Collections.emptySet());
+ LOGGER.error("Unable to perform action", e);
+ throw e;
}
- else
+ catch (PrivilegedActionException e)
{
- String header = request.getHeader("Authorization");
+ LOGGER.error("Unable to perform action", e);
+ throw new RuntimeException(e.getCause());
+ }
+ finally
+ {
+ CurrentActor.remove();
+ }
+ }
+ finally
+ {
+ try
+ {
+ SecurityManager.setThreadSubject(null);
+ }
+ finally
+ {
+ AMQShortString.clearLocalCache();
+ }
+ }
+ }
+
+ /**
+ * Gets the logged-in {@link Subject} by trying the following:
+ *
+ * <ul>
+ * <li>Get it from the session</li>
+ * <li>Get it from the request</li>
+ * <li>Log in using the username and password in the Authorization HTTP header</li>
+ * <li>Create a Subject representing the anonymous user.</li>
+ * </ul>
+ *
+ * If an authenticated subject is found it is cached in the http session.
+ */
+ private Subject getAndCacheAuthorizedSubject(HttpServletRequest request)
+ {
+ HttpSession session = request.getSession();
+ Subject subject = getAuthorisedSubjectFromSession(session);
- /*
- * TODO - Should configure whether basic authentication is allowed... and in particular whether it
- * should be allowed over non-ssl connections
- * */
+ if(subject != null)
+ {
+ return subject;
+ }
- if (header != null)
+ SubjectCreator subjectCreator = getSubjectCreator(request);
+ subject = authenticate(request, subjectCreator);
+ if (subject != null)
+ {
+ authoriseManagement(request, subject);
+ setAuthorisedSubjectInSession(subject, request, session);
+ }
+ else
+ {
+ subject = subjectCreator.createSubjectWithGroups(AnonymousAuthenticationManager.ANONYMOUS_USERNAME);
+ }
+
+ return subject;
+ }
+
+ protected void authoriseManagement(HttpServletRequest request, Subject subject)
+ {
+ // TODO: We should eliminate SecurityManager.setThreadSubject in favour of Subject.doAs
+ SecurityManager.setThreadSubject(subject); // Required for accessManagement check
+ LogActor actor = createHttpManagementActor(request);
+ CurrentActor.set(actor);
+ try
+ {
+ try
+ {
+ Subject.doAs(subject, new PrivilegedExceptionAction<Void>() // Required for proper logging of Subject
{
- String[] tokens = header.split("\\s");
- if(tokens.length >= 2
- && "BASIC".equalsIgnoreCase(tokens[0]))
+ @Override
+ public Void run() throws Exception
{
- String[] credentials = (new String(Base64.decodeBase64(tokens[1].getBytes()))).split(":",2);
- if(credentials.length == 2)
+ boolean allowed = getSecurityManager().accessManagement();
+ if (!allowed)
{
- SocketAddress address = getSocketAddress(request);
- AuthenticationManager authenticationManager =
- ApplicationRegistry.getInstance().getAuthenticationManager(address);
- AuthenticationResult authResult =
- authenticationManager.authenticate(credentials[0], credentials[1]);
- subject = authResult.getSubject();
-
+ throw new AccessControlException("User is not authorised for management");
}
+ return null;
}
- }
+ });
+ }
+ catch (PrivilegedActionException e)
+ {
+ throw new RuntimeException("Unable to perform access check", e);
}
}
- if (subject == null)
+ finally
{
- subject = AnonymousAuthenticationManager.ANONYMOUS_SUBJECT;
+ try
+ {
+ CurrentActor.remove();
+ }
+ finally
+ {
+ SecurityManager.setThreadSubject(null);
+ }
}
- org.apache.qpid.server.security.SecurityManager.setThreadSubject(subject);
-
}
- protected Subject getSubject(HttpSession session)
+ private Subject authenticate(HttpServletRequest request, SubjectCreator subjectCreator)
{
- return (Subject)session.getAttribute("subject");
+ Subject subject = null;
+
+ String remoteUser = request.getRemoteUser();
+ if(remoteUser != null)
+ {
+ subject = authenticateUserAndGetSubject(subjectCreator, remoteUser, null);
+ }
+ else
+ {
+ String header = request.getHeader("Authorization");
+
+ if (header != null)
+ {
+ String[] tokens = header.split("\\s");
+ if(tokens.length >= 2 && "BASIC".equalsIgnoreCase(tokens[0]))
+ {
+ if(!isBasicAuthSupported(request))
+ {
+ //TODO: write a return response indicating failure?
+ throw new IllegalArgumentException("BASIC Authorization is not enabled.");
+ }
+
+ subject = performBasicAuth(subject, subjectCreator, tokens[1]);
+ }
+ }
+ }
+
+ return subject;
}
- @Override
- protected final void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
+ private Subject performBasicAuth(Subject subject,SubjectCreator subjectCreator, String base64UsernameAndPassword)
{
- setAuthorizedSubject(req);
- try
+ String[] credentials = (new String(Base64.decodeBase64(base64UsernameAndPassword.getBytes()))).split(":",2);
+ if(credentials.length == 2)
{
- onPost(req, resp);
+ subject = authenticateUserAndGetSubject(subjectCreator, credentials[0], credentials[1]);
}
- finally
+ else
{
- clearAuthorizedSubject();
+ //TODO: write a return response indicating failure?
+ throw new AccessControlException("Invalid number of credentials supplied: "
+ + credentials.length);
}
+ return subject;
+ }
+ private Subject authenticateUserAndGetSubject(SubjectCreator subjectCreator, String username, String password)
+ {
+ SubjectAuthenticationResult authResult = subjectCreator.authenticate(username, password);
+ if( authResult.getStatus() != AuthenticationStatus.SUCCESS)
+ {
+ //TODO: write a return response indicating failure?
+ throw new AccessControlException("Incorrect username or password");
+ }
+ Subject subject = authResult.getSubject();
+ return subject;
}
- protected void onPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
+ private boolean isBasicAuthSupported(HttpServletRequest req)
{
- super.doPost(req, resp);
+ return req.isSecure() ? _httpManagement.isHttpsBasicAuthenticationEnabled()
+ : _httpManagement.isHttpBasicAuthenticationEnabled();
}
- @Override
- protected final void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
+ private HttpManagementActor getLogActorAndCacheInSession(HttpServletRequest req)
{
- setAuthorizedSubject(req);
- try
- {
- onPut(req, resp);
+ HttpSession session = req.getSession();
- }
- finally
+ HttpManagementActor actor = (HttpManagementActor) session.getAttribute(ATTR_LOG_ACTOR);
+ if(actor == null)
{
- clearAuthorizedSubject();
+ actor = createHttpManagementActor(req);
+ session.setAttribute(ATTR_LOG_ACTOR, actor);
}
+
+ return actor;
}
- protected void onPut(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException
+ protected Subject getAuthorisedSubjectFromSession(HttpSession session)
{
- super.doPut(req,resp);
+ return (Subject)session.getAttribute(ATTR_SUBJECT);
}
- @Override
- protected final void doDelete(HttpServletRequest req, HttpServletResponse resp)
- throws ServletException, IOException
+ protected void setAuthorisedSubjectInSession(Subject subject, HttpServletRequest request, final HttpSession session)
+ {
+ session.setAttribute(ATTR_SUBJECT, subject);
+
+ LogActor logActor = createHttpManagementActor(request);
+ // Cause the user logon to be logged.
+ session.setAttribute(ATTR_LOGIN_LOGOUT_REPORTER, new LoginLogoutReporter(logActor, subject));
+ }
+
+ protected Broker getBroker()
+ {
+ return _broker;
+ }
+
+ protected SocketAddress getSocketAddress(HttpServletRequest request)
+ {
+ return InetSocketAddress.createUnresolved(request.getServerName(), request.getServerPort());
+ }
+
+ protected void sendError(final HttpServletResponse resp, int errorCode)
{
- setAuthorizedSubject(req);
try
{
- onDelete(req, resp);
+ resp.sendError(errorCode);
}
- finally
+ catch (IOException e)
{
- clearAuthorizedSubject();
+ throw new RuntimeException("Failed to send error response code " + errorCode, e);
}
}
- protected void onDelete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
+ private HttpManagementActor createHttpManagementActor(HttpServletRequest request)
{
- super.doDelete(req, resp);
+ return new HttpManagementActor(_rootLogger, request.getRemoteAddr(), request.getRemotePort());
}
+ protected HttpManagement getManagement()
+ {
+ return _httpManagement;
+ }
- protected Broker getBroker()
+ protected SecurityManager getSecurityManager()
{
- return _broker;
+ return _broker.getSecurityManager();
}
- protected SocketAddress getSocketAddress(HttpServletRequest request)
+ protected SubjectCreator getSubjectCreator(HttpServletRequest request)
{
- return InetSocketAddress.createUnresolved(request.getServerName(), request.getServerPort());
+ return _broker.getSubjectCreator(getSocketAddress(request));
}
}
diff --git a/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/LogRecordsServlet.java b/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/LogRecordsServlet.java
index 404793b592..f2cf5d7734 100644
--- a/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/LogRecordsServlet.java
+++ b/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/LogRecordsServlet.java
@@ -26,8 +26,6 @@ import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.qpid.server.logging.LogRecorder;
-import org.apache.qpid.server.model.Broker;
-import org.apache.qpid.server.registry.ApplicationRegistry;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.SerializationConfig;
@@ -35,16 +33,11 @@ public class LogRecordsServlet extends AbstractServlet
{
public LogRecordsServlet()
{
- super(ApplicationRegistry.getInstance().getBroker());
- }
-
- public LogRecordsServlet(Broker broker)
- {
- super(broker);
+ super();
}
@Override
- protected void onGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
+ protected void doGetWithSubjectAndActor(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{
response.setContentType("application/json");
response.setStatus(HttpServletResponse.SC_OK);
@@ -53,10 +46,10 @@ public class LogRecordsServlet extends AbstractServlet
response.setHeader("Pragma","no-cache");
response.setDateHeader ("Expires", 0);
- ApplicationRegistry applicationRegistry = (ApplicationRegistry) ApplicationRegistry.getInstance();
List<Map<String,Object>> logRecords = new ArrayList<Map<String, Object>>();
- for(LogRecorder.Record record : applicationRegistry.getLogRecorder())
+ LogRecorder logRecorder = getBroker().getLogRecorder();
+ for(LogRecorder.Record record : logRecorder)
{
logRecords.add(logRecordToObject(record));
}
diff --git a/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/LogoutServlet.java b/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/LogoutServlet.java
new file mode 100644
index 0000000000..4188e7d60d
--- /dev/null
+++ b/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/LogoutServlet.java
@@ -0,0 +1,65 @@
+/*
+ *
+ * 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.management.plugin.servlet.rest;
+
+import java.io.IOException;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+
+import org.apache.qpid.server.management.plugin.HttpManagement;
+
+@SuppressWarnings("serial")
+public class LogoutServlet extends HttpServlet
+{
+ public static final String RETURN_URL_INIT_PARAM = "qpid.webui_logout_redirect";
+ private String _returnUrl = HttpManagement.ENTRY_POINT_PATH;
+
+ @Override
+ public void init(ServletConfig config) throws ServletException
+ {
+ super.init(config);
+
+ String initValue = config.getServletContext().getInitParameter(RETURN_URL_INIT_PARAM);
+ if(initValue != null)
+ {
+ _returnUrl = initValue;
+ }
+ }
+
+ @Override
+ protected void doGet(HttpServletRequest request, HttpServletResponse resp) throws ServletException, IOException
+ {
+ HttpSession session = request.getSession(false);
+ if(session != null)
+ {
+ // Invalidating the session will cause LoginLogoutReporter to log the user logoff.
+ session.invalidate();
+ }
+
+ resp.sendRedirect(_returnUrl);
+ }
+
+}
diff --git a/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/MessageContentServlet.java b/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/MessageContentServlet.java
index bc87f0bcc5..d61c48bb2c 100644
--- a/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/MessageContentServlet.java
+++ b/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/MessageContentServlet.java
@@ -29,7 +29,6 @@ import javax.servlet.http.HttpServletResponse;
import org.apache.qpid.server.message.MessageReference;
import org.apache.qpid.server.message.ServerMessage;
-import org.apache.qpid.server.model.Broker;
import org.apache.qpid.server.model.Queue;
import org.apache.qpid.server.model.VirtualHost;
import org.apache.qpid.server.queue.QueueEntry;
@@ -42,13 +41,8 @@ public class MessageContentServlet extends AbstractServlet
super();
}
- public MessageContentServlet(Broker broker)
- {
- super(broker);
- }
-
@Override
- protected void onGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
+ protected void doGetWithSubjectAndActor(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{
if(request.getPathInfo() != null && request.getPathInfo().length()>0 && request.getPathInfo().substring(1).split("/").length > 2)
diff --git a/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/MessageServlet.java b/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/MessageServlet.java
index 6e7bc1d935..49e0c2b1bf 100644
--- a/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/MessageServlet.java
+++ b/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/MessageServlet.java
@@ -34,13 +34,10 @@ import org.apache.log4j.Logger;
import org.apache.qpid.server.message.AMQMessageHeader;
import org.apache.qpid.server.message.MessageReference;
import org.apache.qpid.server.message.ServerMessage;
-import org.apache.qpid.server.model.Broker;
import org.apache.qpid.server.model.Queue;
import org.apache.qpid.server.model.VirtualHost;
import org.apache.qpid.server.queue.QueueEntry;
import org.apache.qpid.server.queue.QueueEntryVisitor;
-import org.apache.qpid.server.registry.ApplicationRegistry;
-import org.apache.qpid.server.registry.IApplicationRegistry;
import org.apache.qpid.server.security.SecurityManager;
import org.apache.qpid.server.security.access.Operation;
import org.apache.qpid.server.subscription.Subscription;
@@ -56,13 +53,8 @@ public class MessageServlet extends AbstractServlet
super();
}
- public MessageServlet(Broker broker)
- {
- super(broker);
- }
-
@Override
- protected void onGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
+ protected void doGetWithSubjectAndActor(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{
if(request.getPathInfo() != null && request.getPathInfo().length()>0 && request.getPathInfo().substring(1).split("/").length > 2)
@@ -400,7 +392,7 @@ public class MessageServlet extends AbstractServlet
* POST moves or copies messages to the given queue from a queue specified in the posted JSON data
*/
@Override
- protected void onPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
+ protected void doPostWithSubjectAndActor(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
try
@@ -422,7 +414,7 @@ public class MessageServlet extends AbstractServlet
// FIXME: added temporary authorization check until we introduce management layer
// and review current ACL rules to have common rules for all management interfaces
String methodName = isMoveTransaction? "moveMessages":"copyMessages";
- if (isQueueUpdateMethodAuthorized(methodName, vhost.getName()))
+ if (isQueueUpdateMethodAuthorized(methodName, vhost))
{
final Queue destinationQueue = getQueueFromVirtualHost(destQueueName, vhost);
final List messageIds = new ArrayList((List) providedObject.get("messages"));
@@ -435,7 +427,7 @@ public class MessageServlet extends AbstractServlet
}
else
{
- response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
+ response.setStatus(HttpServletResponse.SC_FORBIDDEN);
}
}
catch(RuntimeException e)
@@ -450,7 +442,7 @@ public class MessageServlet extends AbstractServlet
* DELETE removes messages from the queue
*/
@Override
- protected void onDelete(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
+ protected void doDeleteWithSubjectAndActor(HttpServletRequest request, HttpServletResponse response)
{
final Queue sourceQueue = getQueueFromRequest(request);
@@ -466,37 +458,22 @@ public class MessageServlet extends AbstractServlet
// FIXME: added temporary authorization check until we introduce management layer
// and review current ACL rules to have common rules for all management interfaces
- if (isQueueUpdateMethodAuthorized("deleteMessages", vhost.getName()))
+ if (isQueueUpdateMethodAuthorized("deleteMessages", vhost))
{
vhost.executeTransaction(new DeleteTransaction(sourceQueue, messageIds));
response.setStatus(HttpServletResponse.SC_OK);
}
else
{
- response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
+ response.setStatus(HttpServletResponse.SC_FORBIDDEN);
}
}
- private boolean isQueueUpdateMethodAuthorized(String methodName, String virtualHost)
+ private boolean isQueueUpdateMethodAuthorized(String methodName, VirtualHost host)
{
- SecurityManager securityManager = getSecurityManager(virtualHost);
+ SecurityManager securityManager = host.getSecurityManager();
return securityManager.authoriseMethod(Operation.UPDATE, "VirtualHost.Queue", methodName);
}
- private SecurityManager getSecurityManager(String virtualHost)
- {
- IApplicationRegistry appRegistry = ApplicationRegistry.getInstance();
- SecurityManager security;
- if (virtualHost == null)
- {
- security = appRegistry.getSecurityManager();
- }
- else
- {
- security = appRegistry.getVirtualHostRegistry().getVirtualHost(virtualHost).getSecurityManager();
- }
- return security;
- }
-
}
diff --git a/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/RestServlet.java b/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/RestServlet.java
index 6a79916d07..3fab26cde5 100644
--- a/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/RestServlet.java
+++ b/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/RestServlet.java
@@ -19,6 +19,7 @@ package org.apache.qpid.server.management.plugin.servlet.rest;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.Writer;
+import java.security.AccessControlException;
import java.util.*;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
@@ -31,7 +32,6 @@ import org.apache.qpid.server.model.*;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.SerializationConfig;
-
public class RestServlet extends AbstractServlet
{
private static final Logger LOGGER = Logger.getLogger(RestServlet.class);
@@ -47,29 +47,29 @@ public class RestServlet extends AbstractServlet
private Class<? extends ConfiguredObject>[] _hierarchy;
- private volatile boolean initializationRequired = false;
-
private final ConfiguredObjectToMapConverter _objectConverter = new ConfiguredObjectToMapConverter();
+ private final boolean _hierarchyInitializationRequired;
public RestServlet()
{
super();
- initializationRequired = true;
+ _hierarchyInitializationRequired = true;
}
- public RestServlet(Broker broker, Class<? extends ConfiguredObject>... hierarchy)
+ public RestServlet(Class<? extends ConfiguredObject>... hierarchy)
{
- super(broker);
+ super();
_hierarchy = hierarchy;
+ _hierarchyInitializationRequired = false;
}
@Override
public void init() throws ServletException
{
- if (initializationRequired)
+ super.init();
+ if (_hierarchyInitializationRequired)
{
doInitialization();
- initializationRequired = false;
}
}
@@ -285,7 +285,7 @@ public class RestServlet extends AbstractServlet
}
@Override
- protected void onGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
+ protected void doGetWithSubjectAndActor(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
response.setContentType("application/json");
response.setStatus(HttpServletResponse.SC_OK);
@@ -319,7 +319,7 @@ public class RestServlet extends AbstractServlet
}
@Override
- protected void onPut(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
+ protected void doPutWithSubjectAndActor(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
response.setContentType("application/json");
@@ -336,7 +336,8 @@ public class RestServlet extends AbstractServlet
if(names.size() != _hierarchy.length)
{
- throw new IllegalArgumentException("Path to object to create must be fully specified");
+ throw new IllegalArgumentException("Path to object to create must be fully specified. "
+ + "Found " + names.size() + " expecting " + _hierarchy.length);
}
}
@@ -428,8 +429,11 @@ public class RestServlet extends AbstractServlet
|| (obj.getName().equals(providedObject.get("name")) && equalParents(obj, otherParents)))
{
doUpdate(obj, providedObject);
+ response.setStatus(HttpServletResponse.SC_OK);
+ return;
}
}
+
theParent.createChild(objClass, providedObject, otherParents);
}
catch (RuntimeException e)
@@ -462,13 +466,17 @@ public class RestServlet extends AbstractServlet
private void setResponseStatus(HttpServletResponse response, RuntimeException e) throws IOException
{
- if (e.getCause() instanceof AMQSecurityException)
+ if (e instanceof AccessControlException || e.getCause() instanceof AMQSecurityException)
{
- response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
+ if (LOGGER.isDebugEnabled())
+ {
+ LOGGER.debug("Caught security exception, sending " + HttpServletResponse.SC_FORBIDDEN, e);
+ }
+ response.setStatus(HttpServletResponse.SC_FORBIDDEN);
}
else
{
- LOGGER.warn("Unexpected exception is caught", e);
+ LOGGER.warn("Caught exception", e);
// TODO
response.setStatus(HttpServletResponse.SC_CONFLICT);
@@ -476,7 +484,7 @@ public class RestServlet extends AbstractServlet
}
@Override
- protected void onDelete(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
+ protected void doDeleteWithSubjectAndActor(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
response.setContentType("application/json");
response.setStatus(HttpServletResponse.SC_OK);
diff --git a/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/SaslServlet.java b/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/SaslServlet.java
index 1b78611a50..069132af1e 100644
--- a/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/SaslServlet.java
+++ b/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/SaslServlet.java
@@ -25,10 +25,9 @@ import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.SerializationConfig;
import org.apache.log4j.Logger;
-import org.apache.qpid.server.model.Broker;
-import org.apache.qpid.server.registry.ApplicationRegistry;
-import org.apache.qpid.server.security.auth.manager.AuthenticationManager;
-import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal;
+import org.apache.qpid.server.management.plugin.HttpManagement;
+import org.apache.qpid.server.security.SubjectCreator;
+import org.apache.qpid.server.security.auth.AuthenticatedPrincipal;
import javax.security.auth.Subject;
import javax.security.sasl.SaslException;
@@ -39,6 +38,7 @@ import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;
+import java.security.AccessControlException;
import java.security.Principal;
import java.security.SecureRandom;
import java.util.LinkedHashMap;
@@ -47,6 +47,7 @@ import java.util.Random;
public class SaslServlet extends AbstractServlet
{
+
private static final Logger LOGGER = Logger.getLogger(SaslServlet.class);
private static final SecureRandom SECURE_RANDOM = new SecureRandom();
@@ -56,18 +57,12 @@ public class SaslServlet extends AbstractServlet
private static final String ATTR_EXPIRY = "SaslServlet.Expiry";
private static final long SASL_EXCHANGE_EXPIRY = 1000L;
-
public SaslServlet()
{
super();
}
- public SaslServlet(Broker broker)
- {
- super(broker);
- }
-
- protected void onGet(HttpServletRequest request, HttpServletResponse response) throws
+ protected void doGetWithSubjectAndActor(HttpServletRequest request, HttpServletResponse response) throws
ServletException,
IOException
{
@@ -79,15 +74,16 @@ public class SaslServlet extends AbstractServlet
response.setDateHeader ("Expires", 0);
HttpSession session = request.getSession();
- Random rand = getRandom(session);
+ getRandom(session);
- AuthenticationManager authManager = ApplicationRegistry.getInstance().getAuthenticationManager(getSocketAddress(request));
- String[] mechanisms = authManager.getMechanisms().split(" ");
+ SubjectCreator subjectCreator = getSubjectCreator(request);
+ String[] mechanisms = subjectCreator.getMechanisms().split(" ");
Map<String, Object> outputObject = new LinkedHashMap<String, Object>();
- final Subject subject = (Subject) session.getAttribute("subject");
+
+ final Subject subject = getAuthorisedSubjectFromSession(session);
if(subject != null)
{
- final Principal principal = subject.getPrincipals().iterator().next();
+ Principal principal = AuthenticatedPrincipal.getAuthenticatedPrincipalFromSubject(subject);
outputObject.put("user", principal.getName());
}
else if (request.getRemoteUser() != null)
@@ -121,9 +117,10 @@ public class SaslServlet extends AbstractServlet
@Override
- protected void onPost(final HttpServletRequest request, final HttpServletResponse response)
- throws ServletException, IOException
+ protected void doPostWithSubjectAndActor(final HttpServletRequest request, final HttpServletResponse response) throws IOException
{
+ checkSaslAuthEnabled(request);
+
try
{
response.setContentType("application/json");
@@ -137,14 +134,18 @@ public class SaslServlet extends AbstractServlet
String id = request.getParameter("id");
String saslResponse = request.getParameter("response");
- AuthenticationManager authManager = ApplicationRegistry.getInstance().getAuthenticationManager(getSocketAddress(request));
+ SubjectCreator subjectCreator = getSubjectCreator(request);
if(mechanism != null)
{
if(id == null)
{
- SaslServer saslServer = authManager.createSaslServer(mechanism, request.getServerName(), null/*TODO*/);
- evaluateSaslResponse(response, session, saslResponse, saslServer);
+ if(LOGGER.isDebugEnabled())
+ {
+ LOGGER.debug("Creating SaslServer for mechanism: " + mechanism);
+ }
+ SaslServer saslServer = subjectCreator.createSaslServer(mechanism, request.getServerName(), null/*TODO*/);
+ evaluateSaslResponse(request, response, session, saslResponse, saslServer, subjectCreator);
}
else
{
@@ -152,9 +153,7 @@ public class SaslServlet extends AbstractServlet
session.removeAttribute(ATTR_ID);
session.removeAttribute(ATTR_SASL_SERVER);
session.removeAttribute(ATTR_EXPIRY);
-
}
-
}
else
{
@@ -163,8 +162,7 @@ public class SaslServlet extends AbstractServlet
if(id.equals(session.getAttribute(ATTR_ID)) && System.currentTimeMillis() < (Long) session.getAttribute(ATTR_EXPIRY))
{
SaslServer saslServer = (SaslServer) session.getAttribute(ATTR_SASL_SERVER);
- evaluateSaslResponse(response, session, saslResponse, saslServer);
-
+ evaluateSaslResponse(request, response, session, saslResponse, saslServer, subjectCreator);
}
else
{
@@ -180,7 +178,6 @@ public class SaslServlet extends AbstractServlet
session.removeAttribute(ATTR_ID);
session.removeAttribute(ATTR_SASL_SERVER);
session.removeAttribute(ATTR_EXPIRY);
-
}
}
}
@@ -194,12 +191,30 @@ public class SaslServlet extends AbstractServlet
LOGGER.error("Error processing SASL request", e);
throw e;
}
+ }
+ private void checkSaslAuthEnabled(HttpServletRequest request)
+ {
+ boolean saslAuthEnabled;
+ HttpManagement management = getManagement();
+ if (request.isSecure())
+ {
+ saslAuthEnabled = management.isHttpsSaslAuthenticationEnabled();
+ }
+ else
+ {
+ saslAuthEnabled = management.isHttpSaslAuthenticationEnabled();
+ }
+
+ if (!saslAuthEnabled)
+ {
+ throw new RuntimeException("Sasl authentication disabled.");
+ }
}
- private void evaluateSaslResponse(final HttpServletResponse response,
- final HttpSession session,
- final String saslResponse, final SaslServer saslServer) throws IOException
+ private void evaluateSaslResponse(final HttpServletRequest request,
+ final HttpServletResponse response,
+ final HttpSession session, final String saslResponse, final SaslServer saslServer, SubjectCreator subjectCreator) throws IOException
{
final String id;
byte[] challenge;
@@ -209,27 +224,34 @@ public class SaslServlet extends AbstractServlet
}
catch(SaslException e)
{
-
session.removeAttribute(ATTR_ID);
session.removeAttribute(ATTR_SASL_SERVER);
session.removeAttribute(ATTR_EXPIRY);
- response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
+ response.setStatus(HttpServletResponse.SC_FORBIDDEN);
return;
}
if(saslServer.isComplete())
{
- final Subject subject = new Subject();
- subject.getPrincipals().add(new UsernamePrincipal(saslServer.getAuthorizationID()));
- session.setAttribute("subject", subject);
+ Subject subject = subjectCreator.createSubjectWithGroups(saslServer.getAuthorizationID());
+
+ try
+ {
+ authoriseManagement(request, subject);
+ }
+ catch (AccessControlException ace)
+ {
+ sendError(response, HttpServletResponse.SC_FORBIDDEN);
+ return;
+ }
+
+ setAuthorisedSubjectInSession(subject, request, session);
session.removeAttribute(ATTR_ID);
session.removeAttribute(ATTR_SASL_SERVER);
session.removeAttribute(ATTR_EXPIRY);
response.setStatus(HttpServletResponse.SC_OK);
-
-
}
else
{
@@ -250,7 +272,6 @@ public class SaslServlet extends AbstractServlet
ObjectMapper mapper = new ObjectMapper();
mapper.configure(SerializationConfig.Feature.INDENT_OUTPUT, true);
mapper.writeValue(writer, outputObject);
-
}
}
}
diff --git a/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/StructureServlet.java b/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/StructureServlet.java
index 60f977ca66..40d3c02768 100644
--- a/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/StructureServlet.java
+++ b/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/StructureServlet.java
@@ -41,13 +41,8 @@ public class StructureServlet extends AbstractServlet
super();
}
- public StructureServlet(Broker broker)
- {
- super(broker);
- }
-
@Override
- protected void onGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
+ protected void doGetWithSubjectAndActor(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{
response.setContentType("application/json");
response.setStatus(HttpServletResponse.SC_OK);
@@ -56,6 +51,8 @@ public class StructureServlet extends AbstractServlet
response.setHeader("Pragma","no-cache");
response.setDateHeader ("Expires", 0);
+ // TODO filtering??? request.getParameter("filter"); // filter=1,2,3 /groups/*/*
+
Map<String,Object> structure = generateStructure(getBroker(), Broker.class);
final PrintWriter writer = response.getWriter();
diff --git a/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/session/LoginLogoutReporter.java b/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/session/LoginLogoutReporter.java
new file mode 100644
index 0000000000..238f1b4719
--- /dev/null
+++ b/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/session/LoginLogoutReporter.java
@@ -0,0 +1,103 @@
+/*
+ * 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.management.plugin.session;
+
+import java.security.Principal;
+import java.security.PrivilegedAction;
+
+import javax.security.auth.Subject;
+import javax.servlet.http.HttpSession;
+import javax.servlet.http.HttpSessionBindingEvent;
+import javax.servlet.http.HttpSessionBindingListener;
+
+import org.apache.log4j.Logger;
+import org.apache.qpid.server.logging.LogActor;
+import org.apache.qpid.server.logging.messages.ManagementConsoleMessages;
+import org.apache.qpid.server.security.auth.AuthenticatedPrincipal;
+
+/**
+ * Logs {@link ManagementConsoleMessages#OPEN(String)} and {@link ManagementConsoleMessages#CLOSE(String)}
+ * messages. A single instance of this class must be placed in the {@link HttpSession} immediately after
+ * the user has successfully logged-in, and removed (or the whole session invalidated) as the user logs out.
+ */
+public class LoginLogoutReporter implements HttpSessionBindingListener
+{
+ private static final Logger LOGGER = Logger.getLogger(LoginLogoutReporter.class);
+ private final LogActor _logActor;
+ private final Subject _subject;
+ private final Principal _principal;
+
+ public LoginLogoutReporter(LogActor logActor, Subject subject)
+ {
+ super();
+ _logActor = logActor;
+ _subject = subject;
+ _principal = AuthenticatedPrincipal.getAuthenticatedPrincipalFromSubject(_subject);
+ }
+
+ @Override
+ public void valueBound(HttpSessionBindingEvent arg0)
+ {
+ reportLogin();
+ }
+
+ @Override
+ public void valueUnbound(HttpSessionBindingEvent arg0)
+ {
+ reportLogout();
+ }
+
+ private void reportLogin()
+ {
+ if (LOGGER.isDebugEnabled())
+ {
+ LOGGER.debug("User logging in : " + _principal);
+ }
+
+ Subject.doAs(_subject, new PrivilegedAction<Void>()
+ {
+ @Override
+ public Void run()
+ {
+ _logActor.message(ManagementConsoleMessages.OPEN(_principal.getName()));
+ return null;
+ }
+ });
+ }
+
+ private void reportLogout()
+ {
+ if (LOGGER.isDebugEnabled())
+ {
+ LOGGER.debug("User logging out : " + _principal);
+ }
+
+ Subject.doAs(_subject, new PrivilegedAction<Void>()
+ {
+ @Override
+ public Void run()
+ {
+ _logActor.message(ManagementConsoleMessages.CLOSE(_principal.getName()));
+ return null;
+ }
+ });
+ }
+
+}
diff --git a/java/broker-plugins/management-http/src/main/java/resources/authenticationprovider/showPrincipalDatabaseAuthenticationManager.html b/java/broker-plugins/management-http/src/main/java/resources/authenticationprovider/showPrincipalDatabaseAuthenticationManager.html
index baadc8c35f..e6c067fddf 100644
--- a/java/broker-plugins/management-http/src/main/java/resources/authenticationprovider/showPrincipalDatabaseAuthenticationManager.html
+++ b/java/broker-plugins/management-http/src/main/java/resources/authenticationprovider/showPrincipalDatabaseAuthenticationManager.html
@@ -23,7 +23,5 @@
<div class="users"></div>
<button data-dojo-type="dijit.form.Button" class="addUserButton">Add User</button>
<button data-dojo-type="dijit.form.Button" class="deleteUserButton">Delete Users</button>
-
</div>
-
</div>
diff --git a/java/broker-plugins/management-http/src/main/java/resources/group/addGroupMember.html b/java/broker-plugins/management-http/src/main/java/resources/group/addGroupMember.html
new file mode 100644
index 0000000000..0372468f91
--- /dev/null
+++ b/java/broker-plugins/management-http/src/main/java/resources/group/addGroupMember.html
@@ -0,0 +1,37 @@
+<!--
+ -
+ - 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 Group Member'" id="addGroupMember">
+ <form id="formAddGroupMember" method="post" dojoType="dijit.form.Form">
+ <table cellpadding="0" cellspacing="2">
+ <tr>
+ <td valign="top"><strong>Name*: </strong></td>
+ <td><input type="text" required="true" name="name" id="formAddGroupMember.name" placeholder="Name"
+ dojoType="dijit.form.ValidationTextBox" missingMessage="A name must be supplied" /></td>
+ </tr>
+ </table>
+ <br/>
+
+ <!-- submit buttons -->
+ <input type="submit" value="Add Group Member" label="Add Group Member" dojoType="dijit.form.Button" />
+ </form>
+ </div>
+</div>
diff --git a/java/broker-plugins/firewall/build.xml b/java/broker-plugins/management-http/src/main/java/resources/group/showGroup.html
index 6ae6a35b89..4fddf727d0 100644
--- a/java/broker-plugins/firewall/build.xml
+++ b/java/broker-plugins/management-http/src/main/java/resources/group/showGroup.html
@@ -1,4 +1,5 @@
<!--
+ -
- 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
@@ -6,29 +7,24 @@
- 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.
+ -
-->
-<project name="Qpid Broker-Plugins Firewall" default="build">
- <property name="module.depends" value="common broker" />
- <property name="module.test.depends" value="test broker/test common/test management/common" />
-
- <property name="module.manifest" value="MANIFEST.MF" />
- <property name="module.plugin" value="true" />
- <property name="module.genpom" value="true"/>
- <property name="module.genpom.args" value="-Sqpid-common=provided -Sqpid-broker=provided"/>
+<div class="group">
+ <span style="">Name:</span><span class="name" style="position:absolute; left:6em"></span>
+ <br/>
+ <div data-dojo-type="dijit.TitlePane" data-dojo-props="title: 'Group Members'">
+ <div class="groupMembers"></div>
+ <button data-dojo-type="dijit.form.Button" class="addGroupMemberButton" type="button">Add Group Member</button>
+ <button data-dojo-type="dijit.form.Button" class="removeGroupMemberButton" type="button">Remove Group Members</button>
+ </div>
+</div>
- <property name="broker-plugins-firewall.libs" value=""/>
-
- <import file="../../module.xml" />
-
- <target name="bundle" depends="bundle-tasks" />
-
-</project>
diff --git a/java/broker-plugins/management-http/src/main/java/resources/groupprovider/addGroup.html b/java/broker-plugins/management-http/src/main/java/resources/groupprovider/addGroup.html
new file mode 100644
index 0000000000..8d3431808a
--- /dev/null
+++ b/java/broker-plugins/management-http/src/main/java/resources/groupprovider/addGroup.html
@@ -0,0 +1,38 @@
+<!--
+ -
+ - 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 Group'" id="addGroup">
+ <form id="formAddGroup" method="post" dojoType="dijit.form.Form">
+ <table cellpadding="0" cellspacing="2">
+ <tr>
+ <td valign="top"><strong>Group Name*: </strong></td>
+ <td><input type="text" required="true" name="name" id="formAddGroup.name" placeholder="Group Name"
+ dojoType="dijit.form.ValidationTextBox" missingMessage="A name must be supplied" /></td>
+ </tr>
+ </table>
+ <br/>
+
+ <!-- submit buttons -->
+ <input type="submit" value="Create Group" label="Create Group" dojoType="dijit.form.Button" />
+
+ </form>
+ </div>
+</div>
diff --git a/java/broker-plugins/management-http/src/main/java/resources/groupprovider/showFileGroupManager.html b/java/broker-plugins/management-http/src/main/java/resources/groupprovider/showFileGroupManager.html
new file mode 100644
index 0000000000..734e8b5419
--- /dev/null
+++ b/java/broker-plugins/management-http/src/main/java/resources/groupprovider/showFileGroupManager.html
@@ -0,0 +1,28 @@
+<!--
+ -
+ - 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="FileGroupManager">
+ <div data-dojo-type="dijit.TitlePane" data-dojo-props="title: 'Groups'">
+ <div class="groups"></div>
+ <button data-dojo-type="dijit.form.Button" class="addGroupButton">Add Group</button>
+ <button data-dojo-type="dijit.form.Button" class="deleteGroupButton">Delete Groups</button>
+ </div>
+
+</div>
diff --git a/java/broker-plugins/management-http/src/main/java/resources/management.html b/java/broker-plugins/management-http/src/main/java/resources/index.html
index a8345a8503..2fb9137ff8 100644
--- a/java/broker-plugins/management-http/src/main/java/resources/management.html
+++ b/java/broker-plugins/management-http/src/main/java/resources/index.html
@@ -73,10 +73,8 @@
<div id="pageLayout" data-dojo-type="dijit.layout.BorderContainer" data-dojo-props="design: 'headline', gutters: false">
<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props="region:'top'">
- <div id="header" class="header"></div>
- </div>
- <div data-dojo-type="dijit.layout.ContentPane" data-dojo-props="region:'top'">
- <div id="login"></div>
+ <div id="header" class="header" style="float: left; width: 300px"></div>
+ <div id="login" style="float: right"></div>
</div>
<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props="region:'leading', splitter: true">
<div qpid-type="treeView" qpid-props="query: 'rest/structure'" ></div>
diff --git a/java/broker-plugins/management-http/src/main/java/resources/js/qpid/authorization/sasl.js b/java/broker-plugins/management-http/src/main/java/resources/js/qpid/authorization/sasl.js
index 152504da86..b4f0728685 100644
--- a/java/broker-plugins/management-http/src/main/java/resources/js/qpid/authorization/sasl.js
+++ b/java/broker-plugins/management-http/src/main/java/resources/js/qpid/authorization/sasl.js
@@ -71,7 +71,7 @@ var saslPlain = function saslPlain(user, password)
},
function(error)
{
- if(error.status == 401)
+ if(error.status == 403)
{
alert("Authentication Failed");
}
@@ -127,7 +127,7 @@ var saslCramMD5 = function saslCramMD5(user, password)
},
function(error)
{
- if(error.status == 401)
+ if(error.status == 403)
{
alert("Authentication Failed");
}
@@ -141,7 +141,7 @@ var saslCramMD5 = function saslCramMD5(user, password)
},
function(error)
{
- if(error.status == 401)
+ if(error.status == 403)
{
alert("Authentication Failed");
}
@@ -152,10 +152,45 @@ var saslCramMD5 = function saslCramMD5(user, password)
});
};
+var containsMechanism = function containsMechanism(mechanisms, mech)
+{
+ for (var i = 0; i < mechanisms.length; i++) {
+ if (mechanisms[i] == mech) {
+ return true;
+ }
+ }
+
+ return false;
+};
+
var doAuthenticate = function doAuthenticate()
{
- saslCramMD5(dojo.byId("username").value, dojo.byId("pass").value);
- updateAuthentication();
+ dojo.xhrGet({
+ // The URL of the request
+ url: "rest/sasl",
+ handleAs: "json"
+ }).then(function(data)
+ {
+ var mechMap = data.mechanisms;
+
+ if (containsMechanism(mechMap, "CRAM-MD5"))
+ {
+ saslCramMD5(dojo.byId("username").value, dojo.byId("pass").value);
+ updateAuthentication();
+ }
+ else if (containsMechanism(mechMap, "PLAIN"))
+ {
+ saslPlain(dojo.byId("username").value, dojo.byId("pass").value);
+ updateAuthentication();
+ }
+ else
+ {
+ alert("No supported SASL mechanism offered: " + mechMap);
+ }
+ }
+ );
+
+
};
@@ -170,13 +205,13 @@ var updateAuthentication = function updateAuthentication()
if(data.user)
{
dojo.byId("authenticatedUser").innerHTML = data.user;
- dojo.style(button.domNode, {visibility: 'hidden'});
- dojo.style(usernameSpan, {visibility: 'visible'});
+ dojo.style(button.domNode, {display: 'none'});
+ dojo.style(usernameSpan, {display: 'block'});
}
else
{
- dojo.style(button.domNode, {visibility: 'visible'});
- dojo.style(usernameSpan, {visibility: 'hidden'});
+ dojo.style(button.domNode, {display: 'block'});
+ dojo.style(usernameSpan, {display: 'none'});
}
}
);
@@ -198,13 +233,13 @@ require(["dijit/form/DropDownButton", "dijit/TooltipDialog", "dijit/form/TextBox
dropDown: dialog
});
- usernameSpan = domConstruct.create("span", { innerHTML: '<strong>User: </strong><span id="authenticatedUser"></span>',
- style: { visibility: "hidden" }});
+ usernameSpan = domConstruct.create("span", { innerHTML: '<strong>User: </strong> <span id="authenticatedUser"></span><a href="logout">[logout]</a>',
+ style: { display: "none" }});
var loginDiv = dom.byId("login");
- loginDiv.appendChild(button.domNode);
loginDiv.appendChild(usernameSpan);
+ loginDiv.appendChild(button.domNode);
diff --git a/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/util.js b/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/util.js
index 08fdf5c99b..5557c37a2c 100644
--- a/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/util.js
+++ b/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/util.js
@@ -58,10 +58,10 @@ define(["dojo/_base/xhr"],
return exchangeName == null || exchangeName == "" || "<<default>>" == exchangeName || exchangeName.indexOf("amq.") == 0 || exchangeName.indexOf("qpid.") == 0;
};
- util.deleteGridSelections = function(updater, gridName, url, confirmationMessageStart)
+ util.deleteGridSelections = function(updater, grid, url, confirmationMessageStart)
{
- var grid = updater[gridName].grid;
var data = grid.selection.getSelected();
+
if(data.length)
{
var confirmationMessage = null;
@@ -103,7 +103,8 @@ define(["dojo/_base/xhr"],
xhr.del({url: query, sync: true, handleAs: "json"}).then(
function(data)
{
- grid.setQuery({id: "*"});
+ // TODO why query *??
+ //grid.setQuery({id: "*"});
grid.selection.deselectAll();
updater.update();
},
diff --git a/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/Exchange.js b/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/Exchange.js
index 37bae1ef8e..5a5a6515ef 100644
--- a/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/Exchange.js
+++ b/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/Exchange.js
@@ -115,7 +115,7 @@ define(["dojo/_base/xhr",
{
util.deleteGridSelections(
this.exchangeUpdater,
- "bindingsGrid",
+ that.exchangeUpdater.bindingsGrid.grid,
"rest/binding/"+ encodeURIComponent(this.getVirtualHostName()) + "/" + encodeURIComponent(this.name),
"Are you sure you want to delete binding for queue");
}
diff --git a/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/GroupProvider.js b/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/GroupProvider.js
new file mode 100644
index 0000000000..4e05f4b0ea
--- /dev/null
+++ b/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/GroupProvider.js
@@ -0,0 +1,109 @@
+/*
+ *
+ * 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/parser",
+ "dojo/query",
+ "dojo/_base/connect",
+ "qpid/common/properties",
+ "qpid/common/updater",
+ "qpid/common/util",
+ "qpid/common/UpdatableStore",
+ "dojox/grid/EnhancedGrid",
+ "dojox/grid/enhanced/plugins/Pagination",
+ "dojox/grid/enhanced/plugins/IndirectSelection",
+ "dojo/domReady!"],
+ function (xhr, parser, query, connect, properties, updater, util, UpdatableStore, EnhancedGrid) {
+
+ function GroupProvider(name, parent, controller) {
+ this.name = name;
+ this.controller = controller;
+ this.modelObj = { type: "groupprovider", name: name };
+ if(parent) {
+ this.modelObj.parent = {};
+ this.modelObj.parent[ parent.type] = parent;
+ }
+ }
+
+ GroupProvider.prototype.getTitle = function() {
+ return "GroupProvider";
+ };
+
+ GroupProvider.prototype.open = function(contentPane) {
+ var that = this;
+ this.contentPane = contentPane;
+ xhr.get({url: "showGroupProvider.html",
+ sync: true,
+ load: function(data) {
+ contentPane.containerNode.innerHTML = data;
+ parser.parse(contentPane.containerNode);
+
+ that.groupProviderAdapter = new GroupProviderUpdater(contentPane.containerNode, that.modelObj, that.controller);
+
+ updater.add( that.groupProviderAdapter );
+
+ that.groupProviderAdapter.update();
+
+ }});
+ };
+
+ GroupProvider.prototype.close = function() {
+ updater.remove( this.groupProviderAdapter );
+ };
+
+ function GroupProviderUpdater(node, groupProviderObj, controller)
+ {
+ this.controller = controller;
+ this.name = query(".name", node)[0];
+ this.query = "rest/groupprovider/"+encodeURIComponent(groupProviderObj.name);
+
+ var that = this;
+
+ xhr.get({url: this.query, sync: properties.useSyncGet, handleAs: "json"})
+ .then(function(data)
+ {
+ that.groupProviderData = data[0];
+
+ util.flattenStatistics( that.groupProviderData );
+
+ that.updateHeader();
+
+ require(["qpid/management/groupprovider/"+that.groupProviderData.type],
+ function(SpecificProvider) {
+ that.details = new SpecificProvider(node, groupProviderObj, controller);
+ that.details.update();
+ });
+
+ });
+
+ }
+
+ GroupProviderUpdater.prototype.updateHeader = function()
+ {
+ this.name.innerHTML = this.groupProviderData[ "name" ];
+ };
+
+ GroupProviderUpdater.prototype.update = function()
+ {
+ var that = this;
+ };
+
+ return GroupProvider;
+ });
diff --git a/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/VirtualHost.js b/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/VirtualHost.js
index 957f2381cf..2efc46476d 100644
--- a/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/VirtualHost.js
+++ b/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/VirtualHost.js
@@ -72,7 +72,7 @@ define(["dojo/_base/xhr",
function(evt){
util.deleteGridSelections(
that.vhostUpdater,
- "queuesGrid",
+ that.vhostUpdater.queuesGrid.grid,
"rest/queue/"+ encodeURIComponent(that.name),
"Are you sure you want to delete queue");
}
@@ -87,7 +87,7 @@ define(["dojo/_base/xhr",
{
util.deleteGridSelections(
that.vhostUpdater,
- "exchangesGrid",
+ that.vhostUpdater.exchangesGrid.grid,
"rest/exchange/"+ encodeURIComponent(that.name),
"Are you sure you want to delete exchange");
}
diff --git a/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/controller.js b/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/controller.js
index 1aa05a5a3c..5d3a666760 100644
--- a/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/controller.js
+++ b/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/controller.js
@@ -27,13 +27,17 @@ define(["dojo/dom",
"qpid/management/Queue",
"qpid/management/Connection",
"qpid/management/AuthenticationProvider",
+ "qpid/management/GroupProvider",
+ "qpid/management/group/Group",
"dojo/ready",
"dojo/domReady!"],
- function (dom, registry, ContentPane, Broker, VirtualHost, Exchange, Queue, Connection, AuthProvider, ready) {
+ function (dom, registry, ContentPane, Broker, VirtualHost, Exchange, Queue, Connection, AuthProvider, GroupProvider, Group, ready) {
var controller = {};
var constructors = { broker: Broker, virtualhost: VirtualHost, exchange: Exchange,
- queue: Queue, connection: Connection, authenticationprovider: AuthProvider };
+ queue: Queue, connection: Connection,
+ authenticationprovider: AuthProvider, groupprovider: GroupProvider,
+ group: Group };
var tabDiv = dom.byId("managedViews");
diff --git a/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/group/Group.js b/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/group/Group.js
new file mode 100644
index 0000000000..ea918644e9
--- /dev/null
+++ b/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/group/Group.js
@@ -0,0 +1,204 @@
+/*
+ *
+ * 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/parser",
+ "dojo/query",
+ "dijit/registry",
+ "dojo/_base/connect",
+ "dojo/_base/event",
+ "dojo/json",
+ "qpid/common/properties",
+ "qpid/common/updater",
+ "qpid/common/util",
+ "qpid/common/formatter",
+ "qpid/common/UpdatableStore",
+ "dojo/store/JsonRest",
+ "dojox/grid/EnhancedGrid",
+ "dojo/data/ObjectStore",
+ "qpid/management/group/addGroupMember",
+ "dojox/grid/enhanced/plugins/Pagination",
+ "dojox/grid/enhanced/plugins/IndirectSelection",
+ "dojo/domReady!"],
+ function (xhr, parser, query, registry, connect, event, json, properties, updater, util, formatter,
+ UpdatableStore, JsonRest, EnhancedGrid, ObjectStore, addGroupMember) {
+
+ function Group(name, parent, controller) {
+ this.name = name;
+ this.controller = controller;
+ this.modelObj = { type: "group", name: name };
+
+ if(parent) {
+ this.modelObj.parent = {};
+ this.modelObj.parent[ parent.type] = parent;
+ }
+ }
+
+ Group.prototype.getGroupName = function()
+ {
+ return this.name;
+ };
+
+
+ Group.prototype.getGroupProviderName = function()
+ {
+ return this.modelObj.parent.groupprovider.name;
+ };
+
+ Group.prototype.getTitle = function()
+ {
+ return "Group: " + this.name;
+ };
+
+ Group.prototype.open = function(contentPane) {
+ var that = this;
+ this.contentPane = contentPane;
+
+ xhr.get({url: "group/showGroup.html",
+ sync: true,
+ load: function(data) {
+ contentPane.containerNode.innerHTML = data;
+ parser.parse(contentPane.containerNode);
+
+ that.groupUpdater = new GroupUpdater(contentPane.containerNode, that, that.controller);
+
+ updater.add( that.groupUpdater );
+
+ that.groupUpdater.update();
+
+ var addGroupMemberButton = query(".addGroupMemberButton", contentPane.containerNode)[0];
+ connect.connect(registry.byNode(addGroupMemberButton), "onClick",
+ function(evt){
+ addGroupMember.show(that.getGroupProviderName(), that.getGroupName())
+ }
+ );
+
+ var removeGroupMemberButton = query(".removeGroupMemberButton", contentPane.containerNode)[0];
+ connect.connect(registry.byNode(removeGroupMemberButton), "onClick",
+ function(evt){
+ util.deleteGridSelections(
+ that.groupUpdater,
+ that.groupUpdater.groupMembersUpdatableStore.grid,
+ "rest/groupmember/"+ encodeURIComponent(that.getGroupProviderName()) +
+ "/" + encodeURIComponent(that.getGroupName()),
+ "Are you sure you want to remove group member");
+ }
+ );
+ }});
+ };
+
+ Group.prototype.close = function() {
+ updater.remove( this.groupUpdater );
+ };
+
+ function GroupUpdater(containerNode, groupObj, controller)
+ {
+ var that = this;
+
+ function findNode(name) {
+ return query("." + name, containerNode)[0];
+ }
+
+ function storeNodes(names)
+ {
+ for(var i = 0; i < names.length; i++) {
+ that[names[i]] = findNode(names[i]);
+ }
+ }
+
+ storeNodes(["name",
+ "state",
+ "durable",
+ "lifetimePolicy",
+ "type"]);
+
+ this.query = "rest/groupmember/"+ encodeURIComponent(groupObj.getGroupProviderName()) + "/" + encodeURIComponent(groupObj.getGroupName());
+
+ xhr.get({url: this.query, sync: properties.useSyncGet, handleAs: "json"}).then(function(data)
+ {
+ that.groupMemberData = data;
+
+ util.flattenStatistics( that.groupMemberData );
+
+ 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.groupMembersUpdatableStore = new UpdatableStore(that.groupMemberData, findNode("groupMembers"),
+ [ { name: "Group Member Name", field: "name", width: "100%" }],
+ function(obj)
+ {
+ connect.connect(obj.grid, "onRowDblClick", obj.grid,
+ function(evt){
+
+ });
+ } , gridProperties, EnhancedGrid);
+
+ });
+
+ }
+
+ GroupUpdater.prototype.update = function()
+ {
+
+ var that = this;
+
+ xhr.get({url: this.query, sync: properties.useSyncGet, handleAs: "json"})
+ .then(function(data) {
+ that.groupMemberData = data;
+
+ util.flattenStatistics( that.groupMemberData );
+
+ that.groupMembersUpdatableStore.update(that.groupMemberData);
+ });
+ };
+
+ Group.prototype.deleteGroupMember = function() {
+ if(confirm("Are you sure you want to delete group member'" +this.name+"'?")) {
+ var query = "rest/groupmember/"+ encodeURIComponent(this.getGroupProviderName()) + "/" + 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 Group;
+ });
diff --git a/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/group/addGroupMember.js b/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/group/addGroupMember.js
new file mode 100644
index 0000000000..1861cc6ffe
--- /dev/null
+++ b/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/group/addGroupMember.js
@@ -0,0 +1,108 @@
+/*
+ *
+ * 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',
+ "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",
+ "dojo/domReady!"],
+ function (xhr, dom, construct, win, registry, parser, array, event, json) {
+
+ var addGroupMember = {};
+
+ var node = construct.create("div", null, win.body(), "last");
+
+ var convertToGroupMember = function convertToGroupMember(formValues)
+ {
+ var newGroupMember = {};
+ newGroupMember.name = formValues.name;
+ return newGroupMember;
+ };
+
+ xhr.get({url: "group/addGroupMember.html",
+ sync: true,
+ load: function(data) {
+ var theForm;
+ node.innerHTML = data;
+ addGroupMember.dialogNode = dom.byId("addGroupMember");
+ parser.instantiate([addGroupMember.dialogNode]);
+
+ theForm = registry.byId("formAddGroupMember");
+ theForm.on("submit", function(e) {
+
+ event.stop(e);
+ if(theForm.validate()){
+
+ var newGroupMember = convertToGroupMember(theForm.getValues());
+ var that = this;
+ xhr.put({url: "rest/groupmember/"+encodeURIComponent(addGroupMember.groupProvider) +
+ "/" + encodeURIComponent(addGroupMember.group) + "/" + encodeURIComponent(newGroupMember.name), sync: true, handleAs: "json",
+ headers: { "Content-Type": "application/json"},
+ putData: json.toJson(newGroupMember),
+ load: function(x) {that.success = true; },
+ error: function(error) {that.success = false; that.failureReason = error;}});
+
+ if(this.success === true)
+ {
+ registry.byId("addGroupMember").hide();
+ }
+ else
+ {
+ alert("Error:" + this.failureReason);
+ }
+
+ return false;
+
+
+ }else{
+ alert('Form contains invalid data. Please correct first');
+ return false;
+ }
+
+ });
+ }});
+
+ addGroupMember.show = function(groupProvider, group) {
+ addGroupMember.groupProvider = groupProvider;
+ addGroupMember.group = group;
+ registry.byId("formAddGroupMember").reset();
+ registry.byId("addGroupMember").show();
+ };
+
+ return addGroupMember;
+ }); \ No newline at end of file
diff --git a/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/groupprovider/FileGroupManager.js b/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/groupprovider/FileGroupManager.js
new file mode 100644
index 0000000000..44fc9702e2
--- /dev/null
+++ b/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/groupprovider/FileGroupManager.js
@@ -0,0 +1,251 @@
+/*
+ *
+ * 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/parser",
+ "dojo/query",
+ "dojo/dom-construct",
+ "dojo/_base/connect",
+ "dojo/_base/window",
+ "dojo/_base/event",
+ "dojo/_base/json",
+ "dijit/registry",
+ "qpid/common/util",
+ "qpid/common/properties",
+ "qpid/common/updater",
+ "qpid/common/UpdatableStore",
+ "dojox/grid/EnhancedGrid",
+ "dojox/grid/enhanced/plugins/Pagination",
+ "dojox/grid/enhanced/plugins/IndirectSelection",
+ "dojox/validate/us", "dojox/validate/web",
+ "dijit/Dialog",
+ "dijit/form/TextBox",
+ "dijit/form/ValidationTextBox",
+ "dijit/form/TimeTextBox", "dijit/form/Button",
+ "dijit/form/Form",
+ "dijit/form/DateTextBox",
+ "dojo/domReady!"],
+ function (xhr, dom, parser, query, construct, connect, win, event, json, registry, util, properties, updater, UpdatableStore, EnhancedGrid) {
+ function DatabaseGroupManager(containerNode, groupProviderObj, controller) {
+ var node = construct.create("div", null, containerNode, "last");
+ var that = this;
+ this.name = groupProviderObj.name;
+ xhr.get({url: "groupprovider/showFileGroupManager.html",
+ sync: true,
+ load: function(data) {
+ node.innerHTML = data;
+ parser.parse(node);
+
+
+ that.groupDatabaseUpdater= new GroupProviderUpdater(node, groupProviderObj, controller);
+
+ updater.add( that.groupDatabaseUpdater);
+
+ that.groupDatabaseUpdater.update();
+
+
+ }});
+ }
+
+ DatabaseGroupManager.prototype.update = function() {
+ this.groupDatabaseUpdater.update();
+ };
+
+ DatabaseGroupManager.prototype.close = function() {
+ updater.remove( this.groupDatabaseUpdater );
+ };
+
+ function GroupProviderUpdater(node, groupProviderObj, controller)
+ {
+ this.controller = controller;
+ this.query = "rest/groupprovider/"+encodeURIComponent(groupProviderObj.name);
+ this.name = groupProviderObj.name;
+ var that = this;
+
+ xhr.get({url: this.query, sync: properties.useSyncGet, handleAs: "json"})
+ .then(function(data) {
+ that.groupProviderData = data[0];
+
+ util.flattenStatistics( that.groupProviderData );
+
+ var groupDiv = query(".groups")[0];
+
+ var gridProperties = {
+ height: 400,
+ keepSelection: true,
+ plugins: {
+ pagination: {
+ pageSizes: ["10", "25", "50", "100"],
+ description: true,
+ sizeSwitch: true,
+ pageStepper: true,
+ gotoButton: true,
+ maxPageStep: 4,
+ position: "bottom"
+ },
+ indirectSelection: true
+
+ }};
+
+
+ that.groupsGrid =
+ new UpdatableStore(that.groupProviderData.groups, groupDiv,
+ [ { name: "Group Name", field: "name", width: "100%" }
+ ], null, gridProperties, EnhancedGrid);
+
+
+ var addGroupButton = query(".addGroupButton", node)[0];
+ connect.connect(registry.byNode(addGroupButton), "onClick", function(evt){ addGroup.show(groupProviderObj.name) });
+
+ var deleteMessagesButton = query(".deleteGroupButton", node)[0];
+ var deleteWidget = registry.byNode(deleteMessagesButton);
+ connect.connect(deleteWidget, "onClick",
+ function(evt){
+ event.stop(evt);
+ that.deleteGroups();
+ });
+ });
+ }
+
+ GroupProviderUpdater.prototype.deleteGroups = function()
+ {
+ var grid = this.groupsGrid.grid;
+ var data = grid.selection.getSelected();
+ if(data.length) {
+ var that = this;
+ if(confirm("Delete " + data.length + " groups?")) {
+ var i, queryParam;
+ for(i = 0; i<data.length; i++) {
+ if(queryParam) {
+ queryParam += "&";
+ } else {
+ queryParam = "?";
+ }
+
+ queryParam += "id=" + data[i].id;
+ }
+ var query = "rest/group/"+ encodeURIComponent(that.name)
+ + queryParam;
+ that.success = true
+ xhr.del({url: query, sync: true, handleAs: "json"}).then(
+ function(data) {
+ grid.setQuery({id: "*"});
+ grid.selection.deselectAll();
+ that.update();
+ },
+ function(error) {that.success = false; that.failureReason = error;});
+ if(!that.success ) {
+ alert("Error:" + this.failureReason);
+ }
+ }
+}
+ };
+
+ GroupProviderUpdater.prototype.update = function()
+ {
+
+ var that = this;
+
+ xhr.get({url: this.query, sync: properties.useSyncGet, handleAs: "json"})
+ .then(function(data) {
+ that.groupProviderData = data[0];
+ util.flattenStatistics( that.groupProviderData );
+
+ that.groupsGrid.update(that.groupProviderData.groups);
+
+ });
+
+
+ };
+
+ var addGroup = {};
+
+ var node = construct.create("div", null, win.body(), "last");
+
+ var convertToGroup = function convertToGroup(formValues) {
+ var newGroup = {};
+ newGroup.name = formValues.name;
+ for(var propName in formValues)
+ {
+ if(formValues.hasOwnProperty(propName)) {
+ if(formValues[ propName ] !== "") {
+ newGroup[ propName ] = formValues[propName];
+ }
+ }
+ }
+
+ return newGroup;
+ };
+
+
+ xhr.get({url: "groupprovider/addGroup.html",
+ sync: true,
+ load: function(data) {
+ var theForm;
+ node.innerHTML = data;
+ addGroup.dialogNode = dom.byId("addGroup");
+ parser.instantiate([addGroup.dialogNode]);
+
+ var that = this;
+
+ theForm = registry.byId("formAddGroup");
+ theForm.on("submit", function(e) {
+
+ event.stop(e);
+ if(theForm.validate()){
+
+ var newGroup = convertToGroup(theForm.getValues());
+
+
+ var url = "rest/group/"+encodeURIComponent(addGroup.groupProvider) +
+ "/"+encodeURIComponent(newGroup.name);
+
+ xhr.put({url: url, sync: true, handleAs: "json",
+ headers: { "Content-Type": "application/json"},
+ putData: json.toJson(newGroup),
+ load: function(x) {that.success = true; },
+ error: function(error) {that.success = false; that.failureReason = error;}});
+
+ if(that.success === true) {
+ registry.byId("addGroup").hide();
+ } else {
+ alert("Error:" + that.failureReason);
+ }
+
+ return false;
+
+
+ }else{
+ alert('Form contains invalid data. Please correct first');
+ return false;
+ }
+
+ });
+ }});
+
+ addGroup.show = function(groupProvider) {
+ addGroup.groupProvider = groupProvider;
+ registry.byId("formAddGroup").reset();
+ registry.byId("addGroup").show();
+ };
+
+ return DatabaseGroupManager;
+ });
diff --git a/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/treeView.js b/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/treeView.js
index b1d4abf8c1..59356cfce1 100644
--- a/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/treeView.js
+++ b/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/treeView.js
@@ -273,10 +273,12 @@ define(["dojo/_base/xhr",
controller.show("port", details.port, { type: "virtualhost", name: details.virtualhost, parent: {broker: {type:"broker", name:""}}});
} else if (details.type == 'authenticationprovider') {
controller.show("authenticationprovider", details.authenticationprovider, {broker: {type:"broker", name:""}});
+ } else if (details.type == 'groupprovider') {
+ controller.show("groupprovider", details.groupprovider, {broker: {type:"broker", name:""}});
+ } else if (details.type == 'group') {
+ controller.show("group", details.group, { type: "groupprovider", name: details.groupprovider, parent: {broker: {type:"broker", name:""}}});
}
-
-
};
TreeViewModel.prototype.update = function () {
diff --git a/java/broker-plugins/management-http/src/main/java/resources/showGroupProvider.html b/java/broker-plugins/management-http/src/main/java/resources/showGroupProvider.html
new file mode 100644
index 0000000000..914857db5c
--- /dev/null
+++ b/java/broker-plugins/management-http/src/main/java/resources/showGroupProvider.html
@@ -0,0 +1,25 @@
+<!--
+ -
+ - 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="groupProvider">
+ <span style="">Name:</span><span class="name" style="position:absolute; left:6em"></span>
+ <br/>
+ <span style="">Type:</span><span class="type" style="position:absolute; left:6em"></span>
+</div> \ No newline at end of file
diff --git a/java/broker-plugins/management-http/src/main/resources/META-INF/services/org.apache.qpid.server.plugin.PluginFactory b/java/broker-plugins/management-http/src/main/resources/META-INF/services/org.apache.qpid.server.plugin.PluginFactory
new file mode 100644
index 0000000000..7ffb9a9013
--- /dev/null
+++ b/java/broker-plugins/management-http/src/main/resources/META-INF/services/org.apache.qpid.server.plugin.PluginFactory
@@ -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.
+#
+org.apache.qpid.server.management.plugin.HttpManagementFactory
diff --git a/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/HttpManagementFactoryTest.java b/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/HttpManagementFactoryTest.java
new file mode 100644
index 0000000000..bb4c46826c
--- /dev/null
+++ b/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/HttpManagementFactoryTest.java
@@ -0,0 +1,61 @@
+/*
+ * 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.management.plugin;
+
+import static org.mockito.Mockito.mock;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.plugin.PluginFactory;
+import org.apache.qpid.test.utils.QpidTestCase;
+
+public class HttpManagementFactoryTest extends QpidTestCase
+{
+ private static final int SESSION_TIMEOUT = 3600;
+
+ private PluginFactory _pluginFactory = new HttpManagementFactory();
+ private Map<String, Object> _attributes = new HashMap<String, Object>();
+ private Broker _broker = mock(Broker.class);
+ private UUID _id = UUID.randomUUID();
+
+ public void testCreateInstanceReturnsNullWhenPluginTypeMissing() throws Exception
+ {
+ assertNull(_pluginFactory.createInstance(_id, _attributes, _broker));
+ }
+ public void testCreateInstanceReturnsNullWhenPluginTypeNotHttp()
+ {
+ _attributes.put(PluginFactory.PLUGIN_TYPE, "notHttp");
+ assertNull(_pluginFactory.createInstance(_id, _attributes, _broker));
+ }
+
+ public void testCreateInstance() throws Exception
+ {
+ _attributes.put(PluginFactory.PLUGIN_TYPE, HttpManagement.PLUGIN_TYPE);
+ _attributes.put(HttpManagement.TIME_OUT, SESSION_TIMEOUT);
+
+ HttpManagement management = (HttpManagement) _pluginFactory.createInstance(_id, _attributes, _broker);
+
+ assertEquals(_broker, management.getBroker());
+ assertEquals(SESSION_TIMEOUT, management.getSessionTimeout());
+ }
+
+}
diff --git a/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/Asserts.java b/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/Asserts.java
deleted file mode 100644
index 2595007574..0000000000
--- a/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/Asserts.java
+++ /dev/null
@@ -1,249 +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.management.plugin.servlet.rest;
-
-import static junit.framework.Assert.assertEquals;
-import static junit.framework.Assert.assertNotNull;
-
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Map;
-
-import javax.jms.JMSException;
-
-import org.apache.qpid.client.AMQConnection;
-import org.apache.qpid.server.model.Binding;
-import org.apache.qpid.server.model.Broker;
-import org.apache.qpid.server.model.Connection;
-import org.apache.qpid.server.model.Exchange;
-import org.apache.qpid.server.model.LifetimePolicy;
-import org.apache.qpid.server.model.Port;
-import org.apache.qpid.server.model.Queue;
-import org.apache.qpid.server.model.State;
-import org.apache.qpid.server.model.VirtualHost;
-
-public class Asserts
-{
- public static final String STATISTICS_ATTRIBUTE = "statistics";
-
- public static void assertVirtualHost(String virtualHostName, Map<String, Object> virtualHost)
- {
- assertNotNull("Virtualhost " + virtualHostName + " data are not found", virtualHost);
- assertAttributesPresent(virtualHost, VirtualHost.AVAILABLE_ATTRIBUTES, VirtualHost.TIME_TO_LIVE,
- VirtualHost.CREATED, VirtualHost.UPDATED, VirtualHost.SUPPORTED_QUEUE_TYPES, VirtualHost.STORE_CONFIGURATION);
-
- assertEquals("Unexpected value of attribute " + VirtualHost.NAME, virtualHostName, virtualHost.get(VirtualHost.NAME));
- assertNotNull("Unexpected value of attribute " + VirtualHost.ID, virtualHost.get(VirtualHost.ID));
- assertEquals("Unexpected value of attribute " + VirtualHost.STATE, State.ACTIVE.name(),
- virtualHost.get(VirtualHost.STATE));
- assertEquals("Unexpected value of attribute " + VirtualHost.DURABLE, Boolean.TRUE,
- virtualHost.get(VirtualHost.DURABLE));
- assertEquals("Unexpected value of attribute " + VirtualHost.LIFETIME_POLICY, LifetimePolicy.PERMANENT.name(),
- virtualHost.get(VirtualHost.LIFETIME_POLICY));
- assertEquals("Unexpected value of attribute " + VirtualHost.DEAD_LETTER_QUEUE_ENABLED, Boolean.FALSE,
- virtualHost.get(VirtualHost.DEAD_LETTER_QUEUE_ENABLED));
-
- @SuppressWarnings("unchecked")
- Collection<String> exchangeTypes = (Collection<String>) virtualHost.get(VirtualHost.SUPPORTED_EXCHANGE_TYPES);
- assertEquals("Unexpected value of attribute " + VirtualHost.SUPPORTED_EXCHANGE_TYPES,
- new HashSet<String>(Arrays.asList("headers", "topic", "direct", "fanout", "management")),
- new HashSet<String>(exchangeTypes));
-
- @SuppressWarnings("unchecked")
- Map<String, Object> statistics = (Map<String, Object>) virtualHost.get(STATISTICS_ATTRIBUTE);
- Asserts.assertAttributesPresent(statistics, VirtualHost.AVAILABLE_STATISTICS, VirtualHost.BYTES_RETAINED,
- VirtualHost.LOCAL_TRANSACTION_BEGINS, VirtualHost.LOCAL_TRANSACTION_ROLLBACKS,
- VirtualHost.MESSAGES_RETAINED, VirtualHost.STATE_CHANGED, VirtualHost.XA_TRANSACTION_BRANCH_ENDS,
- VirtualHost.XA_TRANSACTION_BRANCH_STARTS, VirtualHost.XA_TRANSACTION_BRANCH_SUSPENDS);
-
- }
-
- public static void assertQueue(String queueName, String queueType, Map<String, Object> queueData)
- {
- assertQueue(queueName, queueType, queueData, null);
- }
-
- public static void assertQueue(String queueName, String queueType, Map<String, Object> queueData, Map<String, Object> expectedAttributes)
- {
- assertNotNull("Queue " + queueName + " is not found!", queueData);
- Asserts.assertAttributesPresent(queueData, Queue.AVAILABLE_ATTRIBUTES, Queue.CREATED, Queue.UPDATED,
- Queue.DESCRIPTION, Queue.TIME_TO_LIVE, Queue.ALTERNATE_EXCHANGE, Queue.OWNER, Queue.NO_LOCAL, Queue.LVQ_KEY,
- Queue.SORT_KEY, Queue.MESSAGE_GROUP_KEY, Queue.MESSAGE_GROUP_DEFAULT_GROUP,
- Queue.MESSAGE_GROUP_SHARED_GROUPS, Queue.PRIORITIES);
-
- assertEquals("Unexpected value of queue attribute " + Queue.NAME, queueName, queueData.get(Queue.NAME));
- assertNotNull("Unexpected value of queue attribute " + Queue.ID, queueData.get(Queue.ID));
- assertEquals("Unexpected value of queue attribute " + Queue.STATE, State.ACTIVE.name(), queueData.get(Queue.STATE));
- assertEquals("Unexpected value of queue attribute " + Queue.LIFETIME_POLICY, LifetimePolicy.PERMANENT.name(),
- queueData.get(Queue.LIFETIME_POLICY));
- assertEquals("Unexpected value of queue attribute " + Queue.TYPE, queueType, queueData.get(Queue.TYPE));
- if (expectedAttributes == null)
- {
- assertEquals("Unexpected value of queue attribute " + Queue.EXCLUSIVE, Boolean.FALSE, queueData.get(Queue.EXCLUSIVE));
- assertEquals("Unexpected value of queue attribute " + Queue.MAXIMUM_DELIVERY_ATTEMPTS, 0,
- queueData.get(Queue.MAXIMUM_DELIVERY_ATTEMPTS));
- assertEquals("Unexpected value of queue attribute " + Queue.QUEUE_FLOW_CONTROL_SIZE_BYTES, 0,
- queueData.get(Queue.QUEUE_FLOW_CONTROL_SIZE_BYTES));
- assertEquals("Unexpected value of queue attribute " + Queue.QUEUE_FLOW_RESUME_SIZE_BYTES, 0,
- queueData.get(Queue.QUEUE_FLOW_RESUME_SIZE_BYTES));
- assertEquals("Unexpected value of queue attribute " + Queue.QUEUE_FLOW_STOPPED, Boolean.FALSE,
- queueData.get(Queue.QUEUE_FLOW_STOPPED));
- }
- else
- {
- for (Map.Entry<String, Object> attribute : expectedAttributes.entrySet())
- {
- assertEquals("Unexpected value of " + queueName + " queue attribute " + attribute.getKey(),
- attribute.getValue(), queueData.get(attribute.getKey()));
- }
- }
-
- assertNotNull("Unexpected value of queue attribute statistics", queueData.get(Asserts.STATISTICS_ATTRIBUTE));
- @SuppressWarnings("unchecked")
- Map<String, Object> statistics = (Map<String, Object>) queueData.get(Asserts.STATISTICS_ATTRIBUTE);
- Asserts.assertAttributesPresent(statistics, Queue.AVAILABLE_STATISTICS, Queue.DISCARDS_TTL_BYTES,
- Queue.DISCARDS_TTL_MESSAGES, Queue.STATE_CHANGED);
- }
-
- public static void assertAttributesPresent(Map<String, Object> data, String[] attributes)
- {
- for (String name : attributes)
- {
- assertNotNull("Attribute " + name + " is not present", data.get(name));
- }
- }
-
- public static void assertAttributesPresent(Map<String, Object> data, Collection<String> attributes,
- String... unsupportedAttributes)
- {
- for (String name : attributes)
- {
- boolean unsupported = false;
- for (String unsupportedAttribute : unsupportedAttributes)
- {
- if (unsupportedAttribute.equals(name))
- {
- unsupported = true;
- break;
- }
- }
- if (unsupported)
- {
- continue;
- }
- assertNotNull("Attribute " + name + " is not present", data.get(name));
- }
- }
-
- public static void assertConnection(Map<String, Object> connectionData, AMQConnection connection) throws JMSException
- {
- assertNotNull("Unexpected connection data", connectionData);
- assertAttributesPresent(connectionData, Connection.AVAILABLE_ATTRIBUTES, Connection.STATE, Connection.DURABLE,
- Connection.LIFETIME_POLICY, Connection.TIME_TO_LIVE, Connection.CREATED, Connection.UPDATED,
- Connection.INCOMING, Connection.REMOTE_PROCESS_NAME, Connection.REMOTE_PROCESS_PID,
- Connection.LOCAL_ADDRESS, Connection.PROPERTIES);
-
- assertEquals("Unexpected value of connection attribute " + Connection.SESSION_COUNT_LIMIT,
- (int) connection.getMaximumChannelCount(), connectionData.get(Connection.SESSION_COUNT_LIMIT));
- assertEquals("Unexpected value of connection attribute " + Connection.CLIENT_ID, "clientid",
- connectionData.get(Connection.CLIENT_ID));
- assertEquals("Unexpected value of connection attribute " + Connection.PRINCIPAL, "guest",
- connectionData.get(Connection.PRINCIPAL));
-
- @SuppressWarnings("unchecked")
- Map<String, Object> statistics = (Map<String, Object>) connectionData.get(STATISTICS_ATTRIBUTE);
- assertAttributesPresent(statistics, Connection.AVAILABLE_STATISTICS, Connection.LOCAL_TRANSACTION_BEGINS,
- Connection.LOCAL_TRANSACTION_ROLLBACKS, Connection.STATE_CHANGED, Connection.XA_TRANSACTION_BRANCH_ENDS,
- Connection.XA_TRANSACTION_BRANCH_STARTS, Connection.XA_TRANSACTION_BRANCH_SUSPENDS);
- assertEquals("Unexpected value of connection statistics attribute " + Connection.SESSION_COUNT, 1,
- statistics.get(Connection.SESSION_COUNT));
- }
-
- public static void assertPortAttributes(Map<String, Object> port)
- {
- assertAttributesPresent(port, Port.AVAILABLE_ATTRIBUTES, Port.CREATED, Port.UPDATED);
-
- assertNotNull("Unexpected value of attribute " + Port.ID, port.get(Port.ID));
- assertEquals("Unexpected value of attribute " + Port.DURABLE, Boolean.FALSE, port.get(Port.DURABLE));
- assertEquals("Unexpected value of attribute " + Port.LIFETIME_POLICY, LifetimePolicy.PERMANENT.name(),
- port.get(Broker.LIFETIME_POLICY));
- assertEquals("Unexpected value of attribute " + Port.STATE, State.ACTIVE.name(), port.get(Port.STATE));
- assertEquals("Unexpected value of attribute " + Port.TIME_TO_LIVE, 0, port.get(Port.TIME_TO_LIVE));
- assertNotNull("Unexpected value of attribute " + Port.BINDING_ADDRESS, port.get(Port.BINDING_ADDRESS));
- assertNotNull("Unexpected value of attribute " + Port.PROTOCOLS, port.get(Port.PROTOCOLS));
- assertNotNull("Unexpected value of attribute " + Port.NAME, port.get(Port.NAME));
-
- @SuppressWarnings("unchecked")
- Collection<String> transports = (Collection<String>) port.get(Port.TRANSPORTS);
- assertEquals("Unexpected value of attribute " + Port.TRANSPORTS, new HashSet<String>(Arrays.asList("TCP")),
- new HashSet<String>(transports));
- }
-
- public static void assertDurableExchange(String exchangeName, String type, Map<String, Object> exchangeData)
- {
- assertExchange(exchangeName, type, exchangeData);
-
- assertEquals("Unexpected value of exchange attribute " + Exchange.DURABLE, Boolean.TRUE,
- exchangeData.get(Exchange.DURABLE));
- }
-
- public static void assertExchange(String exchangeName, String type, Map<String, Object> exchangeData)
- {
- assertNotNull("Exchange " + exchangeName + " is not found!", exchangeData);
- assertAttributesPresent(exchangeData, Exchange.AVAILABLE_ATTRIBUTES, Exchange.CREATED, Exchange.UPDATED,
- Exchange.ALTERNATE_EXCHANGE, Exchange.TIME_TO_LIVE);
-
- assertEquals("Unexpected value of exchange attribute " + Exchange.NAME, exchangeName,
- exchangeData.get(Exchange.NAME));
- assertNotNull("Unexpected value of exchange attribute " + Exchange.ID, exchangeData.get(VirtualHost.ID));
- assertEquals("Unexpected value of exchange attribute " + Exchange.STATE, State.ACTIVE.name(),
- exchangeData.get(Exchange.STATE));
-
- assertEquals("Unexpected value of exchange attribute " + Exchange.LIFETIME_POLICY, LifetimePolicy.PERMANENT.name(),
- exchangeData.get(Exchange.LIFETIME_POLICY));
- assertEquals("Unexpected value of exchange attribute " + Exchange.TYPE, type, exchangeData.get(Exchange.TYPE));
- assertNotNull("Unexpected value of exchange attribute statistics", exchangeData.get(STATISTICS_ATTRIBUTE));
-
- @SuppressWarnings("unchecked")
- Map<String, Object> statistics = (Map<String, Object>) exchangeData.get(STATISTICS_ATTRIBUTE);
- assertAttributesPresent(statistics, Exchange.AVAILABLE_STATISTICS, Exchange.STATE_CHANGED, Exchange.PRODUCER_COUNT);
- }
-
- public static void assertBinding(String bindingName, String queueName, String exchange, Map<String, Object> binding)
- {
- assertNotNull("Binding map should not be null", binding);
- assertAttributesPresent(binding, Binding.AVAILABLE_ATTRIBUTES, Binding.STATE, Binding.TIME_TO_LIVE,
- Binding.CREATED, Binding.UPDATED);
-
- assertEquals("Unexpected binding attribute " + Binding.NAME, bindingName, binding.get(Binding.NAME));
- assertEquals("Unexpected binding attribute " + Binding.QUEUE, queueName, binding.get(Binding.QUEUE));
- assertEquals("Unexpected binding attribute " + Binding.EXCHANGE, exchange, binding.get(Binding.EXCHANGE));
- assertEquals("Unexpected binding attribute " + Binding.LIFETIME_POLICY, LifetimePolicy.PERMANENT.name(),
- binding.get(Binding.LIFETIME_POLICY));
- }
-
- public static void assertBinding(String queueName, String exchange, Map<String, Object> binding)
- {
- assertBinding(queueName, queueName, exchange, binding);
- }
-
-}
diff --git a/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/AuthenticationProviderRestTest.java b/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/AuthenticationProviderRestTest.java
deleted file mode 100644
index 5e6d9a998a..0000000000
--- a/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/AuthenticationProviderRestTest.java
+++ /dev/null
@@ -1,73 +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.management.plugin.servlet.rest;
-
-import java.util.List;
-import java.util.Map;
-
-import org.apache.qpid.server.model.AuthenticationProvider;
-import org.apache.qpid.server.model.LifetimePolicy;
-import org.apache.qpid.server.model.State;
-import org.apache.qpid.server.model.User;
-
-public class AuthenticationProviderRestTest extends QpidRestTestCase
-{
-
- public void testGet() throws Exception
- {
- List<Map<String, Object>> providerDetails = getJsonAsList("/rest/authenticationprovider");
- assertNotNull("Providers details cannot be null", providerDetails);
- assertEquals("Unexpected number of providers", 1, providerDetails.size());
- for (Map<String, Object> provider : providerDetails)
- {
- assertProvider("PrincipalDatabaseAuthenticationManager", provider);
- Map<String, Object> data = getJsonAsSingletonList("/rest/authenticationprovider/"
- + provider.get(AuthenticationProvider.NAME));
- assertNotNull("Cannot load data for " + provider.get(AuthenticationProvider.NAME), data);
- assertProvider("PrincipalDatabaseAuthenticationManager", data);
- }
- }
-
- private void assertProvider(String type, Map<String, Object> provider)
- {
- Asserts.assertAttributesPresent(provider, AuthenticationProvider.AVAILABLE_ATTRIBUTES,
- AuthenticationProvider.CREATED, AuthenticationProvider.UPDATED, AuthenticationProvider.DESCRIPTION,
- AuthenticationProvider.TIME_TO_LIVE);
- assertEquals("Unexpected value of provider attribute " + AuthenticationProvider.STATE, State.ACTIVE.name(),
- provider.get(AuthenticationProvider.STATE));
- assertEquals("Unexpected value of provider attribute " + AuthenticationProvider.LIFETIME_POLICY,
- LifetimePolicy.PERMANENT.name(), provider.get(AuthenticationProvider.LIFETIME_POLICY));
- assertEquals("Unexpected value of provider attribute " + AuthenticationProvider.DURABLE, Boolean.TRUE,
- provider.get(AuthenticationProvider.DURABLE));
- assertEquals("Unexpected value of provider attribute " + AuthenticationProvider.TYPE, type,
- provider.get(AuthenticationProvider.TYPE));
-
- @SuppressWarnings("unchecked")
- List<Map<String, Object>> users = (List<Map<String, Object>>) provider.get("users");
- assertNotNull("Users are not found", users);
- assertTrue("Unexpected number of users", users.size() > 1);
- for (Map<String, Object> user : users)
- {
- assertNotNull("Attribute " + User.ID, user.get(User.ID));
- assertNotNull("Attribute " + User.NAME, user.get(User.NAME));
- }
- }
-}
diff --git a/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/BindingRestTest.java b/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/BindingRestTest.java
deleted file mode 100644
index 1ed0d97185..0000000000
--- a/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/BindingRestTest.java
+++ /dev/null
@@ -1,129 +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.management.plugin.servlet.rest;
-
-import java.net.HttpURLConnection;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.qpid.server.model.Binding;
-
-public class BindingRestTest extends QpidRestTestCase
-{
-
- public void testGetAllBindings() throws Exception
- {
- List<Map<String, Object>> bindings = getJsonAsList("/rest/binding");
- assertNotNull("Bindings cannot be null", bindings);
- assertTrue("Unexpected number of bindings", bindings.size() >= EXPECTED_HOSTS.length * EXPECTED_QUEUES.length);
- for (Map<String, Object> binding : bindings)
- {
- Asserts.assertBinding((String) binding.get(Binding.NAME), (String) binding.get(Binding.EXCHANGE), binding);
- }
- }
-
- public void testGetVirtualHostBindings() throws Exception
- {
- List<Map<String, Object>> bindings = getJsonAsList("/rest/binding/test");
- assertNotNull("Bindings cannot be null", bindings);
- assertEquals("Unexpected number of bindings", EXPECTED_QUEUES.length * 2, bindings.size());
- for (String queueName : EXPECTED_QUEUES)
- {
- Map<String, Object> searchAttributes = new HashMap<String, Object>();
- searchAttributes.put(Binding.NAME, queueName);
- searchAttributes.put(Binding.EXCHANGE, "amq.direct");
-
- Map<String, Object> binding = find(searchAttributes, bindings);
- Asserts.assertBinding(queueName, "amq.direct", binding);
-
- searchAttributes.put(Binding.EXCHANGE, "<<default>>");
-
- binding = find(searchAttributes, bindings);
- Asserts.assertBinding(queueName, "<<default>>", binding);
- }
- }
-
- public void testGetVirtualHostExchangeBindings() throws Exception
- {
- List<Map<String, Object>> bindings = getJsonAsList("/rest/binding/test/amq.direct");
- assertNotNull("Bindings cannot be null", bindings);
- assertEquals("Unexpected number of bindings", EXPECTED_QUEUES.length, bindings.size());
- for (String queueName : EXPECTED_QUEUES)
- {
- Map<String, Object> binding = find(Binding.NAME, queueName, bindings);
- Asserts.assertBinding(queueName, "amq.direct", binding);
- }
- }
-
- public void testGetVirtualHostExchangeQueueBindings() throws Exception
- {
- List<Map<String, Object>> bindings = getJsonAsList("/rest/binding/test/amq.direct/queue");
- assertNotNull("Bindings cannot be null", bindings);
- assertEquals("Unexpected number of bindings", 1, bindings.size());
- 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/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/BrokerRestHttpsTest.java b/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/BrokerRestHttpsTest.java
deleted file mode 100644
index 4bbe9155cd..0000000000
--- a/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/BrokerRestHttpsTest.java
+++ /dev/null
@@ -1,86 +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.management.plugin.servlet.rest;
-
-import java.io.IOException;
-import java.net.HttpURLConnection;
-import java.net.URL;
-import java.util.Map;
-
-import javax.net.ssl.HttpsURLConnection;
-import javax.net.ssl.SSLSocketFactory;
-
-import org.apache.commons.configuration.ConfigurationException;
-import org.apache.qpid.server.model.Broker;
-
-public class BrokerRestHttpsTest extends QpidRestTestCase
-{
- private static final String TRUSTSTORE = "test-profiles/test_resources/ssl/java_client_truststore.jks";
- private static final String TRUSTSTORE_PASSWORD = "password";
-
- @Override
- public void setUp() throws Exception
- {
- setSystemProperty("javax.net.debug", "ssl");
- super.setUp();
- setSystemProperty("javax.net.ssl.trustStore", TRUSTSTORE);
- setSystemProperty("javax.net.ssl.trustStorePassword", TRUSTSTORE_PASSWORD);
- }
-
- @Override
- protected void customizeConfiguration() throws ConfigurationException, IOException
- {
- setConfigurationProperty("management.enabled", "true");
- setConfigurationProperty("management.http.enabled", "false");
- setConfigurationProperty("management.https.enabled", "true");
- setConfigurationProperty("management.https.port", Integer.toString(getHttpPort()));
- }
-
- @Override
- protected String getHostName()
- {
- return "localhost";
- }
-
- @Override
- protected String getProtocol()
- {
- return "https";
- }
-
- @Override
- protected HttpURLConnection openManagementConection(String path) throws IOException
- {
- URL url = getManagementURL(path);
- HttpURLConnection httpCon = (HttpURLConnection) url.openConnection();
- ((HttpsURLConnection) httpCon).setSSLSocketFactory((SSLSocketFactory) SSLSocketFactory.getDefault());
- httpCon.setDoOutput(true);
- return httpCon;
- }
-
- public void testGetWithHttps() throws Exception
- {
- Map<String, Object> brokerDetails = getJsonAsSingletonList("/rest/broker");
-
- Asserts.assertAttributesPresent(brokerDetails, Broker.AVAILABLE_ATTRIBUTES, Broker.BYTES_RETAINED,
- Broker.PROCESS_PID, Broker.SUPPORTED_STORE_TYPES, Broker.CREATED, Broker.TIME_TO_LIVE, Broker.UPDATED);
- }
-}
diff --git a/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/BrokerRestTest.java b/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/BrokerRestTest.java
deleted file mode 100644
index f2970e2ba9..0000000000
--- a/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/BrokerRestTest.java
+++ /dev/null
@@ -1,118 +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.management.plugin.servlet.rest;
-
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.qpid.common.QpidProperties;
-import org.apache.qpid.server.model.Broker;
-import org.apache.qpid.server.model.LifetimePolicy;
-import org.apache.qpid.server.model.Port;
-import org.apache.qpid.server.model.State;
-import org.apache.qpid.server.model.VirtualHost;
-
-public class BrokerRestTest extends QpidRestTestCase
-{
-
- private static final String BROKER_AUTHENTICATIONPROVIDERS_ATTRIBUTE = "authenticationproviders";
- private static final String BROKER_PORTS_ATTRIBUTE = "ports";
- private static final String BROKER_VIRTUALHOSTS_ATTRIBUTE = "virtualhosts";
- private static final String BROKER_STATISTICS_ATTRIBUTE = "statistics";
-
- public void testGet() throws Exception
- {
- Map<String, Object> brokerDetails = getJsonAsSingletonList("/rest/broker");
-
- assertBrokerAttributes(brokerDetails);
-
- @SuppressWarnings("unchecked")
- Map<String, Object> statistics = (Map<String, Object>) brokerDetails.get(BROKER_STATISTICS_ATTRIBUTE);
- Asserts.assertAttributesPresent(statistics, new String[]{ "bytesIn", "messagesOut", "bytesOut", "messagesIn" });
-
- @SuppressWarnings("unchecked")
- List<Map<String, Object>> virtualhosts = (List<Map<String, Object>>) brokerDetails.get(BROKER_VIRTUALHOSTS_ATTRIBUTE);
- assertEquals("Unexpected number of virtual hosts", 3, virtualhosts.size());
-
- Asserts.assertVirtualHost("development", find(VirtualHost.NAME, "development", virtualhosts));
- Asserts.assertVirtualHost("localhost", find(VirtualHost.NAME, "localhost", virtualhosts));
- Asserts.assertVirtualHost("test", find(VirtualHost.NAME, "test", virtualhosts));
-
- @SuppressWarnings("unchecked")
- List<Map<String, Object>> ports = (List<Map<String, Object>>) brokerDetails.get(BROKER_PORTS_ATTRIBUTE);
- assertEquals("Unexpected number of ports", 2, ports.size());
-
- for (Map<String, Object> port : ports)
- {
- Asserts.assertPortAttributes(port);
- }
-
- String bindingAddress = (String)ports.get(0).get(Port.BINDING_ADDRESS);
-
- Map<String, Object> amqpPort = find(Port.NAME, bindingAddress + ":" + getPort(), ports);
- Map<String, Object> httpPort = find(Port.NAME, bindingAddress + ":" + getHttpPort(), ports);
-
- assertNotNull("Cannot find AMQP port", amqpPort);
- assertNotNull("Cannot find HTTP port", httpPort);
-
- @SuppressWarnings("unchecked")
- Collection<String> port1Protocols = (Collection<String>) amqpPort.get(Port.PROTOCOLS);
- assertFalse("AMQP protocol list cannot contain HTTP", port1Protocols.contains("HTTP"));
-
- @SuppressWarnings("unchecked")
- Collection<String> port2Protocols = (Collection<String>) httpPort.get(Port.PROTOCOLS);
- assertEquals("Unexpected value of attribute " + Port.PROTOCOLS, new HashSet<String>(Arrays.asList("HTTP")),
- new HashSet<String>(port2Protocols));
- }
-
- protected void assertBrokerAttributes(Map<String, Object> brokerDetails)
- {
- Asserts.assertAttributesPresent(brokerDetails, Broker.AVAILABLE_ATTRIBUTES,
- Broker.BYTES_RETAINED, Broker.PROCESS_PID, Broker.SUPPORTED_STORE_TYPES,
- Broker.CREATED, Broker.TIME_TO_LIVE, Broker.UPDATED);
-
- assertEquals("Unexpected value of attribute " + Broker.BUILD_VERSION, QpidProperties.getBuildVersion(),
- brokerDetails.get(Broker.BUILD_VERSION));
- assertEquals("Unexpected value of attribute " + Broker.OPERATING_SYSTEM, System.getProperty("os.name") + " "
- + System.getProperty("os.version") + " " + System.getProperty("os.arch"),
- brokerDetails.get(Broker.OPERATING_SYSTEM));
- assertEquals(
- "Unexpected value of attribute " + Broker.PLATFORM,
- System.getProperty("java.vendor") + " "
- + System.getProperty("java.runtime.version", System.getProperty("java.version")),
- brokerDetails.get(Broker.PLATFORM));
- assertEquals("Unexpected value of attribute " + Broker.DURABLE, Boolean.TRUE, brokerDetails.get(Broker.DURABLE));
- assertEquals("Unexpected value of attribute " + Broker.LIFETIME_POLICY, LifetimePolicy.PERMANENT.name(),
- brokerDetails.get(Broker.LIFETIME_POLICY));
- assertEquals("Unexpected value of attribute " + Broker.NAME, "Broker", brokerDetails.get(Broker.NAME));
- assertEquals("Unexpected value of attribute " + Broker.STATE, State.ACTIVE.name(), brokerDetails.get(Broker.STATE));
-
- assertNotNull("Unexpected value of attribute " + Broker.ID, brokerDetails.get(Broker.ID));
- assertNotNull("Unexpected value of attribute statistics", brokerDetails.get(BROKER_STATISTICS_ATTRIBUTE));
- assertNotNull("Unexpected value of attribute virtualhosts", brokerDetails.get(BROKER_VIRTUALHOSTS_ATTRIBUTE));
- assertNotNull("Unexpected value of attribute ports", brokerDetails.get(BROKER_PORTS_ATTRIBUTE));
- assertNotNull("Unexpected value of attribute authenticationproviders", brokerDetails.get(BROKER_AUTHENTICATIONPROVIDERS_ATTRIBUTE));
- }
-
-}
diff --git a/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/ConnectionRestTest.java b/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/ConnectionRestTest.java
deleted file mode 100644
index 3661b94a7c..0000000000
--- a/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/ConnectionRestTest.java
+++ /dev/null
@@ -1,213 +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.management.plugin.servlet.rest;
-
-import java.io.IOException;
-import java.net.URLDecoder;
-import java.util.List;
-import java.util.Map;
-
-import javax.jms.Destination;
-import javax.jms.JMSException;
-import javax.jms.Message;
-import javax.jms.MessageConsumer;
-import javax.jms.MessageProducer;
-
-import org.apache.qpid.client.AMQConnection;
-import org.apache.qpid.client.AMQSession;
-import org.apache.qpid.server.model.Connection;
-import org.apache.qpid.server.model.Session;
-
-public class ConnectionRestTest extends QpidRestTestCase
-{
- /**
- * Message number to publish into queue
- */
- private static final int MESSAGE_NUMBER = 5;
- private static final int MESSAGE_SIZE = 6;
-
- private static final String SESSIONS_ATTRIBUTE = "sessions";
-
- private javax.jms.Connection _connection;
- private javax.jms.Session _session;
-
- public void setUp() throws Exception
- {
- super.setUp();
-
- _connection = getConnection();
- _session = _connection.createSession(true, javax.jms.Session.SESSION_TRANSACTED);
- String queueName = getTestQueueName();
- Destination queue = _session.createQueue(queueName);
- MessageConsumer consumer = _session.createConsumer(queue);
- MessageProducer producer = _session.createProducer(queue);
- _connection.start();
-
- // send messages
- for (int i = 0; i < MESSAGE_NUMBER; i++)
- {
- producer.send(_session.createTextMessage("Test-" + i));
- }
- _session.commit();
-
- Message m = consumer.receive(1000l);
- assertNotNull("Message was not received", m);
- _session.commit();
-
- // receive the rest of messages for rollback
- for (int i = 0; i < MESSAGE_NUMBER - 1; i++)
- {
- m = consumer.receive(1000l);
- assertNotNull("Message was not received", m);
- }
- _session.rollback();
-
- // receive them again
- for (int i = 0; i < MESSAGE_NUMBER - 1; i++)
- {
- m = consumer.receive(1000l);
- assertNotNull("Message was not received", m);
- }
- }
-
- public void testGetAllConnections() throws Exception
- {
- List<Map<String, Object>> connections = getJsonAsList("/rest/connection");
- assertEquals("Unexpected number of connections", 1, connections.size());
- Asserts.assertConnection(connections.get(0), (AMQConnection) _connection);
- }
-
- public void testGetVirtualHostConnections() throws Exception
- {
- List<Map<String, Object>> connections = getJsonAsList("/rest/connection/test");
- assertEquals("Unexpected number of connections", 1, connections.size());
- Asserts.assertConnection(connections.get(0), (AMQConnection) _connection);
- }
-
- public void testGetConnectionByName() throws Exception
- {
- // get connection name
- String connectionName = getConnectionName();
-
- Map<String, Object> connectionDetails = getJsonAsSingletonList("/rest/connection/test/"
- + URLDecoder.decode(connectionName, "UTF-8"));
- assertConnection(connectionDetails);
- }
-
- public void testGetAllSessions() throws Exception
- {
- List<Map<String, Object>> sessions = getJsonAsList("/rest/session");
- assertEquals("Unexpected number of sessions", 1, sessions.size());
- assertSession(sessions.get(0), (AMQSession<?, ?>) _session);
- }
-
- public void testGetVirtualHostSessions() throws Exception
- {
- List<Map<String, Object>> sessions = getJsonAsList("/rest/session/test");
- assertEquals("Unexpected number of sessions", 1, sessions.size());
- assertSession(sessions.get(0), (AMQSession<?, ?>) _session);
- }
-
- public void testGetConnectionSessions() throws Exception
- {
- // get connection name
- String connectionName = getConnectionName();
-
- List<Map<String, Object>> sessions = getJsonAsList("/rest/session/test/"
- + URLDecoder.decode(connectionName, "UTF-8"));
- assertEquals("Unexpected number of sessions", 1, sessions.size());
- assertSession(sessions.get(0), (AMQSession<?, ?>) _session);
- }
-
- public void testGetSessionByName() throws Exception
- {
- // get connection name
- String connectionName = getConnectionName();
-
- List<Map<String, Object>> sessions = getJsonAsList("/rest/session/test/"
- + URLDecoder.decode(connectionName, "UTF-8") + "/" + ((AMQSession<?, ?>) _session).getChannelId());
- assertEquals("Unexpected number of sessions", 1, sessions.size());
- assertSession(sessions.get(0), (AMQSession<?, ?>) _session);
- }
-
- private void assertConnection(Map<String, Object> connectionDetails) throws JMSException
- {
- Asserts.assertConnection(connectionDetails, (AMQConnection) _connection);
-
- @SuppressWarnings("unchecked")
- Map<String, Object> statistics = (Map<String, Object>) connectionDetails.get(Asserts.STATISTICS_ATTRIBUTE);
- assertEquals("Unexpected value of connection statistics attribute " + Connection.BYTES_IN, MESSAGE_NUMBER
- * MESSAGE_SIZE, statistics.get(Connection.BYTES_IN));
- assertEquals("Unexpected value of connection statistics attribute " + Connection.BYTES_OUT, MESSAGE_SIZE
- + ((MESSAGE_NUMBER - 1) * MESSAGE_SIZE) * 2, statistics.get(Connection.BYTES_OUT));
- assertEquals("Unexpected value of connection statistics attribute " + Connection.MESSAGES_IN, MESSAGE_NUMBER,
- statistics.get(Connection.MESSAGES_IN));
- assertEquals("Unexpected value of connection statistics attribute " + Connection.MESSAGES_OUT,
- MESSAGE_NUMBER * 2 - 1, statistics.get(Connection.MESSAGES_OUT));
-
- @SuppressWarnings("unchecked")
- List<Map<String, Object>> sessions = (List<Map<String, Object>>) connectionDetails.get(SESSIONS_ATTRIBUTE);
- assertNotNull("Sessions cannot be found", sessions);
- assertEquals("Unexpected number of sessions", 1, sessions.size());
- assertSession(sessions.get(0), (AMQSession<?, ?>) _session);
- }
-
- private void assertSession(Map<String, Object> sessionData, AMQSession<?, ?> session)
- {
- assertNotNull("Session map cannot be null", sessionData);
- Asserts.assertAttributesPresent(sessionData, Session.AVAILABLE_ATTRIBUTES, Session.STATE, Session.DURABLE,
- Session.LIFETIME_POLICY, Session.TIME_TO_LIVE, Session.CREATED, Session.UPDATED);
- assertEquals("Unexpecte value of attribute " + Session.NAME, session.getChannelId() + "",
- sessionData.get(Session.NAME));
- assertEquals("Unexpecte value of attribute " + Session.PRODUCER_FLOW_BLOCKED, Boolean.FALSE,
- sessionData.get(Session.PRODUCER_FLOW_BLOCKED));
- assertEquals("Unexpecte value of attribute " + Session.CHANNEL_ID, session.getChannelId(),
- sessionData.get(Session.CHANNEL_ID));
-
- @SuppressWarnings("unchecked")
- Map<String, Object> statistics = (Map<String, Object>) sessionData.get(Asserts.STATISTICS_ATTRIBUTE);
- Asserts.assertAttributesPresent(statistics, Session.AVAILABLE_STATISTICS, Session.BYTES_IN, Session.BYTES_OUT,
- Session.STATE_CHANGED, Session.UNACKNOWLEDGED_BYTES, Session.LOCAL_TRANSACTION_OPEN,
- Session.XA_TRANSACTION_BRANCH_ENDS, Session.XA_TRANSACTION_BRANCH_STARTS,
- Session.XA_TRANSACTION_BRANCH_SUSPENDS);
-
- assertEquals("Unexpecte value of statistic attribute " + Session.UNACKNOWLEDGED_MESSAGES, MESSAGE_NUMBER - 1,
- statistics.get(Session.UNACKNOWLEDGED_MESSAGES));
- assertEquals("Unexpecte value of statistic attribute " + Session.LOCAL_TRANSACTION_BEGINS, 4,
- statistics.get(Session.LOCAL_TRANSACTION_BEGINS));
- assertEquals("Unexpecte value of statistic attribute " + Session.LOCAL_TRANSACTION_ROLLBACKS, 1,
- statistics.get(Session.LOCAL_TRANSACTION_ROLLBACKS));
- assertEquals("Unexpecte value of statistic attribute " + Session.CONSUMER_COUNT, 1,
- statistics.get(Session.CONSUMER_COUNT));
- }
-
- private String getConnectionName() throws IOException
- {
- Map<String, Object> hostDetails = getJsonAsSingletonList("/rest/virtualhost/test");
- @SuppressWarnings("unchecked")
- List<Map<String, Object>> connections = (List<Map<String, Object>>) hostDetails
- .get(VirtualHostRestTest.VIRTUALHOST_CONNECTIONS_ATTRIBUTE);
- assertEquals("Unexpected number of connections", 1, connections.size());
- Map<String, Object> connection = connections.get(0);
- String connectionName = (String) connection.get(Connection.NAME);
- return connectionName;
- }
-}
diff --git a/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/ExchangeRestTest.java b/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/ExchangeRestTest.java
deleted file mode 100644
index 4904d2adf3..0000000000
--- a/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/ExchangeRestTest.java
+++ /dev/null
@@ -1,87 +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.management.plugin.servlet.rest;
-
-import java.net.URLDecoder;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.qpid.server.model.Binding;
-import org.apache.qpid.server.model.Exchange;
-
-public class ExchangeRestTest extends QpidRestTestCase
-{
- public void testGet() throws Exception
- {
- List<Map<String, Object>> exchanges = getJsonAsList("/rest/exchange");
- assertNotNull("Exchanges cannot be null", exchanges);
- assertTrue("Unexpected number of exchanges", exchanges.size() >= EXPECTED_HOSTS.length * EXPECTED_EXCHANGES.length);
- for (Map<String, Object> exchange : exchanges)
- {
- Asserts.assertExchange((String) exchange.get(Exchange.NAME), (String) exchange.get(Exchange.TYPE), exchange);
- }
- }
-
- public void testGetHostExchanges() throws Exception
- {
- List<Map<String, Object>> exchanges = getJsonAsList("/rest/exchange/test");
- assertNotNull("Users cannot be null", exchanges);
- assertEquals("Unexpected number of exchanges", 6, EXPECTED_EXCHANGES.length);
- for (String exchangeName : EXPECTED_EXCHANGES)
- {
- Map<String, Object> exchange = find(Exchange.NAME, exchangeName, exchanges);
- assertExchange(exchangeName, exchange);
- }
- }
-
- public void testGetHostExchangeByName() throws Exception
- {
- for (String exchangeName : EXPECTED_EXCHANGES)
- {
- Map<String, Object> exchange = getJsonAsSingletonList("/rest/exchange/test/"
- + URLDecoder.decode(exchangeName, "UTF-8"));
- assertExchange(exchangeName, exchange);
- }
- }
-
- private void assertExchange(String exchangeName, Map<String, Object> exchange)
- {
- assertNotNull("Exchange with name " + exchangeName + " is not found", exchange);
- String type = (String) exchange.get(Exchange.TYPE);
- Asserts.assertExchange(exchangeName, type, exchange);
- if ("direct".equals(type))
- {
- assertBindings(exchange);
- }
- }
-
- private void assertBindings(Map<String, Object> exchange)
- {
- @SuppressWarnings("unchecked")
- List<Map<String, Object>> bindings = (List<Map<String, Object>>) exchange.get("bindings");
- for (String queueName : EXPECTED_QUEUES)
- {
- Map<String, Object> binding = find(Binding.NAME, queueName, bindings);
- Asserts.assertBinding(queueName, (String) exchange.get(Exchange.NAME), binding);
- }
- }
-
-}
diff --git a/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/LogRecordsRestTest.java b/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/LogRecordsRestTest.java
deleted file mode 100644
index c64fd6e1da..0000000000
--- a/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/LogRecordsRestTest.java
+++ /dev/null
@@ -1,42 +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.management.plugin.servlet.rest;
-
-import java.util.List;
-import java.util.Map;
-
-public class LogRecordsRestTest extends QpidRestTestCase
-{
- public void testGet() throws Exception
- {
- List<Map<String, Object>> logs = getJsonAsList("/rest/logrecords");
- assertNotNull("Logs data cannot be null", logs);
- assertTrue("Logs are not found", logs.size() > 0);
- Map<String, Object> record = find("message", "[Broker] BRK-1004 : Qpid Broker Ready", logs);
-
- assertNotNull("BRK-1004 message is not found", record);
- assertNotNull("Message id cannot be null", record.get("id"));
- assertNotNull("Message timestamp cannot be null", record.get("timestamp"));
- assertEquals("Unexpected log level", "INFO", record.get("level"));
- assertEquals("Unexpected thread", "main", record.get("thread"));
- assertEquals("Unexpected logger", "qpid.message.broker.ready", record.get("logger"));
- }
-}
diff --git a/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/MessagesRestTest.java b/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/MessagesRestTest.java
deleted file mode 100644
index 492df43957..0000000000
--- a/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/MessagesRestTest.java
+++ /dev/null
@@ -1,354 +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.management.plugin.servlet.rest;
-
-import java.io.IOException;
-import java.net.HttpURLConnection;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.TimeUnit;
-
-import javax.jms.BytesMessage;
-import javax.jms.Connection;
-import javax.jms.DeliveryMode;
-import javax.jms.Destination;
-import javax.jms.Message;
-import javax.jms.MessageProducer;
-import javax.jms.Session;
-
-import org.codehaus.jackson.JsonParseException;
-import org.codehaus.jackson.map.JsonMappingException;
-
-public class MessagesRestTest extends QpidRestTestCase
-{
-
- /**
- * Message number to publish into queue
- */
- private static final int MESSAGE_NUMBER = 12;
-
- private Connection _connection;
- private Session _session;
- private MessageProducer _producer;
- private long _startTime;
- private long _ttl;
-
- public void setUp() throws Exception
- {
- super.setUp();
- _startTime = System.currentTimeMillis();
- _connection = getConnection();
- _session = _connection.createSession(true, Session.SESSION_TRANSACTED);
- String queueName = getTestQueueName();
- Destination queue = _session.createQueue(queueName);
- _session.createConsumer(queue);
- _producer = _session.createProducer(queue);
-
- _ttl = TimeUnit.DAYS.toMillis(1);
- for (int i = 0; i < MESSAGE_NUMBER; i++)
- {
- Message m = _session.createTextMessage("Test-" + i);
- m.setIntProperty("index", i);
- if (i % 2 == 0)
- {
- _producer.send(m);
- }
- else
- {
- _producer.send(m, DeliveryMode.NON_PERSISTENT, 5, _ttl);
- }
- }
- _session.commit();
- }
-
- public void testGet() throws Exception
- {
- String queueName = getTestQueueName();
- List<Map<String, Object>> messages = getJsonAsList("/rest/message/test/" + queueName);
- assertNotNull("Messages are not found", messages);
- assertEquals("Unexpected number of messages", MESSAGE_NUMBER, messages.size());
- int position = 0;
- for (Map<String, Object> message : messages)
- {
- assertMessage(position, message);
- position++;
- }
- }
-
- public void testGetMessageContent() throws Exception
- {
- String queueName = getTestQueueName();
-
- // add bytes message
- BytesMessage byteMessage = _session.createBytesMessage();
- byte[] messageBytes = "Test".getBytes();
- byteMessage.writeBytes(messageBytes);
- byteMessage.setStringProperty("test", "value");
- _producer.send(byteMessage);
- _session.commit();
-
- // get message IDs
- List<Long> ids = getMesssageIds(queueName);
-
- Map<String, Object> message = getJsonAsMap("/rest/message/test/" + queueName + "/" + ids.get(0));
- assertMessageAttributes(message);
- assertMessageAttributeValues(message, true);
-
- @SuppressWarnings("unchecked")
- Map<String, Object> headers = (Map<String, Object>) message.get("headers");
- assertNotNull("Message headers are not found", headers);
- assertEquals("Unexpected message header", 0, headers.get("index"));
-
- Long lastMessageId = ids.get(ids.size() - 1);
- message = getJsonAsMap("/rest/message/test/" + queueName + "/" + lastMessageId);
- assertMessageAttributes(message);
- assertEquals("Unexpected message attribute mimeType", "application/octet-stream", message.get("mimeType"));
- assertEquals("Unexpected message attribute size", 4, message.get("size"));
-
- @SuppressWarnings("unchecked")
- Map<String, Object> bytesMessageHeader = (Map<String, Object>) message.get("headers");
- assertNotNull("Message headers are not found", bytesMessageHeader);
- assertEquals("Unexpected message header", "value", bytesMessageHeader.get("test"));
-
- // get content
- HttpURLConnection connection = openManagementConection("/rest/message-content/test/" + queueName + "/"
- + lastMessageId, "GET");
- connection.connect();
- byte[] data = readConnectionInputStream(connection);
- assertTrue("Unexpected message", Arrays.equals(messageBytes, data));
-
- }
-
- public void testPostMoveMessages() throws Exception
- {
- String queueName = getTestQueueName();
- String queueName2 = queueName + "_2";
- Destination queue2 = _session.createQueue(queueName2);
- _session.createConsumer(queue2);
-
- // get message IDs
- List<Long> ids = getMesssageIds(queueName);
-
- // move half of the messages
- int movedNumber = ids.size() / 2;
- List<Long> movedMessageIds = new ArrayList<Long>();
- for (int i = 0; i < movedNumber; i++)
- {
- movedMessageIds.add(ids.remove(i));
- }
-
- // move messages
- HttpURLConnection connection = openManagementConection("/rest/message/test/" + queueName, "POST");
-
- Map<String, Object> messagesData = new HashMap<String, Object>();
- messagesData.put("messages", movedMessageIds);
- messagesData.put("destinationQueue", queueName2);
- messagesData.put("move", Boolean.TRUE);
-
- writeJsonRequest(connection, messagesData);
- assertEquals("Unexpected response code", 200, connection.getResponseCode());
-
- // check messages on target queue
- List<Map<String, Object>> messages = getJsonAsList("/rest/message/test/" + queueName2);
- assertNotNull("Messages are not found", messages);
- assertEquals("Unexpected number of messages", movedMessageIds.size(), messages.size());
- for (Long id : movedMessageIds)
- {
- Map<String, Object> message = find("id", id.intValue(), messages);
- assertMessageAttributes(message);
- }
-
- // check messages on original queue
- messages = getJsonAsList("/rest/message/test/" + queueName);
- assertNotNull("Messages are not found", messages);
- assertEquals("Unexpected number of messages", ids.size(), messages.size());
- for (Long id : ids)
- {
- Map<String, Object> message = find("id", id.intValue(), messages);
- assertMessageAttributes(message);
- }
- for (Long id : movedMessageIds)
- {
- Map<String, Object> message = find("id", id.intValue(), messages);
- assertNull("Moved message " + id + " is found on original queue", message);
- }
- }
-
- public void testPostCopyMessages() throws Exception
- {
- String queueName = getTestQueueName();
- String queueName2 = queueName + "_2";
- Destination queue2 = _session.createQueue(queueName2);
- _session.createConsumer(queue2);
-
- // get message IDs
- List<Long> ids = getMesssageIds(queueName);
-
- // copy half of the messages
- int copyNumber = ids.size() / 2;
- List<Long> copyMessageIds = new ArrayList<Long>();
- for (int i = 0; i < copyNumber; i++)
- {
- copyMessageIds.add(ids.remove(i));
- }
-
- // copy messages
- HttpURLConnection connection = openManagementConection("/rest/message/test/" + queueName, "POST");
-
- Map<String, Object> messagesData = new HashMap<String, Object>();
- messagesData.put("messages", copyMessageIds);
- messagesData.put("destinationQueue", queueName2);
-
- writeJsonRequest(connection, messagesData);
- assertEquals("Unexpected response code", 200, connection.getResponseCode());
-
- // check messages on target queue
- List<Map<String, Object>> messages = getJsonAsList("/rest/message/test/" + queueName2);
- assertNotNull("Messages are not found", messages);
- assertEquals("Unexpected number of messages", copyMessageIds.size(), messages.size());
- for (Long id : copyMessageIds)
- {
- Map<String, Object> message = find("id", id.intValue(), messages);
- assertMessageAttributes(message);
- }
-
- // check messages on original queue
- messages = getJsonAsList("/rest/message/test/" + queueName);
- assertNotNull("Messages are not found", messages);
- assertEquals("Unexpected number of messages", MESSAGE_NUMBER, messages.size());
- for (Long id : ids)
- {
- Map<String, Object> message = find("id", id.intValue(), messages);
- assertMessageAttributes(message);
- }
- for (Long id : copyMessageIds)
- {
- Map<String, Object> message = find("id", id.intValue(), messages);
- assertMessageAttributes(message);
- }
- }
-
- public void testDeleteMessages() throws Exception
- {
- String queueName = getTestQueueName();
-
- // get message IDs
- List<Long> ids = getMesssageIds(queueName);
-
- // delete half of the messages
- int deleteNumber = ids.size() / 2;
- StringBuilder queryString = new StringBuilder();
- List<Long> deleteMessageIds = new ArrayList<Long>();
- for (int i = 0; i < deleteNumber; i++)
- {
- Long id = ids.remove(i);
- deleteMessageIds.add(id);
- if (queryString.length() > 0)
- {
- queryString.append("&");
- }
- queryString.append("id=").append(id);
- }
-
- // delete messages
- HttpURLConnection connection = openManagementConection(
- "/rest/message/test/" + queueName + "?" + queryString.toString(), "DELETE");
- connection.connect();
- assertEquals("Unexpected response code", 200, connection.getResponseCode());
-
- // check messages on queue
- List<Map<String, Object>> messages = getJsonAsList("/rest/message/test/" + queueName);
- assertNotNull("Messages are not found", messages);
- assertEquals("Unexpected number of messages", ids.size(), messages.size());
- for (Long id : ids)
- {
- Map<String, Object> message = find("id", id.intValue(), messages);
- assertMessageAttributes(message);
- }
- for (Long id : deleteMessageIds)
- {
- Map<String, Object> message = find("id", id.intValue(), messages);
- assertNull("Message with id " + id + " was not deleted", message);
- }
- }
-
- private List<Long> getMesssageIds(String queueName) throws IOException, JsonParseException, JsonMappingException
- {
- List<Map<String, Object>> messages = getJsonAsList("/rest/message/test/" + queueName);
- List<Long> ids = new ArrayList<Long>();
- for (Map<String, Object> message : messages)
- {
- ids.add(((Number) message.get("id")).longValue());
- }
- return ids;
- }
-
- private void assertMessage(int position, Map<String, Object> message)
- {
- assertMessageAttributes(message);
-
- assertEquals("Unexpected message attribute position", position, message.get("position"));
- assertEquals("Unexpected message attribute size", position < 10 ? 6 : 7, message.get("size"));
- boolean even = position % 2 == 0;
- assertMessageAttributeValues(message, even);
- }
-
- private void assertMessageAttributeValues(Map<String, Object> message, boolean even)
- {
- if (even)
- {
- assertEquals("Unexpected message attribute expirationTime", 0, message.get("expirationTime"));
- assertEquals("Unexpected message attribute priority", 4, message.get("priority"));
- assertEquals("Unexpected message attribute persistent", Boolean.TRUE, message.get("persistent"));
- }
- else
- {
- assertEquals("Unexpected message attribute expirationTime", ((Number) message.get("timestamp")).longValue()
- + _ttl, message.get("expirationTime"));
- assertEquals("Unexpected message attribute priority", 5, message.get("priority"));
- assertEquals("Unexpected message attribute persistent", Boolean.FALSE, message.get("persistent"));
- }
- assertEquals("Unexpected message attribute mimeType", "text/plain", message.get("mimeType"));
- assertEquals("Unexpected message attribute userId", "guest", message.get("userId"));
- assertEquals("Unexpected message attribute deliveryCount", 0, message.get("deliveryCount"));
- assertEquals("Unexpected message attribute state", "Available", message.get("state"));
- }
-
- private void assertMessageAttributes(Map<String, Object> message)
- {
- assertNotNull("Message map cannot be null", message);
- assertNotNull("Unexpected message attribute deliveryCount", message.get("deliveryCount"));
- assertNotNull("Unexpected message attribute state", message.get("state"));
- assertNotNull("Unexpected message attribute id", message.get("id"));
- assertNotNull("Message arrivalTime cannot be null", message.get("arrivalTime"));
- assertNotNull("Message timestamp cannot be null", message.get("timestamp"));
- assertTrue("Message arrivalTime cannot be null", ((Number) message.get("arrivalTime")).longValue() > _startTime);
- assertNotNull("Message messageId cannot be null", message.get("messageId"));
- assertNotNull("Unexpected message attribute mimeType", message.get("mimeType"));
- assertNotNull("Unexpected message attribute userId", message.get("userId"));
- assertNotNull("Message priority cannot be null", message.get("priority"));
- assertNotNull("Message expirationTime cannot be null", message.get("expirationTime"));
- assertNotNull("Message persistent cannot be null", message.get("persistent"));
- }
-}
diff --git a/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/PortRestTest.java b/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/PortRestTest.java
deleted file mode 100644
index 739ef5c737..0000000000
--- a/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/PortRestTest.java
+++ /dev/null
@@ -1,61 +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.management.plugin.servlet.rest;
-
-import java.net.URLDecoder;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.qpid.server.model.Port;
-
-public class PortRestTest extends QpidRestTestCase
-{
- public void testGet() throws Exception
- {
- List<Map<String, Object>> ports = getJsonAsList("/rest/port/");
- assertNotNull("Port data cannot be null", ports);
- assertEquals("Unexpected number of ports", 2, ports.size());
- int[] expectedPorts = { getPort(), getHttpPort() };
- for (int port : expectedPorts)
- {
- String portName = "0.0.0.0:" + port;
- Map<String, Object> portData = find(Port.NAME, portName, ports);
- assertNotNull("Port " + portName + " is not found", portData);
- Asserts.assertPortAttributes(portData);
- }
- }
-
- public void testGetPort() throws Exception
- {
- List<Map<String, Object>> ports = getJsonAsList("/rest/port/");
- assertNotNull("Ports data cannot be null", ports);
- assertEquals("Unexpected number of ports", 2, ports.size());
- for (Map<String, Object> portMap : ports)
- {
- String portName = (String) portMap.get(Port.NAME);
- assertNotNull("Port name attribute is not found", portName);
- Map<String, Object> portData = getJsonAsSingletonList("/rest/port/" + URLDecoder.decode(portName, "UTF-8"));
- assertNotNull("Port " + portName + " is not found", portData);
- Asserts.assertPortAttributes(portData);
- }
- }
-
-}
diff --git a/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/QpidRestTestCase.java b/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/QpidRestTestCase.java
deleted file mode 100644
index e83341de80..0000000000
--- a/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/QpidRestTestCase.java
+++ /dev/null
@@ -1,245 +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.management.plugin.servlet.rest;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.HttpURLConnection;
-import java.net.InetAddress;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.commons.configuration.ConfigurationException;
-import org.apache.log4j.Logger;
-import org.apache.qpid.test.utils.QpidBrokerTestCase;
-import org.codehaus.jackson.JsonGenerationException;
-import org.codehaus.jackson.JsonParseException;
-import org.codehaus.jackson.map.JsonMappingException;
-import org.codehaus.jackson.map.ObjectMapper;
-import org.codehaus.jackson.type.TypeReference;
-
-public class QpidRestTestCase extends QpidBrokerTestCase
-{
- private static final Logger LOGGER = Logger.getLogger(QpidRestTestCase.class);
-
- public static final String[] EXPECTED_HOSTS = { "development", "test", "localhost" };
- public static final String[] EXPECTED_QUEUES = { "queue", "ping" };
- public static final String[] EXPECTED_EXCHANGES = { "amq.fanout", "amq.match", "amq.direct", "amq.topic",
- "qpid.management", "<<default>>" };
-
- private int _httpPort;
- private String _hostName;
- private List<HttpURLConnection> _httpConnections;
-
- @Override
- public void setUp() throws Exception
- {
- _httpConnections = new ArrayList<HttpURLConnection>();
- _hostName = InetAddress.getLocalHost().getHostName();
- _httpPort = findFreePort();
- customizeConfiguration();
- super.setUp();
-
- }
-
- protected void customizeConfiguration() throws ConfigurationException, IOException
- {
- setConfigurationProperty("management.enabled", "false");
- setConfigurationProperty("management.http.enabled", "true");
- setConfigurationProperty("management.https.enabled", "false");
- setConfigurationProperty("management.http.port", Integer.toString(_httpPort));
- }
-
- public void teearDown() throws Exception
- {
- for (HttpURLConnection connection : _httpConnections)
- {
- try
- {
- connection.disconnect();
- }
- catch (Exception e)
- {
- // ignore
- }
- }
- super.tearDown();
- }
-
- protected int getHttpPort()
- {
- return _httpPort;
- }
-
- protected String getHostName()
- {
- return _hostName;
- }
-
- protected String getProtocol()
- {
- return "http";
- }
-
- protected String getManagementURL()
- {
- return getProtocol() + "://" + getHostName() + ":" + getHttpPort();
- }
-
- protected URL getManagementURL(String path) throws MalformedURLException
- {
- return new URL(getManagementURL() + path);
- }
-
- protected HttpURLConnection openManagementConection(String path) throws IOException
- {
- URL url = getManagementURL(path);
- HttpURLConnection httpCon = (HttpURLConnection) url.openConnection();
- httpCon.setDoOutput(true);
- return httpCon;
- }
-
- protected HttpURLConnection openManagementConection(String path, String method) throws IOException
- {
- HttpURLConnection httpCon = openManagementConection(path);
- httpCon.setRequestMethod(method);
- return httpCon;
- }
-
- protected List<Map<String, Object>> readJsonResponseAsList(HttpURLConnection connection) throws IOException,
- JsonParseException, JsonMappingException
- {
- byte[] data = readConnectionInputStream(connection);
-
- ObjectMapper mapper = new ObjectMapper();
-
- TypeReference<List<LinkedHashMap<String, Object>>> typeReference = new TypeReference<List<LinkedHashMap<String, Object>>>()
- {
- };
- List<Map<String, Object>> providedObject = mapper.readValue(new ByteArrayInputStream(data), typeReference);
- return providedObject;
- }
-
- protected Map<String, Object> readJsonResponseAsMap(HttpURLConnection connection) throws IOException,
- JsonParseException, JsonMappingException
- {
- byte[] data = readConnectionInputStream(connection);
-
- ObjectMapper mapper = new ObjectMapper();
-
- TypeReference<LinkedHashMap<String, Object>> typeReference = new TypeReference<LinkedHashMap<String, Object>>()
- {
- };
- Map<String, Object> providedObject = mapper.readValue(new ByteArrayInputStream(data), typeReference);
- return providedObject;
- }
-
- protected byte[] readConnectionInputStream(HttpURLConnection connection) throws IOException
- {
- InputStream is = connection.getInputStream();
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- byte[] buffer = new byte[1024];
- int len = -1;
- while ((len = is.read(buffer)) != -1)
- {
- baos.write(buffer, 0, len);
- }
- if (LOGGER.isTraceEnabled())
- {
- LOGGER.trace("RESPONSE:" + new String(baos.toByteArray()));
- }
- return baos.toByteArray();
- }
-
- protected void writeJsonRequest(HttpURLConnection connection, Map<String, Object> data) throws JsonGenerationException,
- JsonMappingException, IOException
- {
- ObjectMapper mapper = new ObjectMapper();
- mapper.writeValue(connection.getOutputStream(), data);
- }
-
- protected Map<String, Object> find(String name, Object value, List<Map<String, Object>> data)
- {
- for (Map<String, Object> map : data)
- {
- Object mapValue = map.get(name);
- if (value.equals(mapValue))
- {
- return map;
- }
- }
- return null;
- }
-
- protected Map<String, Object> find(Map<String, Object> searchAttributes, List<Map<String, Object>> data)
- {
- for (Map<String, Object> map : data)
- {
- boolean equals = true;
- for (Map.Entry<String, Object> entry : searchAttributes.entrySet())
- {
- Object mapValue = map.get(entry.getKey());
- if (!entry.getValue().equals(mapValue))
- {
- equals = false;
- break;
- }
- }
- if (equals)
- {
- return map;
- }
- }
- return null;
- }
-
- protected Map<String, Object> getJsonAsSingletonList(String path) throws IOException
- {
- List<Map<String, Object>> response = getJsonAsList(path);
-
- assertNotNull("Response cannot be null", response);
- assertEquals("Unexpected response", 1, response.size());
- return response.get(0);
- }
-
- protected List<Map<String, Object>> getJsonAsList(String path) throws IOException, JsonParseException,
- JsonMappingException
- {
- HttpURLConnection connection = openManagementConection(path, "GET");
- connection.connect();
- List<Map<String, Object>> response = readJsonResponseAsList(connection);
- return response;
- }
-
- protected Map<String, Object> getJsonAsMap(String path) throws IOException
- {
- HttpURLConnection connection = openManagementConection(path, "GET");
- connection.connect();
- Map<String, Object> response = readJsonResponseAsMap(connection);
- return response;
- }
-}
diff --git a/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/QueueRestTest.java b/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/QueueRestTest.java
deleted file mode 100644
index 5f11b3fb1d..0000000000
--- a/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/QueueRestTest.java
+++ /dev/null
@@ -1,225 +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.management.plugin.servlet.rest;
-
-import java.io.IOException;
-import java.net.HttpURLConnection;
-import java.net.URLDecoder;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import javax.jms.Connection;
-import javax.jms.Destination;
-import javax.jms.Message;
-import javax.jms.MessageConsumer;
-import javax.jms.MessageProducer;
-import javax.jms.Session;
-
-import org.apache.qpid.server.model.Binding;
-import org.apache.qpid.server.model.Consumer;
-import org.apache.qpid.server.model.LifetimePolicy;
-import org.apache.qpid.server.model.Queue;
-
-public class QueueRestTest extends QpidRestTestCase
-{
- private static final String QUEUE_ATTRIBUTE_CONSUMERS = "consumers";
- private static final String QUEUE_ATTRIBUTE_BINDINGS = "bindings";
-
- /**
- * Message number to publish into queue
- */
- private static final int MESSAGE_NUMBER = 2;
- private static final int MESSAGE_PAYLOAD_SIZE = 6;
- private static final int ENQUEUED_MESSAGES = 1;
- private static final int DEQUEUED_MESSAGES = 1;
- private static final int ENQUEUED_BYTES = MESSAGE_PAYLOAD_SIZE;
- private static final int DEQUEUED_BYTES = MESSAGE_PAYLOAD_SIZE;
-
- private Connection _connection;
-
- public void setUp() throws Exception
- {
- super.setUp();
- _connection = getConnection();
- Session session = _connection.createSession(true, Session.SESSION_TRANSACTED);
- String queueName = getTestQueueName();
- Destination queue = session.createQueue(queueName);
- MessageConsumer consumer = session.createConsumer(queue);
- MessageProducer producer = session.createProducer(queue);
-
- for (int i = 0; i < MESSAGE_NUMBER; i++)
- {
- producer.send(session.createTextMessage("Test-" + i));
- }
- session.commit();
- _connection.start();
- Message m = consumer.receive(1000l);
- assertNotNull("Message is not received", m);
- session.commit();
- }
-
- public void testGetVirtualHostQueues() throws Exception
- {
- String queueName = getTestQueueName();
- List<Map<String, Object>> queues = getJsonAsList("/rest/queue/test");
- assertEquals("Unexpected number of queues", EXPECTED_QUEUES.length + 1, queues.size());
- String[] expectedQueues = new String[EXPECTED_QUEUES.length + 1];
- System.arraycopy(EXPECTED_QUEUES, 0, expectedQueues, 0, EXPECTED_QUEUES.length);
- expectedQueues[EXPECTED_QUEUES.length] = queueName;
-
- for (String name : expectedQueues)
- {
- Map<String, Object> queueDetails = find(Queue.NAME, name, queues);
- Asserts.assertQueue(name, "standard", queueDetails);
-
- @SuppressWarnings("unchecked")
- List<Map<String, Object>> bindings = (List<Map<String, Object>>) queueDetails.get(QUEUE_ATTRIBUTE_BINDINGS);
- assertNotNull("Queue bindings are not found", bindings);
- assertEquals("Unexpected number of bindings", 2, bindings.size());
-
- Map<String, Object> defaultExchangeBinding = find(Binding.EXCHANGE, "<<default>>", bindings);
- Map<String, Object> directExchangeBinding = find(Binding.EXCHANGE, "amq.direct", bindings);
- Asserts.assertBinding(name, "<<default>>", defaultExchangeBinding);
- Asserts.assertBinding(name, "amq.direct", directExchangeBinding);
- }
- }
-
- public void testGetByName() throws Exception
- {
- String queueName = getTestQueueName();
- Map<String, Object> queueDetails = getJsonAsSingletonList("/rest/queue/test/" + queueName);
- Asserts.assertQueue(queueName, "standard", queueDetails);
- assertStatistics(queueDetails);
-
- @SuppressWarnings("unchecked")
- List<Map<String, Object>> bindings = (List<Map<String, Object>>) queueDetails.get(QUEUE_ATTRIBUTE_BINDINGS);
- assertNotNull("Queue bindings are not found", bindings);
- assertEquals("Unexpected number of bindings", 2, bindings.size());
-
- Map<String, Object> defaultExchangeBinding = find(Binding.EXCHANGE, "<<default>>", bindings);
- Map<String, Object> directExchangeBinding = find(Binding.EXCHANGE, "amq.direct", bindings);
- Asserts.assertBinding(queueName, "<<default>>", defaultExchangeBinding);
- Asserts.assertBinding(queueName, "amq.direct", directExchangeBinding);
-
- @SuppressWarnings("unchecked")
- List<Map<String, Object>> consumers = (List<Map<String, Object>>) queueDetails.get(QUEUE_ATTRIBUTE_CONSUMERS);
- assertNotNull("Queue consumers are not found", consumers);
- assertEquals("Unexpected number of consumers", 1, consumers.size());
- assertConsumer(consumers.get(0));
- }
-
- public void testPutCreateBinding() throws Exception
- {
- String queueName = getTestQueueName();
- String bindingName = queueName + 2;
- String[] exchanges = { "amq.direct", "amq.fanout", "amq.topic", "amq.match", "qpid.management", "<<default>>" };
-
- for (int i = 0; i < exchanges.length; i++)
- {
- createBinding(bindingName, exchanges[i], queueName);
- }
-
- Map<String, Object> queueDetails = getJsonAsSingletonList("/rest/queue/test/" + queueName);
- Asserts.assertQueue(queueName, "standard", queueDetails);
-
- @SuppressWarnings("unchecked")
- List<Map<String, Object>> bindings = (List<Map<String, Object>>) queueDetails.get(QUEUE_ATTRIBUTE_BINDINGS);
- assertNotNull("Queue bindings are not found", bindings);
- assertEquals("Unexpected number of bindings", exchanges.length + 2, bindings.size());
-
- Map<String, Object> searchAttributes = new HashMap<String, Object>();
- searchAttributes.put(Binding.NAME, bindingName);
-
- for (int i = 0; i < exchanges.length; i++)
- {
- searchAttributes.put(Binding.EXCHANGE, exchanges[i]);
- Map<String, Object> binding = find(searchAttributes, bindings);
- Asserts.assertBinding(bindingName, queueName, exchanges[i], binding);
- }
- }
-
- private void createBinding(String bindingName, String exchangeName, String queueName) throws IOException
- {
- HttpURLConnection connection = openManagementConection(
- "/rest/binding/test/" + URLDecoder.decode(exchangeName, "UTF-8") + "/" + queueName + "/" + bindingName,
- "PUT");
-
- Map<String, Object> bindingData = new HashMap<String, Object>();
- bindingData.put(Binding.NAME, bindingName);
- bindingData.put(Binding.EXCHANGE, exchangeName);
- bindingData.put(Binding.QUEUE, queueName);
-
- writeJsonRequest(connection, bindingData);
- assertEquals("Unexpected response code", 201, connection.getResponseCode());
-
- connection.disconnect();
- }
-
- private void assertConsumer(Map<String, Object> consumer)
- {
- assertNotNull("Consumer map should not be null", consumer);
- Asserts.assertAttributesPresent(consumer, Consumer.AVAILABLE_ATTRIBUTES, Consumer.STATE, Consumer.TIME_TO_LIVE,
- Consumer.CREATED, Consumer.UPDATED, Consumer.SETTLEMENT_MODE, Consumer.EXCLUSIVE, Consumer.SELECTOR,
- Consumer.NO_LOCAL);
-
- assertEquals("Unexpected binding attribute " + Consumer.NAME, "1", consumer.get(Consumer.NAME));
- assertEquals("Unexpected binding attribute " + Consumer.DURABLE, Boolean.FALSE, consumer.get(Consumer.DURABLE));
- assertEquals("Unexpected binding attribute " + Consumer.LIFETIME_POLICY, LifetimePolicy.AUTO_DELETE.name(),
- consumer.get(Consumer.LIFETIME_POLICY));
- assertEquals("Unexpected binding attribute " + Consumer.DISTRIBUTION_MODE, "MOVE",
- consumer.get(Consumer.DISTRIBUTION_MODE));
-
- @SuppressWarnings("unchecked")
- Map<String, Object> statistics = (Map<String, Object>) consumer.get(Asserts.STATISTICS_ATTRIBUTE);
- assertNotNull("Consumer statistics is not present", statistics);
- Asserts.assertAttributesPresent(statistics, Consumer.AVAILABLE_STATISTICS, Consumer.STATE_CHANGED);
- }
-
- private void assertStatistics(Map<String, Object> queueDetails)
- {
- @SuppressWarnings("unchecked")
- Map<String, Object> statistics = (Map<String, Object>) queueDetails.get(Asserts.STATISTICS_ATTRIBUTE);
- assertEquals("Unexpected queue statistics attribute " + Queue.PERSISTENT_DEQUEUED_MESSAGES, DEQUEUED_MESSAGES,
- statistics.get(Queue.PERSISTENT_DEQUEUED_MESSAGES));
- assertEquals("Unexpected queue statistics attribute " + Queue.QUEUE_DEPTH_MESSAGES, ENQUEUED_MESSAGES,
- statistics.get(Queue.QUEUE_DEPTH_MESSAGES));
- assertEquals("Unexpected queue statistics attribute " + Queue.CONSUMER_COUNT, 1,
- statistics.get(Queue.CONSUMER_COUNT));
- assertEquals("Unexpected queue statistics attribute " + Queue.CONSUMER_COUNT_WITH_CREDIT, 1,
- statistics.get(Queue.CONSUMER_COUNT_WITH_CREDIT));
- assertEquals("Unexpected queue statistics attribute " + Queue.BINDING_COUNT, 2, statistics.get(Queue.BINDING_COUNT));
- assertEquals("Unexpected queue statistics attribute " + Queue.PERSISTENT_DEQUEUED_MESSAGES, DEQUEUED_MESSAGES,
- statistics.get(Queue.PERSISTENT_DEQUEUED_MESSAGES));
- assertEquals("Unexpected queue statistics attribute " + Queue.TOTAL_DEQUEUED_MESSAGES, DEQUEUED_MESSAGES,
- statistics.get(Queue.TOTAL_DEQUEUED_MESSAGES));
- assertEquals("Unexpected queue statistics attribute " + Queue.TOTAL_DEQUEUED_BYTES, DEQUEUED_BYTES,
- statistics.get(Queue.TOTAL_DEQUEUED_BYTES));
- assertEquals("Unexpected queue statistics attribute " + Queue.PERSISTENT_DEQUEUED_BYTES, DEQUEUED_BYTES,
- statistics.get(Queue.TOTAL_DEQUEUED_BYTES));
- assertEquals("Unexpected queue statistics attribute " + Queue.PERSISTENT_ENQUEUED_BYTES, ENQUEUED_BYTES
- + DEQUEUED_BYTES, statistics.get(Queue.PERSISTENT_ENQUEUED_BYTES));
- assertEquals("Unexpected queue statistics attribute " + Queue.TOTAL_ENQUEUED_BYTES, ENQUEUED_BYTES + DEQUEUED_BYTES,
- statistics.get(Queue.TOTAL_ENQUEUED_BYTES));
- assertEquals("Unexpected queue statistics attribute " + Queue.QUEUE_DEPTH_BYTES, ENQUEUED_BYTES,
- statistics.get(Queue.QUEUE_DEPTH_BYTES));
- }
-}
diff --git a/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/StructureRestTest.java b/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/StructureRestTest.java
deleted file mode 100644
index b01e1d44b8..0000000000
--- a/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/StructureRestTest.java
+++ /dev/null
@@ -1,115 +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.management.plugin.servlet.rest;
-
-import java.util.List;
-import java.util.Map;
-
-public class StructureRestTest extends QpidRestTestCase
-{
-
- public void testGet() throws Exception
- {
- Map<String, Object> structure = getJsonAsMap("/rest/structure");
- assertNotNull("Structure data cannot be null", structure);
- assertNode(structure, "Broker");
-
- @SuppressWarnings("unchecked")
- List<Map<String, Object>> virtualhosts = (List<Map<String, Object>>) structure.get("virtualhosts");
- assertEquals("Unexpected number of virtual hosts", 3, virtualhosts.size());
-
- @SuppressWarnings("unchecked")
- List<Map<String, Object>> ports = (List<Map<String, Object>>) structure.get("ports");
- assertEquals("Unexpected number of ports", 2, ports.size());
-
- @SuppressWarnings("unchecked")
- List<Map<String, Object>> providers = (List<Map<String, Object>>) structure.get("authenticationproviders");
- assertEquals("Unexpected number of authentication providers", 1, providers.size());
-
- for (String hostName : EXPECTED_HOSTS)
- {
- Map<String, Object> host = find("name", hostName, virtualhosts);
- assertNotNull("Host " + hostName + " is not found ", host);
- assertNode(host, hostName);
-
- @SuppressWarnings("unchecked")
- List<Map<String, Object>> queues = (List<Map<String, Object>>) host.get("queues");
- assertNotNull("Host " + hostName + " queues are not found ", queues);
- for (String queueName : EXPECTED_QUEUES)
- {
- Map<String, Object> queue = find("name", queueName, queues);
- assertNotNull(hostName + " queue " + queueName + " is not found ", queue);
- assertNode(queue, queueName);
-
- @SuppressWarnings("unchecked")
- List<Map<String, Object>> bindings = (List<Map<String, Object>>) queue.get("bindings");
- assertNotNull(hostName + " queue " + queueName + " bindings are not found ", queues);
- for (Map<String, Object> binding : bindings)
- {
- assertNode(binding, queueName);
- }
- }
-
- @SuppressWarnings("unchecked")
- List<Map<String, Object>> exchanges = (List<Map<String, Object>>) host.get("exchanges");
- assertNotNull("Host " + hostName + " exchanges are not found ", exchanges);
- for (String exchangeName : EXPECTED_EXCHANGES)
- {
- Map<String, Object> exchange = find("name", exchangeName, exchanges);
- assertNotNull("Exchange " + exchangeName + " is not found ", exchange);
- assertNode(exchange, exchangeName);
- if ("amq.direct".equalsIgnoreCase(exchangeName) || "<<default>>".equalsIgnoreCase(exchangeName))
- {
- @SuppressWarnings("unchecked")
- List<Map<String, Object>> bindings = (List<Map<String, Object>>) exchange.get("bindings");
- assertNotNull(hostName + " exchange " + exchangeName + " bindings are not found ", bindings);
- for (String queueName : EXPECTED_QUEUES)
- {
- Map<String, Object> binding = find("name", queueName, bindings);
- assertNotNull(hostName + " exchange " + exchangeName + " binding " + queueName + " is not found", binding);
- assertNode(binding, queueName);
- }
- }
- }
-
- @SuppressWarnings("unchecked")
- List<Map<String, Object>> aliases = (List<Map<String, Object>>) host.get("virtualhostaliases");
- assertNotNull("Host " + hostName + " aliaces are not found ", aliases);
- assertEquals("Unexpected aliaces size", 1, aliases.size());
- assertNode(aliases.get(0), hostName);
- }
-
- int[] expectedPorts = { getPort(), getHttpPort() };
- for (int port : expectedPorts)
- {
- String portName = "0.0.0.0:" + port;
- Map<String, Object> portData = find("name", portName, ports);
- assertNotNull("Port " + portName + " is not found ", portData);
- assertNode(portData, portName);
- }
- }
-
- private void assertNode(Map<String, Object> node, String name)
- {
- assertEquals("Unexpected name", name, node.get("name"));
- assertNotNull("Unexpected id", node.get("id"));
- }
-}
diff --git a/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/UserRestTest.java b/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/UserRestTest.java
deleted file mode 100644
index e56fa27e21..0000000000
--- a/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/UserRestTest.java
+++ /dev/null
@@ -1,112 +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.management.plugin.servlet.rest;
-
-import java.net.HttpURLConnection;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.qpid.server.model.User;
-
-public class UserRestTest extends QpidRestTestCase
-{
- public void testGet() throws Exception
- {
- List<Map<String, Object>> users = getJsonAsList("/rest/user");
- assertNotNull("Users cannot be null", users);
- assertTrue("Unexpected number of users", users.size() > 1);
- for (Map<String, Object> user : users)
- {
- assertUser(user);
- }
- }
-
- public void testGetUserByName() throws Exception
- {
- List<Map<String, Object>> users = getJsonAsList("/rest/user");
- assertNotNull("Users cannot be null", users);
- assertTrue("Unexpected number of users", users.size() > 1);
- for (Map<String, Object> user : users)
- {
- assertNotNull("Attribute " + User.ID, user.get(User.ID));
- String userName = (String) user.get(User.NAME);
- assertNotNull("Attribute " + User.NAME, userName);
- Map<String, Object> userDetails = getJsonAsSingletonList("/rest/user/PrincipalDatabaseAuthenticationManager/"
- + userName);
- assertUser(userDetails);
- assertEquals("Unexpected user name", userName, userDetails.get(User.NAME));
- }
- }
-
- public void testPut() throws Exception
- {
- String userName = getTestName();
- HttpURLConnection connection = openManagementConection("/rest/user/PrincipalDatabaseAuthenticationManager/"
- + userName, "PUT");
-
- Map<String, Object> userData = new HashMap<String, Object>();
- userData.put(User.NAME, userName);
- userData.put(User.PASSWORD, userName);
-
- writeJsonRequest(connection, userData);
- assertEquals("Unexpected response code", 201, connection.getResponseCode());
-
- connection.disconnect();
-
- Map<String, Object> userDetails = getJsonAsSingletonList("/rest/user/PrincipalDatabaseAuthenticationManager/"
- + userName);
- assertUser(userDetails);
- assertEquals("Unexpected user name", userName, userDetails.get(User.NAME));
- }
-
- public void testDelete() throws Exception
- {
- // add user
- String userName = getTestName();
- HttpURLConnection connection = openManagementConection("/rest/user/PrincipalDatabaseAuthenticationManager/"
- + userName, "PUT");
-
- Map<String, Object> userData = new HashMap<String, Object>();
- userData.put(User.NAME, userName);
- userData.put(User.PASSWORD, userName);
-
- writeJsonRequest(connection, userData);
- assertEquals("Unexpected response code", 201, connection.getResponseCode());
- connection.disconnect();
-
- Map<String, Object> userDetails = getJsonAsSingletonList("/rest/user/PrincipalDatabaseAuthenticationManager/"
- + userName);
- String id = (String) userDetails.get(User.ID);
-
- connection = openManagementConection("/rest/user/PrincipalDatabaseAuthenticationManager?id=" + id, "DELETE");
- connection.connect();
- assertEquals("Unexpected response code", 200, connection.getResponseCode());
- List<Map<String, Object>> users = getJsonAsList("/rest/user/PrincipalDatabaseAuthenticationManager/" + userName);
- assertEquals("User should be deleted", 0, users.size());
- }
-
- private void assertUser(Map<String, Object> user)
- {
- assertNotNull("Attribute " + User.ID, user.get(User.ID));
- assertNotNull("Attribute " + User.NAME, user.get(User.NAME));
- }
-}
diff --git a/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/VirtualHostRestTest.java b/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/VirtualHostRestTest.java
deleted file mode 100644
index 17f1aaaf7b..0000000000
--- a/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/VirtualHostRestTest.java
+++ /dev/null
@@ -1,434 +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.management.plugin.servlet.rest;
-
-import java.io.IOException;
-import java.net.HttpURLConnection;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import javax.jms.Session;
-
-import org.apache.qpid.client.AMQConnection;
-import org.apache.qpid.server.model.Exchange;
-import org.apache.qpid.server.model.Queue;
-import org.apache.qpid.server.model.VirtualHost;
-import org.apache.qpid.server.queue.AMQQueueFactory;
-import org.codehaus.jackson.JsonGenerationException;
-import org.codehaus.jackson.map.JsonMappingException;
-
-public class VirtualHostRestTest extends QpidRestTestCase
-{
- private static final String VIRTUALHOST_EXCHANGES_ATTRIBUTE = "exchanges";
- public static final String VIRTUALHOST_QUEUES_ATTRIBUTE = "queues";
- public static final String VIRTUALHOST_CONNECTIONS_ATTRIBUTE = "connections";
-
- private AMQConnection _connection;
-
- public void testGet() throws Exception
- {
- List<Map<String, Object>> hosts = getJsonAsList("/rest/virtualhost/");
- assertNotNull("Hosts data cannot be null", hosts);
- assertEquals("Unexpected number of hosts", 3, hosts.size());
- for (String hostName : EXPECTED_HOSTS)
- {
- Map<String, Object> host = find("name", hostName, hosts);
- Asserts.assertVirtualHost(hostName, host);
- }
- }
-
- public void testGetHost() throws Exception
- {
- // create AMQP connection to get connection JSON details
- _connection = (AMQConnection) getConnection();
- _connection.createSession(true, Session.SESSION_TRANSACTED);
-
- Map<String, Object> hostDetails = getJsonAsSingletonList("/rest/virtualhost/test");
- Asserts.assertVirtualHost("test", hostDetails);
-
- @SuppressWarnings("unchecked")
- Map<String, Object> statistics = (Map<String, Object>) hostDetails.get(Asserts.STATISTICS_ATTRIBUTE);
- assertEquals("Unexpected number of exchanges in statistics", 6, statistics.get(VirtualHost.EXCHANGE_COUNT));
- assertEquals("Unexpected number of queues in statistics", 2, statistics.get(VirtualHost.QUEUE_COUNT));
- assertEquals("Unexpected number of connections in statistics", 1, statistics.get(VirtualHost.CONNECTION_COUNT));
-
- @SuppressWarnings("unchecked")
- List<Map<String, Object>> exchanges = (List<Map<String, Object>>) hostDetails.get(VIRTUALHOST_EXCHANGES_ATTRIBUTE);
- assertEquals("Unexpected number of exchanges", 6, exchanges.size());
- Asserts.assertDurableExchange("amq.fanout", "fanout", find(Exchange.NAME, "amq.fanout", exchanges));
- Asserts.assertDurableExchange("qpid.management", "management", find(Exchange.NAME, "qpid.management", exchanges));
- Asserts.assertDurableExchange("amq.topic", "topic", find(Exchange.NAME, "amq.topic", exchanges));
- Asserts.assertDurableExchange("amq.direct", "direct", find(Exchange.NAME, "amq.direct", exchanges));
- Asserts.assertDurableExchange("amq.match", "headers", find(Exchange.NAME, "amq.match", exchanges));
- Asserts.assertDurableExchange("<<default>>", "direct", find(Exchange.NAME, "<<default>>", exchanges));
-
- @SuppressWarnings("unchecked")
- List<Map<String, Object>> queues = (List<Map<String, Object>>) hostDetails.get(VIRTUALHOST_QUEUES_ATTRIBUTE);
- assertEquals("Unexpected number of queues", 2, queues.size());
- Map<String, Object> queue = find(Queue.NAME, "queue", queues);
- Map<String, Object> ping = find(Queue.NAME, "ping", queues);
- Asserts.assertQueue("queue", "standard", queue);
- Asserts.assertQueue("ping", "standard", ping);
- assertEquals("Unexpected value of queue attribute " + Queue.DURABLE, Boolean.FALSE, queue.get(Queue.DURABLE));
- assertEquals("Unexpected value of queue attribute " + Queue.DURABLE, Boolean.FALSE, ping.get(Queue.DURABLE));
-
- @SuppressWarnings("unchecked")
- List<Map<String, Object>> connections = (List<Map<String, Object>>) hostDetails
- .get(VIRTUALHOST_CONNECTIONS_ATTRIBUTE);
- assertEquals("Unexpected number of connections", 1, connections.size());
- Asserts.assertConnection(connections.get(0), _connection);
- }
-
- public void testPutCreateQueue() throws Exception
- {
- String queueName = getTestQueueName();
-
- createQueue(queueName + "-standard", "standard", null);
-
- Map<String, Object> sortedQueueAttributes = new HashMap<String, Object>();
- sortedQueueAttributes.put(Queue.SORT_KEY, "sortme");
- createQueue(queueName + "-sorted", "sorted", sortedQueueAttributes);
-
- Map<String, Object> priorityQueueAttributes = new HashMap<String, Object>();
- priorityQueueAttributes.put(Queue.PRIORITIES, 10);
- createQueue(queueName + "-priority", "priority", priorityQueueAttributes);
-
- Map<String, Object> lvqQueueAttributes = new HashMap<String, Object>();
- lvqQueueAttributes.put(Queue.LVQ_KEY, "LVQ");
- createQueue(queueName + "-lvq", "lvq", lvqQueueAttributes);
-
- Map<String, Object> hostDetails = getJsonAsSingletonList("/rest/virtualhost/test");
-
- @SuppressWarnings("unchecked")
- List<Map<String, Object>> queues = (List<Map<String, Object>>) hostDetails.get(VirtualHostRestTest.VIRTUALHOST_QUEUES_ATTRIBUTE);
- Map<String, Object> standardQueue = find(Queue.NAME, queueName + "-standard" , queues);
- Map<String, Object> sortedQueue = find(Queue.NAME, queueName + "-sorted" , queues);
- Map<String, Object> priorityQueue = find(Queue.NAME, queueName + "-priority" , queues);
- Map<String, Object> lvqQueue = find(Queue.NAME, queueName + "-lvq" , queues);
-
- Asserts.assertQueue(queueName + "-standard", "standard", standardQueue);
- Asserts.assertQueue(queueName + "-sorted", "sorted", sortedQueue);
- Asserts.assertQueue(queueName + "-priority", "priority", priorityQueue);
- Asserts.assertQueue(queueName + "-lvq", "lvq", lvqQueue);
-
- assertEquals("Unexpected value of queue attribute " + Queue.DURABLE, Boolean.TRUE, standardQueue.get(Queue.DURABLE));
- assertEquals("Unexpected value of queue attribute " + Queue.DURABLE, Boolean.TRUE, sortedQueue.get(Queue.DURABLE));
- assertEquals("Unexpected value of queue attribute " + Queue.DURABLE, Boolean.TRUE, priorityQueue.get(Queue.DURABLE));
- assertEquals("Unexpected value of queue attribute " + Queue.DURABLE, Boolean.TRUE, lvqQueue.get(Queue.DURABLE));
-
- assertEquals("Unexpected sorted key attribute", "sortme", sortedQueue.get(Queue.SORT_KEY));
- assertEquals("Unexpected lvq key attribute", "LVQ", lvqQueue.get(Queue.LVQ_KEY));
- assertEquals("Unexpected priorities key attribute", 10, priorityQueue.get(Queue.PRIORITIES));
- }
-
- public void testPutCreateExchange() throws Exception
- {
- String exchangeName = getTestName();
-
- createExchange(exchangeName + "-direct", "direct");
- createExchange(exchangeName + "-topic", "topic");
- createExchange(exchangeName + "-headers", "headers");
- createExchange(exchangeName + "-fanout", "fanout");
-
- Map<String, Object> hostDetails = getJsonAsSingletonList("/rest/virtualhost/test");
-
- @SuppressWarnings("unchecked")
- List<Map<String, Object>> exchanges = (List<Map<String, Object>>) hostDetails.get(VirtualHostRestTest.VIRTUALHOST_EXCHANGES_ATTRIBUTE);
- Map<String, Object> directExchange = find(Queue.NAME, exchangeName + "-direct" , exchanges);
- Map<String, Object> topicExchange = find(Queue.NAME, exchangeName + "-topic" , exchanges);
- Map<String, Object> headersExchange = find(Queue.NAME, exchangeName + "-headers" , exchanges);
- Map<String, Object> fanoutExchange = find(Queue.NAME, exchangeName + "-fanout" , exchanges);
-
- Asserts.assertDurableExchange(exchangeName + "-direct", "direct", directExchange);
- Asserts.assertDurableExchange(exchangeName + "-topic", "topic", topicExchange);
- Asserts.assertDurableExchange(exchangeName + "-headers", "headers", headersExchange);
- Asserts.assertDurableExchange(exchangeName + "-fanout", "fanout", fanoutExchange);
-
- assertEquals("Unexpected value of queue attribute " + Queue.DURABLE, Boolean.TRUE, directExchange.get(Queue.DURABLE));
- assertEquals("Unexpected value of queue attribute " + Queue.DURABLE, Boolean.TRUE, topicExchange.get(Queue.DURABLE));
- assertEquals("Unexpected value of queue attribute " + Queue.DURABLE, Boolean.TRUE, headersExchange.get(Queue.DURABLE));
- assertEquals("Unexpected value of queue attribute " + Queue.DURABLE, Boolean.TRUE, fanoutExchange.get(Queue.DURABLE));
-
- }
-
- public void testPutCreateLVQWithoutKey() throws Exception
- {
- String queueName = getTestQueueName()+ "-lvq";
- createQueue(queueName, "lvq", null);
-
- Map<String, Object> hostDetails = getJsonAsSingletonList("/rest/virtualhost/test");
-
- @SuppressWarnings("unchecked")
- List<Map<String, Object>> queues = (List<Map<String, Object>>) hostDetails.get(VirtualHostRestTest.VIRTUALHOST_QUEUES_ATTRIBUTE);
- Map<String, Object> lvqQueue = find(Queue.NAME, queueName , queues);
-
- Asserts.assertQueue(queueName , "lvq", lvqQueue);
- assertEquals("Unexpected value of queue attribute " + Queue.DURABLE, Boolean.TRUE, lvqQueue.get(Queue.DURABLE));
- assertEquals("Unexpected lvq key attribute", AMQQueueFactory.QPID_LVQ_KEY, lvqQueue.get(Queue.LVQ_KEY));
- }
-
- public void testPutCreateSortedQueueWithoutKey() throws Exception
- {
- String queueName = getTestQueueName() + "-sorted";
- int responseCode = tryCreateQueue(queueName, "sorted", null);
- assertEquals("Unexpected response code", 409, responseCode);
-
- Map<String, Object> hostDetails = getJsonAsSingletonList("/rest/virtualhost/test");
-
- @SuppressWarnings("unchecked")
- List<Map<String, Object>> queues = (List<Map<String, Object>>) hostDetails.get(VirtualHostRestTest.VIRTUALHOST_QUEUES_ATTRIBUTE);
- Map<String, Object> testQueue = find(Queue.NAME, queueName , queues);
-
- assertNull("Sorted queue without a key was created ", testQueue);
- }
-
- public void testPutCreatePriorityQueueWithoutKey() throws Exception
- {
- String queueName = getTestQueueName()+ "-priority";
- createQueue(queueName, "priority", null);
-
- Map<String, Object> hostDetails = getJsonAsSingletonList("/rest/virtualhost/test");
-
- @SuppressWarnings("unchecked")
- List<Map<String, Object>> queues = (List<Map<String, Object>>) hostDetails.get(VirtualHostRestTest.VIRTUALHOST_QUEUES_ATTRIBUTE);
- Map<String, Object> priorityQueue = find(Queue.NAME, queueName , queues);
-
- Asserts.assertQueue(queueName , "priority", priorityQueue);
- assertEquals("Unexpected value of queue attribute " + Queue.DURABLE, Boolean.TRUE, priorityQueue.get(Queue.DURABLE));
- assertEquals("Unexpected number of priorities", 10, priorityQueue.get(Queue.PRIORITIES));
- }
-
- public void testPutCreateStandardQueueWithoutType() throws Exception
- {
- String queueName = getTestQueueName();
- createQueue(queueName, null, null);
-
- Map<String, Object> hostDetails = getJsonAsSingletonList("/rest/virtualhost/test");
-
- @SuppressWarnings("unchecked")
- List<Map<String, Object>> queues = (List<Map<String, Object>>) hostDetails.get(VirtualHostRestTest.VIRTUALHOST_QUEUES_ATTRIBUTE);
- Map<String, Object> queue = find(Queue.NAME, queueName , queues);
-
- Asserts.assertQueue(queueName , "standard", queue);
- }
-
- public void testPutCreateQueueOfUnsupportedType() throws Exception
- {
- String queueName = getTestQueueName();
- int responseCode = tryCreateQueue(queueName, "unsupported", null);
- assertEquals("Unexpected response code", 409, responseCode);
-
- Map<String, Object> hostDetails = getJsonAsSingletonList("/rest/virtualhost/test");
-
- @SuppressWarnings("unchecked")
- List<Map<String, Object>> queues = (List<Map<String, Object>>) hostDetails.get(VirtualHostRestTest.VIRTUALHOST_QUEUES_ATTRIBUTE);
- Map<String, Object> queue = find(Queue.NAME, queueName , queues);
-
- 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());
- }
-
- public void testPutCreateQueueWithAttributes() throws Exception
- {
- String queueName = getTestQueueName();
-
- Map<String, Object> attributes = new HashMap<String, Object>();
- attributes.put(Queue.ALERT_REPEAT_GAP, 1000);
- attributes.put(Queue.ALERT_THRESHOLD_MESSAGE_AGE, 3600000);
- attributes.put(Queue.ALERT_THRESHOLD_MESSAGE_SIZE, 1000000000);
- attributes.put(Queue.ALERT_THRESHOLD_QUEUE_DEPTH_MESSAGES, 800);
- attributes.put(Queue.MAXIMUM_DELIVERY_ATTEMPTS, 15);
- attributes.put(Queue.QUEUE_FLOW_CONTROL_SIZE_BYTES, 2000000000);
- attributes.put(Queue.QUEUE_FLOW_RESUME_SIZE_BYTES, 1500000000);
-
- createQueue(queueName + "-standard", "standard", attributes);
-
- Map<String, Object> sortedQueueAttributes = new HashMap<String, Object>();
- sortedQueueAttributes.putAll(attributes);
- sortedQueueAttributes.put(Queue.SORT_KEY, "sortme");
- createQueue(queueName + "-sorted", "sorted", sortedQueueAttributes);
-
- Map<String, Object> priorityQueueAttributes = new HashMap<String, Object>();
- priorityQueueAttributes.putAll(attributes);
- priorityQueueAttributes.put(Queue.PRIORITIES, 10);
- createQueue(queueName + "-priority", "priority", priorityQueueAttributes);
-
- Map<String, Object> lvqQueueAttributes = new HashMap<String, Object>();
- lvqQueueAttributes.putAll(attributes);
- lvqQueueAttributes.put(Queue.LVQ_KEY, "LVQ");
- createQueue(queueName + "-lvq", "lvq", lvqQueueAttributes);
-
- Map<String, Object> hostDetails = getJsonAsSingletonList("/rest/virtualhost/test");
-
- @SuppressWarnings("unchecked")
- List<Map<String, Object>> queues = (List<Map<String, Object>>) hostDetails.get(VirtualHostRestTest.VIRTUALHOST_QUEUES_ATTRIBUTE);
- Map<String, Object> standardQueue = find(Queue.NAME, queueName + "-standard" , queues);
- Map<String, Object> sortedQueue = find(Queue.NAME, queueName + "-sorted" , queues);
- Map<String, Object> priorityQueue = find(Queue.NAME, queueName + "-priority" , queues);
- Map<String, Object> lvqQueue = find(Queue.NAME, queueName + "-lvq" , queues);
-
- attributes.put(Queue.DURABLE, Boolean.TRUE);
- Asserts.assertQueue(queueName + "-standard", "standard", standardQueue, attributes);
- Asserts.assertQueue(queueName + "-sorted", "sorted", sortedQueue, attributes);
- Asserts.assertQueue(queueName + "-priority", "priority", priorityQueue, attributes);
- Asserts.assertQueue(queueName + "-lvq", "lvq", lvqQueue, attributes);
-
- assertEquals("Unexpected sorted key attribute", "sortme", sortedQueue.get(Queue.SORT_KEY));
- assertEquals("Unexpected lvq key attribute", "LVQ", lvqQueue.get(Queue.LVQ_KEY));
- assertEquals("Unexpected priorities key attribute", 10, priorityQueue.get(Queue.PRIORITIES));
- }
-
- @SuppressWarnings("unchecked")
- public void testCreateQueueWithDLQEnabled() throws Exception
- {
- String queueName = getTestQueueName();
-
- Map<String, Object> attributes = new HashMap<String, Object>();
- attributes.put(AMQQueueFactory.X_QPID_DLQ_ENABLED, true);
-
- //verify the starting state
- Map<String, Object> hostDetails = getJsonAsSingletonList("/rest/virtualhost/test");
- List<Map<String, Object>> queues = (List<Map<String, Object>>) hostDetails.get(VirtualHostRestTest.VIRTUALHOST_QUEUES_ATTRIBUTE);
- List<Map<String, Object>> exchanges = (List<Map<String, Object>>) hostDetails.get(VirtualHostRestTest.VIRTUALHOST_EXCHANGES_ATTRIBUTE);
-
- assertNull("queue should not have already been present", find(Queue.NAME, queueName , queues));
- assertNull("queue should not have already been present", find(Queue.NAME, queueName + "_DLQ" , queues));
- assertNull("exchange should not have already been present", find(Exchange.NAME, queueName + "_DLE" , exchanges));
-
- //create the queue
- createQueue(queueName, "standard", attributes);
-
- //verify the new queue, as well as the DLQueue and DLExchange have been created
- hostDetails = getJsonAsSingletonList("/rest/virtualhost/test");
- queues = (List<Map<String, Object>>) hostDetails.get(VirtualHostRestTest.VIRTUALHOST_QUEUES_ATTRIBUTE);
- exchanges = (List<Map<String, Object>>) hostDetails.get(VirtualHostRestTest.VIRTUALHOST_EXCHANGES_ATTRIBUTE);
-
- Map<String, Object> queue = find(Queue.NAME, queueName , queues);
- Map<String, Object> dlqQueue = find(Queue.NAME, queueName + "_DLQ" , queues);
- Map<String, Object> dlExchange = find(Exchange.NAME, queueName + "_DLE" , exchanges);
- assertNotNull("queue should not have been present", queue);
- assertNotNull("queue should not have been present", dlqQueue);
- assertNotNull("exchange should not have been present", dlExchange);
-
- //verify that the alternate exchange is set as expected on the new queue
- Map<String, Object> queueAttributes = new HashMap<String, Object>();
- queueAttributes.put(Queue.ALTERNATE_EXCHANGE, queueName + "_DLE");
-
- Asserts.assertQueue(queueName, "standard", queue, queueAttributes);
- Asserts.assertQueue(queueName, "standard", queue, null);
- }
-
- private void createExchange(String exchangeName, String exchangeType) throws IOException
- {
- HttpURLConnection connection = openManagementConection("/rest/exchange/test/" + exchangeName, "PUT");
-
- Map<String, Object> queueData = new HashMap<String, Object>();
- queueData.put(Exchange.NAME, exchangeName);
- queueData.put(Exchange.DURABLE, Boolean.TRUE);
- queueData.put(Exchange.TYPE, exchangeType);
-
- writeJsonRequest(connection, queueData);
- assertEquals("Unexpected response code", 201, connection.getResponseCode());
-
- connection.disconnect();
- }
-
- private void createQueue(String queueName, String queueType, Map<String, Object> attributes) throws IOException,
- JsonGenerationException, JsonMappingException
- {
- int responseCode = tryCreateQueue(queueName, queueType, attributes);
- assertEquals("Unexpected response code", 201, responseCode);
- }
-
- private int tryCreateQueue(String queueName, String queueType, Map<String, Object> attributes) throws IOException,
- JsonGenerationException, JsonMappingException
- {
- HttpURLConnection connection = openManagementConection("/rest/queue/test/" + queueName, "PUT");
-
- Map<String, Object> queueData = new HashMap<String, Object>();
- queueData.put(Queue.NAME, queueName);
- queueData.put(Queue.DURABLE, Boolean.TRUE);
- if (queueType != null)
- {
- queueData.put(Queue.TYPE, queueType);
- }
- if (attributes != null)
- {
- queueData.putAll(attributes);
- }
-
- writeJsonRequest(connection, queueData);
- int responseCode = connection.getResponseCode();
- connection.disconnect();
- return responseCode;
- }
-
-}
diff --git a/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/session/LoginLogoutReporterTest.java b/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/session/LoginLogoutReporterTest.java
new file mode 100644
index 0000000000..1d43c44587
--- /dev/null
+++ b/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/session/LoginLogoutReporterTest.java
@@ -0,0 +1,74 @@
+/*
+ * 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.management.plugin.session;
+
+import static org.mockito.Mockito.verify;
+import static org.mockito.Matchers.argThat;
+
+import javax.security.auth.Subject;
+
+import org.apache.qpid.server.logging.LogActor;
+import org.apache.qpid.server.logging.LogMessage;
+import org.apache.qpid.server.security.auth.AuthenticatedPrincipal;
+import org.mockito.ArgumentMatcher;
+import org.mockito.Mockito;
+
+import junit.framework.TestCase;
+
+public class LoginLogoutReporterTest extends TestCase
+{
+ private LoginLogoutReporter _loginLogoutReport;
+ private Subject _subject = new Subject();
+ private LogActor _logActor = Mockito.mock(LogActor.class);
+
+ @Override
+ protected void setUp() throws Exception
+ {
+ super.setUp();
+
+ _subject.getPrincipals().add(new AuthenticatedPrincipal("mockusername"));
+ _loginLogoutReport = new LoginLogoutReporter(_logActor, _subject);
+ }
+
+ public void testLoginLogged()
+ {
+ _loginLogoutReport.valueBound(null);
+ verify(_logActor).message(isLogMessageWithMessage("MNG-1007 : Open : User mockusername"));
+ }
+
+ public void testLogoutLogged()
+ {
+ _loginLogoutReport.valueUnbound(null);
+ verify(_logActor).message(isLogMessageWithMessage("MNG-1008 : Close : User mockusername"));
+ }
+
+ private LogMessage isLogMessageWithMessage(final String expectedMessage)
+ {
+ return argThat( new ArgumentMatcher<LogMessage>()
+ {
+ @Override
+ public boolean matches(Object argument)
+ {
+ LogMessage actual = (LogMessage) argument;
+ return actual.toString().equals(expectedMessage);
+ }
+ });
+ }
+}
diff --git a/java/broker-plugins/management-jmx/MANIFEST.MF b/java/broker-plugins/management-jmx/MANIFEST.MF
deleted file mode 100644
index b18ec1ace7..0000000000
--- a/java/broker-plugins/management-jmx/MANIFEST.MF
+++ /dev/null
@@ -1,66 +0,0 @@
-Manifest-Version: 1.0
-Bundle-ManifestVersion: 2
-Bundle-Name: Qpid Broker-Plugins Management JMX
-Bundle-SymbolicName: broker-plugins-management-jmx
-Bundle-Description: JMX management plugin for Qpid.
-Bundle-License: http://www.apache.org/licenses/LICENSE-2.0.txt
-Bundle-DocURL: http://www.apache.org/
-Bundle-Version: 1.0.0
-Bundle-Activator: org.apache.qpid.server.jmx.JMXActivator
-Bundle-RequiredExecutionEnvironment: JavaSE-1.6
-Bundle-ClassPath: .
-Bundle-ActivationPolicy: lazy
-Import-Package: org.apache.qpid,
- org.apache.qpid.framing,
- org.apache.qpid.protocol,
- org.apache.qpid.common,
- org.apache.qpid.management.common.mbeans,
- org.apache.qpid.management.common.mbeans.annotations,
- org.apache.qpid.server.security.auth,
- org.apache.qpid.server.security.auth.manager,
- org.apache.qpid.server.security.auth.rmi,
- org.apache.qpid.server.security.auth.sasl,
- org.apache.qpid.server.binding,
- org.apache.qpid.server.exchange,
- org.apache.qpid.server.logging,
- org.apache.qpid.server.logging.log4j,
- org.apache.qpid.server.logging.actors,
- org.apache.qpid.server.logging.messages,
- org.apache.qpid.server.message,
- org.apache.qpid.server.model,
- org.apache.qpid.server.model.adapter,
- org.apache.qpid.server.model.impl,
- org.apache.qpid.server.configuration,
- org.apache.qpid.server.configuration.plugins,
- org.apache.qpid.server.connection,
- org.apache.qpid.server.plugins,
- org.apache.qpid.server.protocol,
- org.apache.qpid.server.queue,
- org.apache.qpid.server.registry,
- org.apache.qpid.server.security,
- org.apache.qpid.server.security.access,
- org.apache.qpid.server.stats,
- org.apache.qpid.server.virtualhost,
- org.apache.qpid.util,
- org.apache.commons.codec;version=1.3.0,
- org.apache.commons.codec.binary;version=1.3.0,
- org.apache.commons.configuration;version=1.0.0,
- org.apache.commons.lang;version=1.0.0,
- org.apache.commons.lang.builder;version=1.0.0,
- org.apache.commons.lang.time;version=1.0.0,
- org.apache.log4j;version=1.2.16,
- org.codehaus.jackson;version=1.9.0,
- org.codehaus.jackson.map;version=1.9.0,
- javax.management.remote.rmi,
- javax.management.remote,
- javax.servlet,
- javax.servlet.http,
- javax.management;version=1.0.0,
- javax.management.monitor;version=1.0.0,
- javax.management.openmbean;version=1.0.0,
- javax.security.auth.login;version=1.0.0,
- javax.security.auth;version=1.0.0,
- javax.rmi.ssl;version=1.0.0,
- org.osgi.util.tracker;version=1.0.0,
- org.osgi.framework;version=1.3
-Export-Package: org.apache.qpid.server.jmx;uses:="org.osgi.framework"
diff --git a/java/broker-plugins/management-jmx/build.xml b/java/broker-plugins/management-jmx/build.xml
index fa50b8467d..9d212cf39a 100644
--- a/java/broker-plugins/management-jmx/build.xml
+++ b/java/broker-plugins/management-jmx/build.xml
@@ -17,28 +17,14 @@
- under the License.
-->
<project name="Qpid Broker-Plugins Management JMX" default="build">
-
- <condition property="systests.optional.depends" value="bdbstore" else="">
- <or>
- <and>
- <contains string="${modules.opt}" substring="bdbstore"/>
- <contains string="${profile}" substring="bdb"/>
- </and>
- <and>
- <istrue value="${optional}"/>
- <contains string="${profile}" substring="bdb"/>
- </and>
- </or>
- </condition>
-
<property name="module.depends" value="common broker management/common" />
- <property name="module.test.depends" value="systests test broker/test common/test management/common client ${systests.optional.depends}" />
+ <property name="module.test.depends" value="broker/tests common/tests management/common client" />
- <property name="module.manifest" value="MANIFEST.MF" />
- <property name="module.plugin" value="true" />
<property name="module.genpom" value="true"/>
<property name="module.genpom.args" value="-Sqpid-common=provided -Sqpid-broker=provided -Sqpid-management-common=provided"/>
+ <property name="broker.plugin" value="true"/>
+
<property name="broker-plugins-management-jmx.libs" value=""/>
<import file="../../module.xml" />
diff --git a/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/CustomRMIServerSocketFactory.java b/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/CustomRMIServerSocketFactory.java
new file mode 100644
index 0000000000..b7aab78e45
--- /dev/null
+++ b/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/CustomRMIServerSocketFactory.java
@@ -0,0 +1,68 @@
+/*
+ * 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.jmx;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.rmi.server.RMIServerSocketFactory;
+
+/**
+ * Custom RMIServerSocketFactory class, used to prevent updates to the RMI registry.
+ * Supplied to the registry at creation, this will prevent RMI-based operations on the
+ * registry such as attempting to bind a new object, thereby securing it from tampering.
+ * This is accomplished by always returning null when attempting to determine the address
+ * of the caller, thus ensuring the registry will refuse the attempt. Calls to bind etc
+ * made using the object reference will not be affected and continue to operate normally.
+ */
+class CustomRMIServerSocketFactory implements RMIServerSocketFactory
+{
+
+ public ServerSocket createServerSocket(int port) throws IOException
+ {
+ return new NoLocalAddressServerSocket(port);
+ }
+
+ private static class NoLocalAddressServerSocket extends ServerSocket
+ {
+ NoLocalAddressServerSocket(int port) throws IOException
+ {
+ super(port);
+ }
+
+ @Override
+ public Socket accept() throws IOException
+ {
+ Socket s = new NoLocalAddressSocket();
+ super.implAccept(s);
+ return s;
+ }
+ }
+
+ private static class NoLocalAddressSocket extends Socket
+ {
+ @Override
+ public InetAddress getInetAddress()
+ {
+ return null;
+ }
+ }
+} \ No newline at end of file
diff --git a/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXActivator.java b/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXActivator.java
deleted file mode 100644
index c588b40de7..0000000000
--- a/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXActivator.java
+++ /dev/null
@@ -1,136 +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.jmx;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-import org.apache.log4j.Logger;
-import org.apache.qpid.server.configuration.plugins.ConfigurationPluginFactory;
-import org.apache.qpid.server.registry.ApplicationRegistry;
-import org.osgi.framework.BundleActivator;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceRegistration;
-
-public class JMXActivator implements BundleActivator
-{
- private static final Logger LOGGER = Logger.getLogger(JMXActivator.class);
-
- private String _bundleName;
- private JMXService _jmxService;
-
- private List<ServiceRegistration> _registeredServices;
-
-
- public void start(final BundleContext ctx) throws Exception
- {
- boolean jmxManagementEnabled = ApplicationRegistry.getInstance().getConfiguration().getJMXManagementEnabled();
-
- if (jmxManagementEnabled)
- {
- _jmxService = new JMXService();
- startJmsService(_jmxService);
-
- _bundleName = ctx.getBundle().getSymbolicName();
-
- _registeredServices = registerServices(ctx);
- }
- else
- {
- LOGGER.debug("Skipping registration of JMX plugin as JMX Management disabled in config. ");
- }
- }
-
- public void stop(final BundleContext bundleContext) throws Exception
- {
- try
- {
- if (_jmxService != null)
- {
- if (LOGGER.isInfoEnabled())
- {
- LOGGER.info("Stopping jmx plugin: " + _bundleName);
- }
- _jmxService.close();
- }
-
- if (_registeredServices != null)
- {
- unregisterServices();
- }
- }
- finally
- {
- _jmxService = null;
- _registeredServices = null;
- }
- }
-
-
- private List<ServiceRegistration> registerServices(BundleContext ctx)
- {
- if (LOGGER.isInfoEnabled())
- {
- LOGGER.info("Registering jmx plugin: " + _bundleName);
- }
-
- List<ServiceRegistration> serviceRegistrations = new ArrayList<ServiceRegistration>();
-
- ServiceRegistration jmxServiceRegistration = ctx.registerService(JMXService.class.getName(), _jmxService, null);
- ServiceRegistration jmxConfigFactoryRegistration = ctx.registerService(ConfigurationPluginFactory.class.getName(), JMXConfiguration.FACTORY, null);
-
- serviceRegistrations.add(jmxServiceRegistration);
- serviceRegistrations.add(jmxConfigFactoryRegistration);
- return serviceRegistrations;
- }
-
- private void startJmsService(JMXService jmxService) throws Exception
- {
- if (LOGGER.isInfoEnabled())
- {
- LOGGER.info("Starting JMX service");
- }
- boolean startedSuccessfully = false;
- try
- {
- jmxService.start();
- startedSuccessfully = true;
- }
- finally
- {
- if (!startedSuccessfully)
- {
- LOGGER.error("JMX failed to start normally, closing service");
- jmxService.close();
- }
- }
- }
-
- private void unregisterServices()
- {
- for (Iterator<ServiceRegistration> iterator = _registeredServices.iterator(); iterator.hasNext();)
- {
- ServiceRegistration service = iterator.next();
- service.unregister();
- }
- }
-}
diff --git a/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXConfiguration.java b/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXConfiguration.java
deleted file mode 100644
index dc9a712f90..0000000000
--- a/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXConfiguration.java
+++ /dev/null
@@ -1,76 +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.jmx;
-
-import org.apache.commons.configuration.CompositeConfiguration;
-import org.apache.commons.configuration.Configuration;
-import org.apache.commons.configuration.ConfigurationException;
-import org.apache.commons.configuration.XMLConfiguration;
-import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin;
-import org.apache.qpid.server.configuration.plugins.ConfigurationPluginFactory;
-
-import java.util.Arrays;
-import java.util.List;
-
-public class JMXConfiguration extends ConfigurationPlugin
-{
- CompositeConfiguration _finalConfig;
-
- public static final ConfigurationPluginFactory FACTORY = new ConfigurationPluginFactory()
- {
- public ConfigurationPlugin newInstance(String path, Configuration config) throws ConfigurationException
- {
- ConfigurationPlugin instance = new JMXConfiguration();
- instance.setConfiguration(path, config);
- return instance;
- }
-
- public List<String> getParentPaths()
- {
- return Arrays.asList("jmx");
- }
- };
-
- public String[] getElementsProcessed()
- {
- return new String[] { "" };
- }
-
- public Configuration getConfiguration()
- {
- return _finalConfig;
- }
-
-
- @Override
- public void validateConfiguration() throws ConfigurationException
- {
- // Valid Configuration either has xml links to new files
- _finalConfig = new CompositeConfiguration(getConfig());
- List subFiles = getConfig().getList("xml[@fileName]");
- for (Object subFile : subFiles)
- {
- _finalConfig.addConfiguration(new XMLConfiguration((String) subFile));
- }
-
- }
-
-}
diff --git a/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagedObjectRegistry.java b/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagedObjectRegistry.java
index 0648235077..a045683de1 100644
--- a/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagedObjectRegistry.java
+++ b/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagedObjectRegistry.java
@@ -20,171 +20,114 @@
*/
package org.apache.qpid.server.jmx;
-import org.apache.commons.configuration.ConfigurationException;
import org.apache.log4j.Logger;
-import org.apache.qpid.AMQException;
+import org.apache.qpid.server.configuration.BrokerProperties;
+import org.apache.qpid.server.configuration.IllegalConfigurationException;
import org.apache.qpid.server.logging.actors.CurrentActor;
import org.apache.qpid.server.logging.messages.ManagementConsoleMessages;
-
-import org.apache.qpid.server.registry.ApplicationRegistry;
-import org.apache.qpid.server.registry.IApplicationRegistry;
+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.security.auth.rmi.RMIPasswordAuthenticator;
-import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal;
import javax.management.JMException;
import javax.management.MBeanServer;
import javax.management.MBeanServerFactory;
-import javax.management.Notification;
-import javax.management.NotificationFilterSupport;
-import javax.management.NotificationListener;
import javax.management.ObjectName;
-import javax.management.remote.JMXConnectionNotification;
import javax.management.remote.JMXConnectorServer;
import javax.management.remote.JMXServiceURL;
import javax.management.remote.MBeanServerForwarder;
-import javax.management.remote.rmi.RMIConnection;
import javax.management.remote.rmi.RMIConnectorServer;
-import javax.management.remote.rmi.RMIJRMPServerImpl;
-import javax.management.remote.rmi.RMIServerImpl;
import javax.rmi.ssl.SslRMIClientSocketFactory;
import javax.rmi.ssl.SslRMIServerSocketFactory;
-import javax.security.auth.Subject;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.management.ManagementFactory;
-import java.lang.reflect.Proxy;
import java.net.InetAddress;
import java.net.InetSocketAddress;
-import java.net.ServerSocket;
-import java.net.Socket;
import java.net.UnknownHostException;
import java.rmi.AlreadyBoundException;
import java.rmi.NoSuchObjectException;
import java.rmi.NotBoundException;
+import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.RMIClientSocketFactory;
import java.rmi.server.RMIServerSocketFactory;
import java.rmi.server.UnicastRemoteObject;
import java.util.HashMap;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
/**
- * This class starts up an MBeanserver. If out of the box agent has been enabled then there are no
+ * This class starts up an MBeanserver. If out of the box agent has been enabled then there are no
* security features implemented like user authentication and authorisation.
*/
public class JMXManagedObjectRegistry implements ManagedObjectRegistry
{
private static final Logger _log = Logger.getLogger(JMXManagedObjectRegistry.class);
+ private static final String OPERATIONAL_LOGGING_NAME = "JMX";
+
private final MBeanServer _mbeanServer;
+
private JMXConnectorServer _cs;
private Registry _rmiRegistry;
- private boolean _useCustomSocketFactory;
- private final int _jmxPortRegistryServer;
- private final int _jmxPortConnectorServer;
+ private final Broker _broker;
+ private final Port _registryPort;
+ private final Port _connectorPort;
- public JMXManagedObjectRegistry() throws AMQException
+ public JMXManagedObjectRegistry(
+ Broker broker,
+ Port connectorPort, Port registryPort,
+ JMXManagement jmxManagement)
{
- _log.info("Initialising managed object registry using platform MBean server");
- IApplicationRegistry appRegistry = ApplicationRegistry.getInstance();
+ _broker = broker;
+ _registryPort = registryPort;
+ _connectorPort = connectorPort;
- // Retrieve the config parameters
- _useCustomSocketFactory = appRegistry.getConfiguration().getUseCustomRMISocketFactory();
- boolean platformServer = appRegistry.getConfiguration().getPlatformMbeanserver();
+ boolean usePlatformServer = (Boolean)jmxManagement.getAttribute(JMXManagement.USE_PLATFORM_MBEAN_SERVER);
_mbeanServer =
- platformServer ? ManagementFactory.getPlatformMBeanServer()
+ usePlatformServer ? ManagementFactory.getPlatformMBeanServer()
: MBeanServerFactory.createMBeanServer(ManagedObject.DOMAIN);
+ }
- _jmxPortRegistryServer = appRegistry.getConfiguration().getJMXPortRegistryServer();
- _jmxPortConnectorServer = appRegistry.getConfiguration().getJMXConnectorServerPort();
-
- }
-
- public void start() throws IOException, ConfigurationException
+ @Override
+ public void start() throws IOException
{
-
- CurrentActor.get().message(ManagementConsoleMessages.STARTUP());
+ CurrentActor.get().message(ManagementConsoleMessages.STARTUP(OPERATIONAL_LOGGING_NAME));
//check if system properties are set to use the JVM's out-of-the-box JMXAgent
if (areOutOfTheBoxJMXOptionsSet())
{
- CurrentActor.get().message(ManagementConsoleMessages.READY(true));
- return;
+ CurrentActor.get().message(ManagementConsoleMessages.READY(OPERATIONAL_LOGGING_NAME));
}
+ else
+ {
+ startRegistryAndConnector();
+ }
+ }
- IApplicationRegistry appRegistry = ApplicationRegistry.getInstance();
-
-
- //Socket factories for the RMIConnectorServer, either default or SLL depending on configuration
+ private void startRegistryAndConnector() throws IOException
+ {
+ //Socket factories for the RMIConnectorServer, either default or SSL depending on configuration
RMIClientSocketFactory csf;
RMIServerSocketFactory ssf;
- //check ssl enabled option in config, default to true if option is not set
- boolean sslEnabled = appRegistry.getConfiguration().getManagementSSLEnabled();
+ //check ssl enabled option on connector port (note we don't provide ssl for registry server at
+ //moment).
+ boolean connectorSslEnabled = _connectorPort.getTransports().contains(Transport.SSL);
- if (sslEnabled)
+ if (connectorSslEnabled)
{
- //set the SSL related system properties used by the SSL RMI socket factories to the values
- //given in the configuration file, unless command line settings have already been specified
- String keyStorePath;
+ String keyStorePath = System.getProperty("javax.net.ssl.keyStore");
+ String keyStorePassword = System.getProperty("javax.net.ssl.keyStorePassword");
- if(System.getProperty("javax.net.ssl.keyStore") != null)
- {
- keyStorePath = System.getProperty("javax.net.ssl.keyStore");
- }
- else
- {
- keyStorePath = appRegistry.getConfiguration().getManagementKeyStorePath();
- }
+ validateKeyStoreProperties(keyStorePath, keyStorePassword);
- //check the keystore path value is valid
- if (keyStorePath == null)
- {
- throw new ConfigurationException("JMX management SSL keystore path not defined, " +
- "unable to start SSL protected JMX ConnectorServer");
- }
- else
- {
- //ensure the system property is set
- System.setProperty("javax.net.ssl.keyStore", keyStorePath);
-
- //check the file is usable
- File ksf = new File(keyStorePath);
-
- if (!ksf.exists())
- {
- throw new FileNotFoundException("Cannot find JMX management SSL keystore file: " + ksf);
- }
- if (!ksf.canRead())
- {
- throw new FileNotFoundException("Cannot read JMX management SSL keystore file: "
- + ksf + ". Check permissions.");
- }
-
- CurrentActor.get().message(ManagementConsoleMessages.SSL_KEYSTORE(ksf.getAbsolutePath()));
- }
-
- //check the key store password is set
- if (System.getProperty("javax.net.ssl.keyStorePassword") == null)
- {
-
- if (appRegistry.getConfiguration().getManagementKeyStorePassword() == null)
- {
- throw new ConfigurationException("JMX management SSL keystore password not defined, " +
- "unable to start requested SSL protected JMX server");
- }
- else
- {
- System.setProperty("javax.net.ssl.keyStorePassword",
- appRegistry.getConfiguration().getManagementKeyStorePassword());
- }
- }
+ CurrentActor.get().message(ManagementConsoleMessages.SSL_KEYSTORE(keyStorePath));
//create the SSL RMI socket factories
csf = new SslRMIClientSocketFactory();
@@ -197,27 +140,23 @@ public class JMXManagedObjectRegistry implements ManagedObjectRegistry
ssf = null;
}
+ int jmxPortRegistryServer = _registryPort.getPort();
+ int jmxPortConnectorServer = _connectorPort.getPort();
+
//add a JMXAuthenticator implementation the env map to authenticate the RMI based JMX connector server
- RMIPasswordAuthenticator rmipa = new RMIPasswordAuthenticator(new InetSocketAddress(_jmxPortRegistryServer));
- HashMap<String,Object> env = new HashMap<String,Object>();
- env.put(JMXConnectorServer.AUTHENTICATOR, rmipa);
+ RMIPasswordAuthenticator rmipa = new RMIPasswordAuthenticator(_broker, new InetSocketAddress(jmxPortConnectorServer));
+ HashMap<String,Object> connectorEnv = new HashMap<String,Object>();
+ connectorEnv.put(JMXConnectorServer.AUTHENTICATOR, rmipa);
+
+ System.setProperty("java.rmi.server.randomIDs", "true");
+ boolean useCustomSocketFactory = Boolean.parseBoolean(System.getProperty(BrokerProperties.PROPERTY_USE_CUSTOM_RMI_SOCKET_FACTORY, Boolean.TRUE.toString()));
/*
* Start a RMI registry on the management port, to hold the JMX RMI ConnectorServer stub.
* Using custom socket factory to prevent anyone (including us unfortunately) binding to the registry using RMI.
* As a result, only binds made using the object reference will succeed, thus securing it from external change.
*/
- System.setProperty("java.rmi.server.randomIDs", "true");
- if(_useCustomSocketFactory)
- {
- _rmiRegistry = LocateRegistry.createRegistry(_jmxPortRegistryServer, null, new CustomRMIServerSocketFactory());
- }
- else
- {
- _rmiRegistry = LocateRegistry.createRegistry(_jmxPortRegistryServer, null, null);
- }
-
- CurrentActor.get().message(ManagementConsoleMessages.LISTENING("RMI Registry", _jmxPortRegistryServer));
+ _rmiRegistry = createRmiRegistry(jmxPortRegistryServer, useCustomSocketFactory);
/*
* We must now create the RMI ConnectorServer manually, as the JMX Factory methods use RMI calls
@@ -225,57 +164,16 @@ public class JMXManagedObjectRegistry implements ManagedObjectRegistry
* locked it from any RMI based modifications, including our own. Instead, we will manually bind
* the RMIConnectorServer stub to the registry using its object reference, which will still succeed.
*
- * The registry is exported on the defined management port 'port'. We will export the RMIConnectorServer
- * on 'port +1'. Use of these two well-defined ports will ease any navigation through firewall's.
+ * The registry is exported on the defined management port 'port'.
*/
- final Map<String, String> connectionIdUsernameMap = new ConcurrentHashMap<String, String>();
- final RMIServerImpl rmiConnectorServerStub = new RMIJRMPServerImpl(_jmxPortConnectorServer, csf, ssf, env)
- {
-
- /**
- * Override makeClient so we can cache the username of the client in a Map keyed by connectionId.
- * ConnectionId is guaranteed to be unique per client connection, according to the JMS spec.
- * An instance of NotificationListener (mapCleanupListener) will be responsible for removing these Map
- * entries.
- *
- * @see javax.management.remote.rmi.RMIJRMPServerImpl#makeClient(String, javax.security.auth.Subject)
- */
- @Override
- protected RMIConnection makeClient(String connectionId, Subject subject) throws IOException
- {
- final RMIConnection makeClient = super.makeClient(connectionId, subject);
- final UsernamePrincipal usernamePrincipalFromSubject = UsernamePrincipal.getUsernamePrincipalFromSubject(subject);
- connectionIdUsernameMap.put(connectionId, usernamePrincipalFromSubject.getName());
- return makeClient;
- }
- };
-
- // Create a Listener responsible for removing the map entries add by the #makeClient entry above.
- final NotificationListener mapCleanupListener = new NotificationListener()
- {
-
- public void handleNotification(Notification notification, Object handback)
- {
- final String connectionId = ((JMXConnectionNotification) notification).getConnectionId();
- connectionIdUsernameMap.remove(connectionId);
- }
- };
+ final UsernameCachingRMIJRMPServer usernameCachingRmiServer = new UsernameCachingRMIJRMPServer(jmxPortConnectorServer, csf, ssf, connectorEnv);
- String localHost;
- try
- {
- localHost = InetAddress.getLocalHost().getHostName();
- }
- catch(UnknownHostException ex)
- {
- localHost="127.0.0.1";
- }
- final String hostname = localHost;
+ final String localHostName = getLocalhost();
final JMXServiceURL externalUrl = new JMXServiceURL(
- "service:jmx:rmi://"+hostname+":"+(_jmxPortConnectorServer)+"/jndi/rmi://"+hostname+":"+_jmxPortRegistryServer+"/jmxrmi");
+ "service:jmx:rmi://"+localHostName+":"+(jmxPortConnectorServer)+"/jndi/rmi://"+localHostName+":"+jmxPortRegistryServer+"/jmxrmi");
- final JMXServiceURL internalUrl = new JMXServiceURL("rmi", hostname, _jmxPortConnectorServer);
- _cs = new RMIConnectorServer(internalUrl, env, rmiConnectorServerStub, _mbeanServer)
+ final JMXServiceURL internalUrl = new JMXServiceURL("rmi", localHostName, jmxPortConnectorServer);
+ _cs = new RMIConnectorServer(internalUrl, connectorEnv, usernameCachingRmiServer, _mbeanServer)
{
@Override
public synchronized void start() throws IOException
@@ -283,7 +181,7 @@ public class JMXManagedObjectRegistry implements ManagedObjectRegistry
try
{
//manually bind the connector server to the registry at key 'jmxrmi', like the out-of-the-box agent
- _rmiRegistry.bind("jmxrmi", rmiConnectorServerStub);
+ _rmiRegistry.bind("jmxrmi", usernameCachingRmiServer);
}
catch (AlreadyBoundException abe)
{
@@ -311,7 +209,6 @@ public class JMXManagedObjectRegistry implements ManagedObjectRegistry
}
catch (NotBoundException nbe)
{
- // TODO consider if we want to keep new logging
_log.error("Failed to unbind jmxrmi", nbe);
//ignore
}
@@ -326,97 +223,100 @@ public class JMXManagedObjectRegistry implements ManagedObjectRegistry
//must return our pre-crafted url that includes the full details, inc JNDI details
return externalUrl;
}
-
};
-
//Add the custom invoker as an MBeanServerForwarder, and start the RMIConnectorServer.
- MBeanServerForwarder mbsf = MBeanInvocationHandlerImpl.newProxyInstance();
+ MBeanServerForwarder mbsf = MBeanInvocationHandlerImpl.newProxyInstance(_broker);
_cs.setMBeanServerForwarder(mbsf);
+ // Install a ManagementLogonLogoffReporter so we can report as users logon/logoff
+ ManagementLogonLogoffReporter jmxManagementUserLogonLogoffReporter = new ManagementLogonLogoffReporter(_broker.getRootMessageLogger(), usernameCachingRmiServer);
+ _cs.addNotificationListener(jmxManagementUserLogonLogoffReporter, jmxManagementUserLogonLogoffReporter, null);
- // Get the handler that is used by the above MBInvocationHandler Proxy.
- // which is the MBeanInvocationHandlerImpl and so also a NotificationListener.
- final NotificationListener invocationHandler = (NotificationListener) Proxy.getInvocationHandler(mbsf);
-
- // Install a notification listener on OPENED, CLOSED, and FAILED,
- // passing the map of connection-ids to usernames as hand-back data.
- final NotificationFilterSupport invocationHandlerFilter = new NotificationFilterSupport();
- invocationHandlerFilter.enableType(JMXConnectionNotification.OPENED);
- invocationHandlerFilter.enableType(JMXConnectionNotification.CLOSED);
- invocationHandlerFilter.enableType(JMXConnectionNotification.FAILED);
- _cs.addNotificationListener(invocationHandler, invocationHandlerFilter, connectionIdUsernameMap);
-
- // Install a second notification listener on CLOSED AND FAILED only to remove the entry from the
- // Map. Here we rely on the fact that JMX will call the listeners in the order in which they are
- // installed.
- final NotificationFilterSupport mapCleanupHandlerFilter = new NotificationFilterSupport();
- mapCleanupHandlerFilter.enableType(JMXConnectionNotification.CLOSED);
- mapCleanupHandlerFilter.enableType(JMXConnectionNotification.FAILED);
- _cs.addNotificationListener(mapCleanupListener, mapCleanupHandlerFilter, null);
+ // Install the usernameCachingRmiServer as a listener so it may cleanup as clients disconnect
+ _cs.addNotificationListener(usernameCachingRmiServer, usernameCachingRmiServer, null);
_cs.start();
- String connectorServer = (sslEnabled ? "SSL " : "") + "JMX RMIConnectorServer";
- CurrentActor.get().message(ManagementConsoleMessages.LISTENING(connectorServer, _jmxPortConnectorServer));
-
- CurrentActor.get().message(ManagementConsoleMessages.READY(false));
+ String connectorServer = (connectorSslEnabled ? "SSL " : "") + "JMX RMIConnectorServer";
+ CurrentActor.get().message(ManagementConsoleMessages.LISTENING(connectorServer, jmxPortConnectorServer));
+ CurrentActor.get().message(ManagementConsoleMessages.READY(OPERATIONAL_LOGGING_NAME));
}
- /*
- * Custom RMIServerSocketFactory class, used to prevent updates to the RMI registry.
- * Supplied to the registry at creation, this will prevent RMI-based operations on the
- * registry such as attempting to bind a new object, thereby securing it from tampering.
- * This is accomplished by always returning null when attempting to determine the address
- * of the caller, thus ensuring the registry will refuse the attempt. Calls to bind etc
- * made using the object reference will not be affected and continue to operate normally.
- */
-
- private static class CustomRMIServerSocketFactory implements RMIServerSocketFactory
+ private Registry createRmiRegistry(int jmxPortRegistryServer, boolean useCustomRmiRegistry)
+ throws RemoteException
{
-
- public ServerSocket createServerSocket(int port) throws IOException
+ Registry rmiRegistry;
+ if(useCustomRmiRegistry)
{
- return new NoLocalAddressServerSocket(port);
+ _log.debug("Using custom RMIServerSocketFactory");
+ rmiRegistry = LocateRegistry.createRegistry(jmxPortRegistryServer, null, new CustomRMIServerSocketFactory());
}
-
- private static class NoLocalAddressServerSocket extends ServerSocket
+ else
{
- NoLocalAddressServerSocket(int port) throws IOException
- {
- super(port);
- }
+ _log.debug("Using default RMIServerSocketFactory");
+ rmiRegistry = LocateRegistry.createRegistry(jmxPortRegistryServer, null, null);
+ }
- @Override
- public Socket accept() throws IOException
- {
- Socket s = new NoLocalAddressSocket();
- super.implAccept(s);
- return s;
- }
+ CurrentActor.get().message(ManagementConsoleMessages.LISTENING("RMI Registry", jmxPortRegistryServer));
+ return rmiRegistry;
+ }
+
+ private void validateKeyStoreProperties(String keyStorePath, String keyStorePassword) throws FileNotFoundException
+ {
+ if (keyStorePath == null)
+ {
+ throw new IllegalConfigurationException("JVM system property 'javax.net.ssl.keyStore' is not set, "
+ + "unable to start requested SSL protected JMX connector");
+ }
+ if (keyStorePassword == null)
+ {
+ throw new IllegalConfigurationException( "JVM system property 'javax.net.ssl.keyStorePassword' is not set, "
+ + "unable to start requested SSL protected JMX connector");
}
- private static class NoLocalAddressSocket extends Socket
+ File ksf = new File(keyStorePath);
+ if (!ksf.exists())
{
- @Override
- public InetAddress getInetAddress()
- {
- return null;
- }
+ throw new FileNotFoundException("Cannot find JMX management SSL keystore file: " + ksf);
+ }
+ if (!ksf.canRead())
+ {
+ throw new FileNotFoundException("Cannot read JMX management SSL keystore file: "
+ + ksf + ". Check permissions.");
}
}
-
+ @Override
public void registerObject(ManagedObject managedObject) throws JMException
{
_mbeanServer.registerMBean(managedObject, managedObject.getObjectName());
}
+ @Override
public void unregisterObject(ManagedObject managedObject) throws JMException
{
_mbeanServer.unregisterMBean(managedObject.getObjectName());
}
+ @Override
+ public void close()
+ {
+ _log.debug("close() called");
+
+ closeConnectorAndRegistryServers();
+
+ unregisterAllMbeans();
+
+ CurrentActor.get().message(ManagementConsoleMessages.STOPPED(OPERATIONAL_LOGGING_NAME));
+ }
+
+ private void closeConnectorAndRegistryServers()
+ {
+ closeConnectorServer();
+ closeRegistryServer();
+ }
+
// checks if the system properties are set which enable the JVM's out-of-the-box JMXAgent.
private boolean areOutOfTheBoxJMXOptionsSet()
{
@@ -433,29 +333,26 @@ public class JMXManagedObjectRegistry implements ManagedObjectRegistry
return false;
}
- //Stops the JMXConnectorServer and RMIRegistry, then unregisters any remaining MBeans from the MBeanServer
- public void close()
+ private String getLocalhost()
{
- _log.debug("close() called");
-
- if (_cs != null)
+ String localHost;
+ try
{
- // Stopping the JMX ConnectorServer
- try
- {
- CurrentActor.get().message(ManagementConsoleMessages.SHUTTING_DOWN("JMX RMIConnectorServer", _cs.getAddress().getPort()));
- _cs.stop();
- }
- catch (IOException e)
- {
- _log.error("Exception while closing the JMX ConnectorServer: ", e);
- }
+ localHost = InetAddress.getLocalHost().getHostName();
}
-
+ catch(UnknownHostException ex)
+ {
+ localHost="127.0.0.1";
+ }
+ return localHost;
+ }
+
+ private void closeRegistryServer()
+ {
if (_rmiRegistry != null)
{
// Stopping the RMI registry
- CurrentActor.get().message(ManagementConsoleMessages.SHUTTING_DOWN("RMI Registry", _jmxPortRegistryServer));
+ CurrentActor.get().message(ManagementConsoleMessages.SHUTTING_DOWN("RMI Registry", _registryPort.getPort()));
try
{
boolean success = UnicastRemoteObject.unexportObject(_rmiRegistry, false);
@@ -468,8 +365,36 @@ public class JMXManagedObjectRegistry implements ManagedObjectRegistry
{
_log.error("Exception while closing the RMI Registry: ", e);
}
+ finally
+ {
+ _rmiRegistry = null;
+ }
+ }
+ }
+
+ private void closeConnectorServer()
+ {
+ if (_cs != null)
+ {
+ // Stopping the JMX ConnectorServer
+ try
+ {
+ CurrentActor.get().message(ManagementConsoleMessages.SHUTTING_DOWN("JMX RMIConnectorServer", _cs.getAddress().getPort()));
+ _cs.stop();
+ }
+ catch (IOException e)
+ {
+ _log.error("Exception while closing the JMX ConnectorServer: ", e);
+ }
+ finally
+ {
+ _cs = null;
+ }
}
-
+ }
+
+ private void unregisterAllMbeans()
+ {
//ObjectName query to gather all Qpid related MBeans
ObjectName mbeanNameQuery = null;
try
@@ -492,8 +417,6 @@ public class JMXManagedObjectRegistry implements ManagedObjectRegistry
_log.error("Exception unregistering MBean '"+ name +"': " + e.getMessage());
}
}
-
- CurrentActor.get().message(ManagementConsoleMessages.STOPPED());
}
}
diff --git a/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagement.java b/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagement.java
new file mode 100644
index 0000000000..8f087ba50c
--- /dev/null
+++ b/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagement.java
@@ -0,0 +1,343 @@
+/*
+ *
+ * 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.jmx;
+
+import java.io.IOException;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.UUID;
+
+import javax.management.JMException;
+
+import org.apache.log4j.Logger;
+import org.apache.qpid.server.jmx.mbeans.LoggingManagementMBean;
+import org.apache.qpid.server.jmx.mbeans.UserManagementMBean;
+import org.apache.qpid.server.jmx.mbeans.ServerInformationMBean;
+import org.apache.qpid.server.jmx.mbeans.Shutdown;
+import org.apache.qpid.server.jmx.mbeans.VirtualHostMBean;
+import org.apache.qpid.server.logging.log4j.LoggingManagementFacade;
+import org.apache.qpid.server.model.AuthenticationProvider;
+import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.model.ConfigurationChangeListener;
+import org.apache.qpid.server.model.ConfiguredObject;
+import org.apache.qpid.server.model.PasswordCredentialManagingAuthenticationProvider;
+import org.apache.qpid.server.model.Plugin;
+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.VirtualHost;
+import org.apache.qpid.server.model.adapter.AbstractPluginAdapter;
+import org.apache.qpid.server.plugin.PluginFactory;
+import org.apache.qpid.server.plugin.QpidServiceLoader;
+import org.apache.qpid.server.util.MapValueConverter;
+
+public class JMXManagement extends AbstractPluginAdapter implements ConfigurationChangeListener
+{
+ private static final Logger LOGGER = Logger.getLogger(JMXManagement.class);
+
+ public static final String PLUGIN_TYPE = "MANAGEMENT-JMX";
+
+ // attributes
+ public static final String USE_PLATFORM_MBEAN_SERVER = "usePlatformMBeanServer";
+ public static final String NAME = "name";
+
+ // default values
+ public static final String DEFAULT_NAME = "JMXManagement";
+ public static final boolean DEFAULT_USE_PLATFORM_MBEAN_SERVER = true;
+
+ @SuppressWarnings("serial")
+ private static final Collection<String> AVAILABLE_ATTRIBUTES = Collections.unmodifiableCollection(new HashSet<String>(Plugin.AVAILABLE_ATTRIBUTES){{
+ add(NAME);
+ add(USE_PLATFORM_MBEAN_SERVER);
+ add(PluginFactory.PLUGIN_TYPE);
+ }});
+
+ @SuppressWarnings("serial")
+ private static final Map<String, Object> DEFAULTS = new HashMap<String, Object>(){{
+ put(USE_PLATFORM_MBEAN_SERVER, DEFAULT_USE_PLATFORM_MBEAN_SERVER);
+ put(NAME, DEFAULT_NAME);
+ put(PluginFactory.PLUGIN_TYPE, PLUGIN_TYPE);
+ }};
+
+ @SuppressWarnings("serial")
+ private static final Map<String, Class<?>> ATTRIBUTE_TYPES = new HashMap<String, Class<?>>(){{
+ put(USE_PLATFORM_MBEAN_SERVER, Boolean.class);
+ put(NAME, String.class);
+ put(PluginFactory.PLUGIN_TYPE, String.class);
+ }};
+
+ private final Broker _broker;
+ private JMXManagedObjectRegistry _objectRegistry;
+
+ private final Map<ConfiguredObject, AMQManagedObject> _children = new HashMap<ConfiguredObject, AMQManagedObject>();
+
+ public JMXManagement(UUID id, Broker broker, Map<String, Object> attributes)
+ {
+ super(id, DEFAULTS, MapValueConverter.convert(attributes, ATTRIBUTE_TYPES), broker.getTaskExecutor());
+ _broker = broker;
+ addParent(Broker.class, broker);
+ }
+
+ @Override
+ protected boolean setState(State currentState, State desiredState)
+ {
+ if(desiredState == State.ACTIVE)
+ {
+ try
+ {
+ start();
+ }
+ catch (JMException e)
+ {
+ throw new RuntimeException("Couldn't start JMX management", e);
+ }
+ catch (IOException e)
+ {
+ throw new RuntimeException("Couldn't start JMX management", e);
+ }
+ return true;
+ }
+ else if(desiredState == State.STOPPED)
+ {
+ stop();
+ return true;
+ }
+ return false;
+ }
+
+ private void start() throws JMException, IOException
+ {
+ Port connectorPort = null;
+ Port registryPort = null;
+ Collection<Port> ports = _broker.getPorts();
+ for (Port port : ports)
+ {
+ if (State.QUIESCED.equals(port.getActualState()))
+ {
+ continue;
+ }
+
+ if(isRegistryPort(port))
+ {
+ registryPort = port;
+ }
+ else if(isConnectorPort(port))
+ {
+ connectorPort = port;
+ }
+ }
+ if(connectorPort == null)
+ {
+ throw new IllegalStateException("No JMX connector port found supporting protocol " + Protocol.JMX_RMI);
+ }
+ if(registryPort == null)
+ {
+ throw new IllegalStateException("No JMX RMI port found supporting protocol " + Protocol.RMI);
+ }
+
+ _objectRegistry = new JMXManagedObjectRegistry(_broker, connectorPort, registryPort, this);
+
+ _broker.addChangeListener(this);
+
+ synchronized (_children)
+ {
+ for(VirtualHost virtualHost : _broker.getVirtualHosts())
+ {
+ if(!_children.containsKey(virtualHost))
+ {
+ LOGGER.debug("Create MBean for virtual host:" + virtualHost.getName());
+ VirtualHostMBean mbean = new VirtualHostMBean(virtualHost, _objectRegistry);
+ LOGGER.debug("Check for additional MBeans for virtual host:" + virtualHost.getName());
+ createAdditionalMBeansFromProviders(virtualHost, mbean);
+ }
+ }
+ Collection<AuthenticationProvider> authenticationProviders = _broker.getAuthenticationProviders();
+ for (AuthenticationProvider authenticationProvider : authenticationProviders)
+ {
+ if(authenticationProvider instanceof PasswordCredentialManagingAuthenticationProvider)
+ {
+ UserManagementMBean mbean = new UserManagementMBean(
+ (PasswordCredentialManagingAuthenticationProvider) authenticationProvider,
+ _objectRegistry);
+ _children.put(authenticationProvider, mbean);
+ }
+ }
+ }
+ new Shutdown(_objectRegistry);
+ new ServerInformationMBean(_objectRegistry, _broker);
+ if (LoggingManagementFacade.getCurrentInstance() != null)
+ {
+ new LoggingManagementMBean(LoggingManagementFacade.getCurrentInstance(), _objectRegistry);
+ }
+ _objectRegistry.start();
+ }
+
+ private boolean isConnectorPort(Port port)
+ {
+ return port.getProtocols().contains(Protocol.JMX_RMI);
+ }
+
+ private boolean isRegistryPort(Port port)
+ {
+ return port.getProtocols().contains(Protocol.RMI);
+ }
+
+ private void stop()
+ {
+ synchronized (_children)
+ {
+ for(ConfiguredObject object : _children.keySet())
+ {
+ AMQManagedObject mbean = _children.get(object);
+ if (mbean instanceof ConfigurationChangeListener)
+ {
+ object.removeChangeListener((ConfigurationChangeListener)mbean);
+ }
+ try
+ {
+ mbean.unregister();
+ }
+ catch (JMException e)
+ {
+ LOGGER.error("Error unregistering mbean", e);
+ }
+ }
+ _children.clear();
+ }
+ _broker.removeChangeListener(this);
+ _objectRegistry.close();
+ }
+
+ @Override
+ public void stateChanged(ConfiguredObject object, State oldState, State newState)
+ {
+ // no-op
+ }
+
+ @Override
+ public void childAdded(ConfiguredObject object, ConfiguredObject child)
+ {
+ synchronized (_children)
+ {
+ try
+ {
+ AMQManagedObject mbean;
+ if(child instanceof VirtualHost)
+ {
+ VirtualHost vhostChild = (VirtualHost)child;
+ mbean = new VirtualHostMBean(vhostChild, _objectRegistry);
+ }
+ else if(child instanceof PasswordCredentialManagingAuthenticationProvider)
+ {
+ mbean = new UserManagementMBean((PasswordCredentialManagingAuthenticationProvider) child, _objectRegistry);
+ }
+ else
+ {
+ mbean = null;
+ }
+
+ if (mbean != null)
+ {
+ createAdditionalMBeansFromProviders(child, mbean);
+ }
+ }
+ catch(JMException e)
+ {
+ LOGGER.error("Error creating mbean", e);
+ // TODO - Implement error reporting on mbean creation
+ }
+ }
+ }
+
+ @Override
+ public void childRemoved(ConfiguredObject object, ConfiguredObject child)
+ {
+ // TODO - implement vhost removal (possibly just removing the instanceof check below)
+
+ synchronized (_children)
+ {
+ if(child instanceof PasswordCredentialManagingAuthenticationProvider)
+ {
+ AMQManagedObject mbean = _children.remove(child);
+ if(mbean != null)
+ {
+ try
+ {
+ mbean.unregister();
+ }
+ catch(JMException e)
+ {
+ LOGGER.error("Error creating mbean", e);
+ //TODO - report error on removing child MBean
+ }
+ }
+ }
+
+ }
+ }
+
+ @Override
+ public void attributeSet(ConfiguredObject object, String attributeName, Object oldAttributeValue, Object newAttributeValue)
+ {
+ // no-op
+ }
+
+ private void createAdditionalMBeansFromProviders(ConfiguredObject child, AMQManagedObject mbean) throws JMException
+ {
+ _children.put(child, mbean);
+
+ QpidServiceLoader<MBeanProvider> qpidServiceLoader = new QpidServiceLoader<MBeanProvider>();
+ for (MBeanProvider provider : qpidServiceLoader.instancesOf(MBeanProvider.class))
+ {
+ LOGGER.debug("Consulting mbean provider : " + provider + " for child : " + child);
+ if (provider.isChildManageableByMBean(child))
+ {
+ LOGGER.debug("Provider will create mbean ");
+ provider.createMBean(child, mbean);
+ // TODO track the mbeans that have been created on behalf of a child in a map, then
+ // if the child is ever removed, destroy these beans too.
+ }
+ }
+ }
+
+ /** Added for testing purposes */
+ Broker getBroker()
+ {
+ return _broker;
+ }
+
+ @Override
+ public String getName()
+ {
+ return (String)getAttribute(NAME);
+ }
+
+ @Override
+ public Collection<String> getAttributeNames()
+ {
+ return AVAILABLE_ATTRIBUTES;
+ }
+
+}
diff --git a/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/SaslRestTest.java b/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagementFactory.java
index b504c9fa60..c2186c372b 100644
--- a/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/SaslRestTest.java
+++ b/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagementFactory.java
@@ -1,5 +1,4 @@
/*
- *
* 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
@@ -16,27 +15,35 @@
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
- *
*/
-package org.apache.qpid.server.management.plugin.servlet.rest;
+package org.apache.qpid.server.jmx;
-import java.util.List;
import java.util.Map;
+import java.util.UUID;
-public class SaslRestTest extends QpidRestTestCase
+import org.apache.log4j.Logger;
+import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.model.Plugin;
+import org.apache.qpid.server.plugin.PluginFactory;
+
+public class JMXManagementFactory implements PluginFactory
{
- public void testGet() throws Exception
- {
- Map<String, Object> saslData = getJsonAsMap("/rest/sasl");
- assertNotNull("mechanisms attribute is not found", saslData.get("mechanisms"));
+ private static final Logger LOGGER = Logger.getLogger(JMXManagementFactory.class);
- @SuppressWarnings("unchecked")
- List<String> mechanisms = (List<String>) saslData.get("mechanisms");
- String[] expectedMechanisms = { "AMQPLAIN", "PLAIN", "CRAM-MD5" };
- for (String mechanism : expectedMechanisms)
+ @Override
+ public Plugin createInstance(UUID id, Map<String, Object> attributes, Broker broker)
+ {
+ if (JMXManagement.PLUGIN_TYPE.equals(attributes.get(PLUGIN_TYPE)))
+ {
+ return new JMXManagement(id, broker, attributes);
+ }
+ else
{
- assertTrue("Mechanism " + mechanism + " is not found", mechanisms.contains(mechanism));
+ if (LOGGER.isDebugEnabled())
+ {
+ LOGGER.debug("Skipping registration of JMX plugin as JMX Management disabled in config.");
+ }
+ return null;
}
}
-
}
diff --git a/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXService.java b/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXService.java
deleted file mode 100644
index 7a232d2584..0000000000
--- a/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXService.java
+++ /dev/null
@@ -1,193 +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.jmx;
-
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.ServiceLoader;
-
-import javax.management.JMException;
-import javax.management.StandardMBean;
-
-import org.apache.commons.configuration.ConfigurationException;
-import org.apache.log4j.Logger;
-import org.apache.qpid.AMQException;
-import org.apache.qpid.server.jmx.mbeans.LoggingManagementMBean;
-import org.apache.qpid.server.jmx.mbeans.UserManagementMBean;
-import org.apache.qpid.server.jmx.mbeans.ConfigurationManagementMBean;
-import org.apache.qpid.server.jmx.mbeans.ServerInformationMBean;
-import org.apache.qpid.server.jmx.mbeans.Shutdown;
-import org.apache.qpid.server.jmx.mbeans.VirtualHostMBean;
-import org.apache.qpid.server.logging.log4j.LoggingFacade;
-import org.apache.qpid.server.model.Broker;
-import org.apache.qpid.server.model.ConfigurationChangeListener;
-import org.apache.qpid.server.model.ConfiguredObject;
-import org.apache.qpid.server.model.PasswordCredentialManagingAuthenticationProvider;
-import org.apache.qpid.server.model.State;
-import org.apache.qpid.server.model.VirtualHost;
-import org.apache.qpid.server.registry.ApplicationRegistry;
-
-
-public class JMXService implements ConfigurationChangeListener
-{
- private static final ClassLoader BUNDLE_CLASSLOADER = JMXService.class.getClassLoader();
-
- private static final Logger LOGGER = Logger.getLogger(JMXService.class);
-
- private final Broker _broker;
- private final JMXManagedObjectRegistry _objectRegistry;
- private final Shutdown _shutdown;
- private final ServerInformationMBean _serverInfo;
- private final ConfigurationManagementMBean _configManagement;
- private final LoggingManagementMBean _loggingManagement;
-
- private final Map<ConfiguredObject, AMQManagedObject> _children = new HashMap<ConfiguredObject, AMQManagedObject>();
-
- public JMXService() throws AMQException, JMException
- {
- _broker = ApplicationRegistry.getInstance().getBroker();
- _objectRegistry = new JMXManagedObjectRegistry();
-
- _broker.addChangeListener(this);
- synchronized (_children)
- {
- for(VirtualHost virtualHost : _broker.getVirtualHosts())
- {
- if(!_children.containsKey(virtualHost))
- {
- _children.put(virtualHost, new VirtualHostMBean(virtualHost, _objectRegistry));
- }
- }
- }
- _shutdown = new Shutdown(_objectRegistry);
- _serverInfo = new ServerInformationMBean(_objectRegistry, _broker);
- _configManagement = new ConfigurationManagementMBean(_objectRegistry);
- _loggingManagement = new LoggingManagementMBean(LoggingFacade.getCurrentInstance(), _objectRegistry);
- }
-
- public void start() throws IOException, ConfigurationException
- {
- _objectRegistry.start();
- }
-
- public void close()
- {
- _broker.removeChangeListener(this);
-
- _objectRegistry.close();
- }
-
- public void stateChanged(ConfiguredObject object, State oldState, State newState)
- {
-
- }
-
- public void childAdded(ConfiguredObject object, ConfiguredObject child)
- {
- synchronized (_children)
- {
- try
- {
- AMQManagedObject mbean;
- if(child instanceof VirtualHost)
- {
- VirtualHost vhostChild = (VirtualHost)child;
- mbean = new VirtualHostMBean(vhostChild, _objectRegistry);
- }
- else if(child instanceof PasswordCredentialManagingAuthenticationProvider)
- {
- mbean = new UserManagementMBean((PasswordCredentialManagingAuthenticationProvider) child, _objectRegistry);
- }
- else
- {
- mbean = null;
- }
-
- if (mbean != null)
- {
- createAdditionalMBeansFromProviders(child, mbean);
- }
- }
- catch(JMException e)
- {
- LOGGER.error("Error creating mbean", e);
- // TODO - Implement error reporting on mbean creation
- }
- }
- }
-
-
- public void childRemoved(ConfiguredObject object, ConfiguredObject child)
- {
- // TODO - implement vhost removal (possibly just removing the instanceof check below)
-
- synchronized (_children)
- {
- if(child instanceof PasswordCredentialManagingAuthenticationProvider)
- {
- AMQManagedObject mbean = _children.remove(child);
- if(mbean != null)
- {
- try
- {
- mbean.unregister();
- }
- catch(JMException e)
- {
- LOGGER.error("Error creating mbean", e);
- //TODO - report error on removing child MBean
- }
- }
- }
-
- }
- }
-
- private void createAdditionalMBeansFromProviders(ConfiguredObject child, AMQManagedObject mbean) throws JMException
- {
- _children.put(child, mbean);
-
- for (Iterator<MBeanProvider> iterator = getMBeanProviderIterator(); iterator.hasNext();)
- {
- MBeanProvider provider = iterator.next();
- LOGGER.debug("Consulting mbean provider : " + provider + " for child : " + child);
- if (provider.isChildManageableByMBean(child))
- {
- LOGGER.debug("Provider will create mbean ");
- StandardMBean bean = provider.createMBean(child, mbean);
- // TODO track the mbeans that have been created on behalf of a child in a map, then
- // if the child is ever removed, destroy these beans too.
- }
- }
- }
-
- /**
- * Finds all classes implementing the {@link MBeanProvider} interface. This will find
- * <b>only</b> those classes which are visible to the classloader of this OSGI bundle.
- */
- private Iterator<MBeanProvider> getMBeanProviderIterator()
- {
- return ServiceLoader.load(MBeanProvider.class, BUNDLE_CLASSLOADER).iterator();
- }
-}
diff --git a/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/MBeanInvocationHandlerImpl.java b/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/MBeanInvocationHandlerImpl.java
index a2a0d2d093..8bc2afb176 100644
--- a/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/MBeanInvocationHandlerImpl.java
+++ b/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/MBeanInvocationHandlerImpl.java
@@ -22,26 +22,22 @@ package org.apache.qpid.server.jmx;
import org.apache.log4j.Logger;
-import org.apache.qpid.server.logging.LogActor;
+import org.apache.qpid.server.configuration.BrokerProperties;
import org.apache.qpid.server.logging.actors.CurrentActor;
import org.apache.qpid.server.logging.actors.ManagementActor;
-import org.apache.qpid.server.logging.messages.ManagementConsoleMessages;
-import org.apache.qpid.server.registry.ApplicationRegistry;
-import org.apache.qpid.server.registry.IApplicationRegistry;
+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.security.access.Operation;
+import org.apache.qpid.server.security.auth.AuthenticatedPrincipal;
import javax.management.Attribute;
import javax.management.JMException;
import javax.management.MBeanInfo;
import javax.management.MBeanOperationInfo;
import javax.management.MBeanServer;
-import javax.management.Notification;
-import javax.management.NotificationListener;
import javax.management.ObjectName;
import javax.management.RuntimeErrorException;
-import javax.management.remote.JMXConnectionNotification;
-import javax.management.remote.JMXPrincipal;
import javax.management.remote.MBeanServerForwarder;
import javax.security.auth.Subject;
import java.lang.reflect.InvocationHandler;
@@ -51,27 +47,32 @@ import java.lang.reflect.Proxy;
import java.security.AccessControlContext;
import java.security.AccessController;
import java.util.Arrays;
-import java.util.Map;
-import java.util.Set;
/**
* This class can be used by the JMXConnectorServer as an InvocationHandler for the mbean operations. It delegates
* JMX access decisions to the SecurityPlugin.
*/
-public class MBeanInvocationHandlerImpl implements InvocationHandler, NotificationListener
+public class MBeanInvocationHandlerImpl implements InvocationHandler
{
private static final Logger _logger = Logger.getLogger(MBeanInvocationHandlerImpl.class);
- private final IApplicationRegistry _appRegistry = ApplicationRegistry.getInstance();
private final static String DELEGATE = "JMImplementation:type=MBeanServerDelegate";
private MBeanServer _mbs;
- private final ManagementActor _logActor = new ManagementActor(_appRegistry.getRootMessageLogger());
- private final boolean _managementRightsInferAllAccess =
- _appRegistry.getConfiguration().getManagementRightsInferAllAccess();
+ private final ManagementActor _logActor;
- public static MBeanServerForwarder newProxyInstance()
+ private final boolean _managementRightsInferAllAccess;
+ private final Broker _broker;
+
+ MBeanInvocationHandlerImpl(Broker broker)
+ {
+ _managementRightsInferAllAccess = Boolean.valueOf(System.getProperty(BrokerProperties.PROPERTY_MANAGEMENT_RIGHTS_INFER_ALL_ACCESS, "true"));
+ _broker = broker;
+ _logActor = new ManagementActor(broker.getRootMessageLogger());
+ }
+
+ public static MBeanServerForwarder newProxyInstance(Broker broker)
{
- final InvocationHandler handler = new MBeanInvocationHandlerImpl();
+ final InvocationHandler handler = new MBeanInvocationHandlerImpl(broker);
final Class<?>[] interfaces = new Class[] { MBeanServerForwarder.class };
Object proxy = Proxy.newProxyInstance(MBeanServerForwarder.class.getClassLoader(), interfaces, handler);
@@ -101,7 +102,7 @@ public class MBeanInvocationHandlerImpl implements InvocationHandler, Notificati
{
ObjectName mbean = (ObjectName) args[0];
- if(!DefaultManagedObject.DOMAIN.equalsIgnoreCase(mbean.getDomain()))
+ if(!ManagedObject.DOMAIN.equalsIgnoreCase(mbean.getDomain()))
{
return true;
}
@@ -151,11 +152,13 @@ public class MBeanInvocationHandlerImpl implements InvocationHandler, Notificati
return method.invoke(_mbs, args);
}
- // Retrieve JMXPrincipal from Subject
- Set<JMXPrincipal> principals = subject.getPrincipals(JMXPrincipal.class);
- if (principals == null || principals.isEmpty())
+ try
+ {
+ AuthenticatedPrincipal.getAuthenticatedPrincipalFromSubject(subject);
+ }
+ catch(Exception e)
{
- throw new SecurityException("Access denied: no JMX principal");
+ throw new SecurityException("Access denied: no authenticated principal", e);
}
// Save the subject
@@ -211,11 +214,16 @@ public class MBeanInvocationHandlerImpl implements InvocationHandler, Notificati
SecurityManager security;
if (vhost == null)
{
- security = _appRegistry.getSecurityManager();
+ security = _broker.getSecurityManager();
}
else
{
- security = _appRegistry.getVirtualHostRegistry().getVirtualHost(vhost).getSecurityManager();
+ VirtualHost virtualHost = _broker.findVirtualHostByName(vhost);
+ if (virtualHost == null)
+ {
+ throw new IllegalArgumentException("Virtual host with name '" + vhost + "' is not found.");
+ }
+ security = virtualHost.getSecurityManager();
}
methodName = getMethodName(method, args);
@@ -360,50 +368,5 @@ public class MBeanInvocationHandlerImpl implements InvocationHandler, Notificati
return (methodName.startsWith("query") || methodName.startsWith("get") || methodName.startsWith("is"));
}
- /**
- * Receives notifications from the MBeanServer.
- */
- public void handleNotification(final Notification notification, final Object handback)
- {
- assert notification instanceof JMXConnectionNotification;
-
- final String connectionId = ((JMXConnectionNotification) notification).getConnectionId();
- final String type = notification.getType();
-
- if (_logger.isDebugEnabled())
- {
- _logger.debug("Notification connectionId : " + connectionId + " type : " + type
- + " Notification handback : " + handback);
- }
-
- // Normally JMXManagedObjectRegistry provides a Map as handback data containing a map
- // between connection id and username.
- String user = null;
- if (handback instanceof Map)
- {
- final Map<String, String> connectionIdUsernameMap = (Map<String, String>) handback;
- user = connectionIdUsernameMap.get(connectionId);
- }
-
- // If user is still null, fallback to an unordered list of Principals from the connection id.
- if (user == null)
- {
- final String[] splitConnectionId = connectionId.split(" ");
- user = splitConnectionId[1];
- }
-
- // use a separate instance of actor as subject is not set on connect/disconnect
- // we need to pass principal name explicitly into log actor
- LogActor logActor = new ManagementActor(_appRegistry.getRootMessageLogger(), user);
- if (JMXConnectionNotification.OPENED.equals(type))
- {
- logActor.message(ManagementConsoleMessages.OPEN(user));
- }
- else if (JMXConnectionNotification.CLOSED.equals(type) ||
- JMXConnectionNotification.FAILED.equals(type))
- {
- logActor.message(ManagementConsoleMessages.CLOSE(user));
- }
- }
}
diff --git a/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/MBeanProvider.java b/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/MBeanProvider.java
index 83909dbe72..b80ddc7fac 100644
--- a/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/MBeanProvider.java
+++ b/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/MBeanProvider.java
@@ -21,17 +21,16 @@
package org.apache.qpid.server.jmx;
-import java.util.ServiceLoader;
-
import javax.management.JMException;
import javax.management.StandardMBean;
import org.apache.qpid.server.model.ConfiguredObject;
+import org.apache.qpid.server.plugin.QpidServiceLoader;
/**
* A provider of an mbean implementation.
*
- * Provider implementations are advertised as services and loaded via {@link ServiceLoader}.
+ * Provider implementations are advertised as services and loaded by a {@link QpidServiceLoader}.
*/
public interface MBeanProvider
{
diff --git a/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/ManagementLogonLogoffReporter.java b/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/ManagementLogonLogoffReporter.java
new file mode 100644
index 0000000000..ae0574dc21
--- /dev/null
+++ b/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/ManagementLogonLogoffReporter.java
@@ -0,0 +1,95 @@
+/*
+ * 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.jmx;
+
+import static javax.management.remote.JMXConnectionNotification.CLOSED;
+import static javax.management.remote.JMXConnectionNotification.FAILED;
+import static javax.management.remote.JMXConnectionNotification.OPENED;
+
+import javax.management.Notification;
+import javax.management.NotificationFilter;
+import javax.management.NotificationListener;
+import javax.management.remote.JMXConnectionNotification;
+
+import org.apache.log4j.Logger;
+import org.apache.qpid.server.logging.LogActor;
+import org.apache.qpid.server.logging.RootMessageLogger;
+import org.apache.qpid.server.logging.actors.ManagementActor;
+import org.apache.qpid.server.logging.messages.ManagementConsoleMessages;
+
+public class ManagementLogonLogoffReporter implements NotificationListener, NotificationFilter
+{
+ private static final Logger LOGGER = Logger.getLogger(ManagementLogonLogoffReporter.class);
+ private final RootMessageLogger _rootMessageLogger;
+ private final UsernameAccessor _usernameAccessor;
+
+ public ManagementLogonLogoffReporter(RootMessageLogger rootMessageLogger, UsernameAccessor usernameAccessor)
+ {
+ _rootMessageLogger = rootMessageLogger;
+ _usernameAccessor = usernameAccessor;
+ }
+
+ @Override
+ public void handleNotification(final Notification notification, final Object handback)
+ {
+ final String connectionId = ((JMXConnectionNotification) notification).getConnectionId();
+ final String type = notification.getType();
+
+ if (LOGGER.isDebugEnabled())
+ {
+ LOGGER.debug("Notification connectionId : " + connectionId + " type : " + type);
+ }
+
+ String user = _usernameAccessor.getUsernameForConnectionId(connectionId);
+
+ // If user is still null, fallback to an unordered list of Principals from the connection id.
+ if (user == null)
+ {
+ final String[] splitConnectionId = connectionId.split(" ");
+ user = splitConnectionId[1];
+ }
+
+ // use a separate instance of actor as subject is not set on connect/disconnect
+ // we need to pass principal name explicitly into log actor
+ LogActor logActor = new ManagementActor(_rootMessageLogger, user);
+ if (JMXConnectionNotification.OPENED.equals(type))
+ {
+ logActor.message(ManagementConsoleMessages.OPEN(user));
+ }
+ else if (JMXConnectionNotification.CLOSED.equals(type) ||
+ JMXConnectionNotification.FAILED.equals(type))
+ {
+ logActor.message(ManagementConsoleMessages.CLOSE(user));
+ }
+ }
+
+ @Override
+ public boolean isNotificationEnabled(Notification notification)
+ {
+ return notification instanceof JMXConnectionNotification && isLogonTypeEvent(notification);
+ }
+
+ private boolean isLogonTypeEvent(Notification notification)
+ {
+ final String type = notification.getType();
+ return CLOSED.equals(type) || FAILED.equals(type) || OPENED.equals(type);
+ }
+
+}
diff --git a/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/UsernameAccessor.java b/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/UsernameAccessor.java
new file mode 100644
index 0000000000..0cbb0d2687
--- /dev/null
+++ b/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/UsernameAccessor.java
@@ -0,0 +1,26 @@
+/*
+ * 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.jmx;
+
+public interface UsernameAccessor
+{
+ public String getUsernameForConnectionId(String connectionId);
+
+}
diff --git a/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/UsernameCachingRMIJRMPServer.java b/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/UsernameCachingRMIJRMPServer.java
new file mode 100644
index 0000000000..838e9e5664
--- /dev/null
+++ b/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/UsernameCachingRMIJRMPServer.java
@@ -0,0 +1,100 @@
+/*
+ * 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.jmx;
+
+import static javax.management.remote.JMXConnectionNotification.CLOSED;
+import static javax.management.remote.JMXConnectionNotification.FAILED;
+
+import java.io.IOException;
+import java.rmi.server.RMIClientSocketFactory;
+import java.rmi.server.RMIServerSocketFactory;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import javax.management.Notification;
+import javax.management.NotificationFilter;
+import javax.management.NotificationListener;
+import javax.management.remote.JMXConnectionNotification;
+import javax.management.remote.JMXConnectorServer;
+import javax.management.remote.rmi.RMIConnection;
+import javax.management.remote.rmi.RMIJRMPServerImpl;
+import javax.security.auth.Subject;
+
+import org.apache.qpid.server.security.auth.AuthenticatedPrincipal;
+
+/**
+ * An implementation of RMIJRMPServerImpl that caches the usernames of users as they log-on
+ * and makes the same available via {@link UsernameAccessor#getUsernameForConnectionId(String)}.
+ *
+ * Caller is responsible for installing this object as a {@link NotificationListener} of the
+ * {@link JMXConnectorServer} so the cache entries are removed as the clients disconnect.
+ *
+ */
+public class UsernameCachingRMIJRMPServer extends RMIJRMPServerImpl implements NotificationListener, NotificationFilter, UsernameAccessor
+{
+ // ConnectionId is guaranteed to be unique per client connection, according to the JMX spec.
+ private final Map<String, String> _connectionIdUsernameMap = new ConcurrentHashMap<String, String>();
+
+ UsernameCachingRMIJRMPServer(int port, RMIClientSocketFactory csf, RMIServerSocketFactory ssf,
+ Map<String, ?> env) throws IOException
+ {
+ super(port, csf, ssf, env);
+ }
+
+ @Override
+ protected RMIConnection makeClient(String connectionId, Subject subject) throws IOException
+ {
+ final RMIConnection makeClient = super.makeClient(connectionId, subject);
+ final AuthenticatedPrincipal authenticatedPrincipalFromSubject = AuthenticatedPrincipal.getAuthenticatedPrincipalFromSubject(subject);
+ _connectionIdUsernameMap.put(connectionId, authenticatedPrincipalFromSubject.getName());
+ return makeClient;
+ }
+
+ @Override
+ public String getUsernameForConnectionId(String connectionId)
+ {
+ return _connectionIdUsernameMap.get(connectionId);
+ }
+
+ @Override
+ public void handleNotification(Notification notification, Object handback)
+ {
+ final String connectionId = ((JMXConnectionNotification) notification).getConnectionId();
+ removeConnectionIdFromCache(connectionId);
+ }
+
+ @Override
+ public boolean isNotificationEnabled(Notification notification)
+ {
+ return isClientDisconnectEvent(notification);
+ }
+
+ private void removeConnectionIdFromCache(String connectionId)
+ {
+ _connectionIdUsernameMap.remove(connectionId);
+ }
+
+ private boolean isClientDisconnectEvent(Notification notification)
+ {
+ final String type = notification.getType();
+ return CLOSED.equals(type) || FAILED.equals(type);
+ }
+
+} \ No newline at end of file
diff --git a/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/mbeans/ConfigurationManagementMBean.java b/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/mbeans/ConfigurationManagementMBean.java
deleted file mode 100644
index beffb4eaa9..0000000000
--- a/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/mbeans/ConfigurationManagementMBean.java
+++ /dev/null
@@ -1,56 +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.jmx.mbeans;
-
-import org.apache.qpid.management.common.mbeans.ConfigurationManagement;
-import org.apache.qpid.server.jmx.AMQManagedObject;
-import org.apache.qpid.server.jmx.ManagedObject;
-import org.apache.qpid.server.jmx.ManagedObjectRegistry;
-import org.apache.qpid.server.registry.ApplicationRegistry;
-
-import javax.management.JMException;
-import javax.management.NotCompliantMBeanException;
-
-public class ConfigurationManagementMBean extends AMQManagedObject implements ConfigurationManagement
-{
-
- public ConfigurationManagementMBean(ManagedObjectRegistry registry) throws JMException
- {
- super(ConfigurationManagement.class, ConfigurationManagement.TYPE, registry);
- register();
- }
-
- public String getObjectInstanceName()
- {
- return ConfigurationManagement.TYPE;
- }
-
- public void reloadSecurityConfiguration() throws Exception
- {
- ApplicationRegistry.getInstance().getConfiguration().reparseConfigFileSecuritySections();
- }
-
- @Override
- public ManagedObject getParentObject()
- {
- return null;
- }
-}
diff --git a/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/mbeans/LoggingManagementMBean.java b/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/mbeans/LoggingManagementMBean.java
index 0dac8ebe37..d6f4b5d8c9 100644
--- a/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/mbeans/LoggingManagementMBean.java
+++ b/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/mbeans/LoggingManagementMBean.java
@@ -26,7 +26,7 @@ import org.apache.qpid.management.common.mbeans.annotations.MBeanDescription;
import org.apache.qpid.server.jmx.AMQManagedObject;
import org.apache.qpid.server.jmx.ManagedObject;
import org.apache.qpid.server.jmx.ManagedObjectRegistry;
-import org.apache.qpid.server.logging.log4j.LoggingFacade;
+import org.apache.qpid.server.logging.log4j.LoggingManagementFacade;
import org.apache.qpid.server.logging.log4j.LoggingFacadeException;
import javax.management.JMException;
@@ -55,7 +55,8 @@ public class LoggingManagementMBean extends AMQManagedObject implements LoggingM
private static final TabularType LOGGER_LEVEL_TABULAR_TYE;
private static final CompositeType LOGGER_LEVEL_COMPOSITE_TYPE;
- private final LoggingFacade _configurator;
+ private final LoggingManagementFacade _loggingManagementFacade;
+ private final String[] _allAvailableLogLevels;
static
{
@@ -77,12 +78,13 @@ public class LoggingManagementMBean extends AMQManagedObject implements LoggingM
throw new ExceptionInInitializerError(e);
}
}
-
- public LoggingManagementMBean(LoggingFacade configurator, ManagedObjectRegistry registry) throws JMException
+
+ public LoggingManagementMBean(LoggingManagementFacade loggingManagementFacade, ManagedObjectRegistry registry) throws JMException
{
super(LoggingManagement.class, LoggingManagement.TYPE, registry);
register();
- _configurator = configurator;
+ _loggingManagementFacade = loggingManagementFacade;
+ _allAvailableLogLevels = buildAllAvailableLoggerLevelsWithInheritedPsuedoLogLevel(_loggingManagementFacade);
}
@Override
@@ -100,30 +102,26 @@ public class LoggingManagementMBean extends AMQManagedObject implements LoggingM
@Override
public Integer getLog4jLogWatchInterval()
{
- return _configurator.getLog4jLogWatchInterval();
+ return _loggingManagementFacade.getLog4jLogWatchInterval();
}
@Override
public String[] getAvailableLoggerLevels()
{
- List<String> levels = _configurator.getAvailableLoggerLevels();
- List<String> mbeanLevels = new ArrayList<String>(levels);
- mbeanLevels.add(INHERITED_PSUEDO_LOG_LEVEL);
-
- return mbeanLevels.toArray(new String[mbeanLevels.size()]);
+ return _allAvailableLogLevels;
}
@Override
public TabularData viewEffectiveRuntimeLoggerLevels()
{
- Map<String, String> levels = _configurator.retrieveRuntimeLoggersLevels();
+ Map<String, String> levels = _loggingManagementFacade.retrieveRuntimeLoggersLevels();
return createTabularDataFromLevelsMap(levels);
}
@Override
public String getRuntimeRootLoggerLevel()
{
- return _configurator.retrieveRuntimeRootLoggerLevel();
+ return _loggingManagementFacade.retrieveRuntimeRootLoggerLevel();
}
@Override
@@ -139,7 +137,7 @@ public class LoggingManagementMBean extends AMQManagedObject implements LoggingM
return false;
}
- _configurator.setRuntimeRootLoggerLevel(level);
+ _loggingManagementFacade.setRuntimeRootLoggerLevel(level);
return true;
}
@@ -159,7 +157,7 @@ public class LoggingManagementMBean extends AMQManagedObject implements LoggingM
try
{
- _configurator.setRuntimeLoggerLevel(logger, validatedLevel);
+ _loggingManagementFacade.setRuntimeLoggerLevel(logger, validatedLevel);
}
catch (LoggingFacadeException e)
{
@@ -175,7 +173,7 @@ public class LoggingManagementMBean extends AMQManagedObject implements LoggingM
Map<String,String> levels;
try
{
- levels = _configurator.retrieveConfigFileLoggersLevels();
+ levels = _loggingManagementFacade.retrieveConfigFileLoggersLevels();
}
catch (LoggingFacadeException e)
{
@@ -191,7 +189,7 @@ public class LoggingManagementMBean extends AMQManagedObject implements LoggingM
{
try
{
- return _configurator.retrieveConfigFileRootLoggerLevel().toUpperCase();
+ return _loggingManagementFacade.retrieveConfigFileRootLoggerLevel().toUpperCase();
}
catch (LoggingFacadeException e)
{
@@ -216,7 +214,7 @@ public class LoggingManagementMBean extends AMQManagedObject implements LoggingM
try
{
- _configurator.setConfigFileLoggerLevel(logger, validatedLevel);
+ _loggingManagementFacade.setConfigFileLoggerLevel(logger, validatedLevel);
}
catch (LoggingFacadeException e)
{
@@ -241,7 +239,7 @@ public class LoggingManagementMBean extends AMQManagedObject implements LoggingM
try
{
- _configurator.setConfigFileRootLoggerLevel(level);
+ _loggingManagementFacade.setConfigFileRootLoggerLevel(level);
return true;
}
catch (LoggingFacadeException e)
@@ -257,7 +255,7 @@ public class LoggingManagementMBean extends AMQManagedObject implements LoggingM
try
{
- _configurator.reload();
+ _loggingManagementFacade.reload();
}
catch (LoggingFacadeException e)
{
@@ -283,9 +281,8 @@ public class LoggingManagementMBean extends AMQManagedObject implements LoggingM
private void validateLevelNotAllowingInherited(String level)
{
- final List<String> availableLoggerLevels = _configurator.getAvailableLoggerLevels();
- if (!availableLoggerLevels.contains(level)
- && !availableLoggerLevels.contains(String.valueOf(level).toUpperCase()))
+ final List<String> availableLoggerLevels = _loggingManagementFacade.getAvailableLoggerLevels();
+ if (level == null || !availableLoggerLevels.contains(level.toUpperCase()))
{
throw new IllegalArgumentException(level + " not known");
}
@@ -305,7 +302,6 @@ public class LoggingManagementMBean extends AMQManagedObject implements LoggingM
return loggerLevelList;
}
-
private CompositeData createRow(String loggerName, String level)
{
Object[] itemData = {loggerName, level.toUpperCase()};
@@ -321,4 +317,13 @@ public class LoggingManagementMBean extends AMQManagedObject implements LoggingM
throw new RuntimeException(ode);
}
}
+
+ private String[] buildAllAvailableLoggerLevelsWithInheritedPsuedoLogLevel(LoggingManagementFacade loggingManagementFacade)
+ {
+ List<String> levels = loggingManagementFacade.getAvailableLoggerLevels();
+ List<String> mbeanLevels = new ArrayList<String>(levels);
+ mbeanLevels.add(INHERITED_PSUEDO_LOG_LEVEL);
+
+ return mbeanLevels.toArray(new String[mbeanLevels.size()]);
+ }
}
diff --git a/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/mbeans/QueueMBean.java b/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/mbeans/QueueMBean.java
index 5c8b0f7194..94fac218ff 100644
--- a/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/mbeans/QueueMBean.java
+++ b/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/mbeans/QueueMBean.java
@@ -513,7 +513,6 @@ public class QueueMBean extends AMQManagedObject implements ManagedQueue, QueueN
{
_queue.visit(new QueueEntryVisitor()
{
-
public boolean visit(final QueueEntry entry)
{
final ServerMessage message = entry.getMessage();
@@ -525,11 +524,9 @@ public class QueueMBean extends AMQManagedObject implements ManagedQueue, QueueN
&& (messageId <= toMessageId))
{
txn.dequeue(entry);
- return true;
}
- return false;
}
- return true;
+ return false;
}
});
}
diff --git a/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/mbeans/VirtualHostMBean.java b/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/mbeans/VirtualHostMBean.java
index 6990a40dee..51dea92775 100644
--- a/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/mbeans/VirtualHostMBean.java
+++ b/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/mbeans/VirtualHostMBean.java
@@ -65,7 +65,7 @@ public class VirtualHostMBean extends AMQManagedObject implements ManagedVirtual
_managerMBean = new VirtualHostManagerMBean(this);
}
- private void initQueues() throws JMException
+ private void initQueues()
{
synchronized (_children)
{
@@ -73,13 +73,20 @@ public class VirtualHostMBean extends AMQManagedObject implements ManagedVirtual
{
if(!_children.containsKey(queue))
{
- _children.put(queue, new QueueMBean(queue, this));
+ try
+ {
+ _children.put(queue, new QueueMBean(queue, this));
+ }
+ catch(Exception e)
+ {
+ LOGGER.error("Cannot create queue mbean for queue " + queue.getName(), e);
+ }
}
}
}
}
- private void initExchanges() throws JMException
+ private void initExchanges()
{
synchronized (_children)
{
@@ -87,13 +94,20 @@ public class VirtualHostMBean extends AMQManagedObject implements ManagedVirtual
{
if(!_children.containsKey(exchange))
{
- _children.put(exchange, new ExchangeMBean(exchange, this));
+ try
+ {
+ _children.put(exchange, new ExchangeMBean(exchange, this));
+ }
+ catch(Exception e)
+ {
+ LOGGER.error("Cannot create exchange mbean for exchange " + exchange.getName(), e);
+ }
}
}
}
}
- private void initConnections() throws JMException
+ private void initConnections()
{
synchronized (_children)
{
@@ -101,7 +115,14 @@ public class VirtualHostMBean extends AMQManagedObject implements ManagedVirtual
{
if(!_children.containsKey(conn))
{
- _children.put(conn, new ConnectionMBean(conn, this));
+ try
+ {
+ _children.put(conn, new ConnectionMBean(conn, this));
+ }
+ catch(Exception e)
+ {
+ LOGGER.error("Cannot create connection mbean for connection " + conn.getName(), e);
+ }
}
}
}
@@ -119,7 +140,7 @@ public class VirtualHostMBean extends AMQManagedObject implements ManagedVirtual
public void stateChanged(ConfiguredObject object, State oldState, State newState)
{
- // ignore
+ // no-op
}
public void childAdded(ConfiguredObject object, ConfiguredObject child)
@@ -208,4 +229,35 @@ public class VirtualHostMBean extends AMQManagedObject implements ManagedVirtual
return queues;
}
+
+ @Override
+ public void unregister() throws JMException
+ {
+ synchronized (_children)
+ {
+ for (AMQManagedObject mbean : _children.values())
+ {
+ if(mbean != null)
+ {
+ try
+ {
+ mbean.unregister();
+ }
+ catch(JMException e)
+ {
+ LOGGER.error("Failed to remove mbean for child : " + mbean, e);
+ }
+ }
+ }
+ _children.clear();
+ }
+ _managerMBean.unregister();
+ }
+
+ @Override
+ public void attributeSet(ConfiguredObject object, String attributeName, Object oldAttributeValue, Object newAttributeValue)
+ {
+ // no-op
+ }
+
}
diff --git a/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/mbeans/VirtualHostManagerMBean.java b/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/mbeans/VirtualHostManagerMBean.java
index b3dbbc424a..67ac1bdc7c 100644
--- a/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/mbeans/VirtualHostManagerMBean.java
+++ b/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/mbeans/VirtualHostManagerMBean.java
@@ -229,10 +229,9 @@ public class VirtualHostManagerMBean extends AbstractStatisticsGatheringMBean<Vi
return getObjectNameForSingleInstanceMBean();
}
- public synchronized boolean isStatisticsEnabled()
+ public boolean isStatisticsEnabled()
{
- updateStats();
- return false; //TODO - implement isStatisticsEnabled
+ return true;
}
}
diff --git a/java/broker-plugins/management-jmx/src/main/resources/META-INF/services/org.apache.qpid.server.plugin.PluginFactory b/java/broker-plugins/management-jmx/src/main/resources/META-INF/services/org.apache.qpid.server.plugin.PluginFactory
new file mode 100644
index 0000000000..8fa778269e
--- /dev/null
+++ b/java/broker-plugins/management-jmx/src/main/resources/META-INF/services/org.apache.qpid.server.plugin.PluginFactory
@@ -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.
+#
+org.apache.qpid.server.jmx.JMXManagementFactory
diff --git a/java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/server/jmx/JMXManagementFactoryTest.java b/java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/server/jmx/JMXManagementFactoryTest.java
new file mode 100644
index 0000000000..5af1369239
--- /dev/null
+++ b/java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/server/jmx/JMXManagementFactoryTest.java
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.qpid.server.jmx;
+
+import static org.mockito.Mockito.mock;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.plugin.PluginFactory;
+import org.apache.qpid.test.utils.QpidTestCase;
+
+public class JMXManagementFactoryTest extends QpidTestCase
+{
+ private final JMXManagementFactory _jmxManagementFactory = new JMXManagementFactory();
+ private final Map<String, Object> _attributes = new HashMap<String, Object>();
+ private final Broker _broker = mock(Broker.class);
+ private UUID _id = UUID.randomUUID();
+
+ public void testJMXConfigured() throws Exception
+ {
+ _attributes.put(PluginFactory.PLUGIN_TYPE, JMXManagement.PLUGIN_TYPE);
+
+ JMXManagement jmxManagement = (JMXManagement) _jmxManagementFactory.createInstance(_id, _attributes, _broker);
+
+ assertNotNull(jmxManagement);
+ assertEquals("Unexpected plugin type", JMXManagement.PLUGIN_TYPE, jmxManagement.getAttribute(JMXManagementFactory.PLUGIN_TYPE));
+ assertEquals("Unexpected default mbean platform", JMXManagement.DEFAULT_USE_PLATFORM_MBEAN_SERVER, jmxManagement.getAttribute(JMXManagement.USE_PLATFORM_MBEAN_SERVER));
+ assertEquals("Unexpected default name", JMXManagement.DEFAULT_NAME, jmxManagement.getAttribute(JMXManagement.NAME));
+ }
+
+ public void testCreateInstanceReturnsNullWhenPluginTypeMissing()
+ {
+ assertNull(_jmxManagementFactory.createInstance(_id, _attributes, _broker));
+ }
+
+ public void testCreateInstanceReturnsNullWhenPluginTypeNotJmx()
+ {
+ _attributes.put(PluginFactory.PLUGIN_TYPE, "notJmx");
+ assertNull(_jmxManagementFactory.createInstance(_id, _attributes, _broker));
+ }
+}
diff --git a/java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/server/jmx/ManagementLogActorTest.java b/java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/server/jmx/ManagementLogActorTest.java
deleted file mode 100644
index c1df9afc5d..0000000000
--- a/java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/server/jmx/ManagementLogActorTest.java
+++ /dev/null
@@ -1,170 +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.jmx;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.management.JMException;
-import javax.management.MBeanServerConnection;
-import javax.management.ObjectName;
-import javax.management.remote.JMXConnector;
-import javax.management.remote.JMXConnectorFactory;
-import javax.management.remote.JMXServiceURL;
-
-import org.apache.commons.configuration.ConfigurationException;
-import org.apache.commons.configuration.XMLConfiguration;
-import org.apache.qpid.server.configuration.ServerConfiguration;
-import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin;
-import org.apache.qpid.server.logging.actors.CurrentActor;
-import org.apache.qpid.server.registry.ApplicationRegistry;
-import org.apache.qpid.server.security.Result;
-import org.apache.qpid.server.security.SecurityPlugin;
-import org.apache.qpid.server.security.access.ObjectProperties;
-import org.apache.qpid.server.security.access.ObjectType;
-import org.apache.qpid.server.security.access.Operation;
-import org.apache.qpid.server.util.TestApplicationRegistry;
-import org.apache.qpid.test.utils.QpidTestCase;
-
-public class ManagementLogActorTest extends QpidTestCase
-{
- private ApplicationRegistry _registry;
- private JMXManagedObjectRegistry _objectRegistry;
- private int _registryPort;
- private int _connectorPort;
- private TestPlugin _plugin;
-
- @Override
- public void setUp() throws Exception
- {
- super.setUp();
-
- _registryPort = findFreePort();
- _connectorPort = getNextAvailable(_registryPort + 1);
- XMLConfiguration config = new XMLConfiguration();
- config.addProperty(ServerConfiguration.MGMT_JMXPORT_REGISTRYSERVER, _registryPort + "");
- config.addProperty(ServerConfiguration.MGMT_JMXPORT_CONNECTORSERVER, _connectorPort + "");
- _registry = new TestApplicationRegistry(new ServerConfiguration(config));
- ApplicationRegistry.initialise(_registry);
-
- _plugin = new TestPlugin();
- _registry.getSecurityManager().addHostPlugin(_plugin);
-
- _objectRegistry = new JMXManagedObjectRegistry();
- new TestMBean(_objectRegistry);
- _objectRegistry.start();
- }
-
- public void tearDown() throws Exception
- {
- _objectRegistry.close();
- ApplicationRegistry.remove();
- super.tearDown();
- }
-
- public void testPrincipalInLogMessage() throws Throwable
- {
- Map<String, Object> environment = new HashMap<String, Object>();
- environment.put(JMXConnector.CREDENTIALS, new String[] { "admin", "admin" });
- String urlString = "service:jmx:rmi:///jndi/rmi://localhost:" + _registryPort + "/jmxrmi";
- JMXServiceURL url = new JMXServiceURL(urlString);
- JMXConnector jmxConnector = JMXConnectorFactory.connect(url, environment);
- MBeanServerConnection mbsc = jmxConnector.getMBeanServerConnection();
- ObjectName mbeanObject = new ObjectName("org.apache.qpid:type=TestMBean,name=test");
-
- String actorLogMessage = (String) mbsc.getAttribute(mbeanObject, "ActorLogMessage");
-
- assertTrue("Unexpected log principal in security plugin", _plugin.getLogMessage().startsWith("[mng:admin"));
- assertTrue("Unexpected log principal in MBean", actorLogMessage.startsWith("[mng:admin"));
- }
-
- public static class TestMBean extends DefaultManagedObject implements CurrentActorRetriever
- {
-
- public TestMBean(ManagedObjectRegistry registry) throws JMException
- {
- super(CurrentActorRetriever.class, "TestMBean", registry);
- register();
- }
-
- @Override
- public String getObjectInstanceName()
- {
- return "test";
- }
-
- @Override
- public ManagedObject getParentObject()
- {
- return null;
- }
-
- @Override
- public String getActorLogMessage()
- {
- return CurrentActor.get().getLogMessage();
- }
-
- }
-
- public static interface CurrentActorRetriever
- {
- String getActorLogMessage();
- }
-
- public static class TestPlugin implements SecurityPlugin
- {
- private String _logMessage;
-
- @Override
- public void configure(ConfigurationPlugin config) throws ConfigurationException
- {
- }
-
- @Override
- public Result getDefault()
- {
- return Result.ALLOWED;
- }
-
- @Override
- public Result access(ObjectType objectType, Object instance)
- {
- return Result.ALLOWED;
- }
-
- @Override
- public Result authorise(Operation operation, ObjectType objectType, ObjectProperties properties)
- {
- // set thread name to work around logic in MangementActor
- Thread.currentThread().setName("RMI TCP Connection(1)-" + System.currentTimeMillis());
- _logMessage = CurrentActor.get().getLogMessage();
- return Result.ALLOWED;
- }
-
- public String getLogMessage()
- {
- return _logMessage;
- }
-
- }
-
-}
diff --git a/java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/server/jmx/ManagementLogonLogoffReporterTest.java b/java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/server/jmx/ManagementLogonLogoffReporterTest.java
new file mode 100644
index 0000000000..ba9c2cdaa5
--- /dev/null
+++ b/java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/server/jmx/ManagementLogonLogoffReporterTest.java
@@ -0,0 +1,101 @@
+/*
+ * 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.jmx;
+
+import static javax.management.remote.JMXConnectionNotification.OPENED;
+import static javax.management.remote.JMXConnectionNotification.CLOSED;
+import static javax.management.remote.JMXConnectionNotification.FAILED;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyString;
+
+import javax.management.remote.JMXConnectionNotification;
+
+import org.apache.qpid.server.logging.LogActor;
+import org.apache.qpid.server.logging.RootMessageLogger;
+
+import junit.framework.TestCase;
+
+public class ManagementLogonLogoffReporterTest extends TestCase
+{
+ private static final String TEST_JMX_UNIQUE_CONNECTION_ID = "jmxconnectionid1 jmxuser,group";
+ private static final String TEST_USER = "jmxuser";
+
+ private ManagementLogonLogoffReporter _reporter;
+ private UsernameAccessor _usernameAccessor;
+ private RootMessageLogger _rootMessageLogger;
+
+ @Override
+ protected void setUp() throws Exception
+ {
+ super.setUp();
+ _usernameAccessor = mock(UsernameAccessor.class);
+ _rootMessageLogger = mock(RootMessageLogger.class);
+ // Enable messaging so we can valid the generated strings
+ when(_rootMessageLogger.isMessageEnabled(any(LogActor.class), anyString())).thenReturn(true);
+
+ _reporter = new ManagementLogonLogoffReporter(_rootMessageLogger, _usernameAccessor);
+ }
+
+ public void testOpenedNotification()
+ {
+ when(_usernameAccessor.getUsernameForConnectionId(TEST_JMX_UNIQUE_CONNECTION_ID)).thenReturn(TEST_USER);
+ JMXConnectionNotification openNotification = createMockNotification(TEST_JMX_UNIQUE_CONNECTION_ID, OPENED);
+
+ _reporter.handleNotification(openNotification, null);
+
+ verify(_rootMessageLogger).rawMessage("[main] MNG-1007 : Open : User jmxuser", "qpid.message.managementconsole.open");
+ }
+
+ public void testClosedNotification()
+ {
+ when(_usernameAccessor.getUsernameForConnectionId(TEST_JMX_UNIQUE_CONNECTION_ID)).thenReturn(TEST_USER);
+ JMXConnectionNotification closeNotification = createMockNotification(TEST_JMX_UNIQUE_CONNECTION_ID, CLOSED);
+
+ _reporter.handleNotification(closeNotification, null);
+
+ verify(_rootMessageLogger).rawMessage("[main] MNG-1008 : Close : User jmxuser", "qpid.message.managementconsole.close");
+ }
+
+ public void tesNotifiedForLogOnTypeEvents()
+ {
+ JMXConnectionNotification openNotification = createMockNotification(TEST_JMX_UNIQUE_CONNECTION_ID, OPENED);
+ JMXConnectionNotification closeNotification = createMockNotification(TEST_JMX_UNIQUE_CONNECTION_ID, CLOSED);
+ JMXConnectionNotification failedNotification = createMockNotification(TEST_JMX_UNIQUE_CONNECTION_ID, FAILED);
+
+ assertTrue(_reporter.isNotificationEnabled(openNotification));
+ assertTrue(_reporter.isNotificationEnabled(closeNotification));
+ assertTrue(_reporter.isNotificationEnabled(failedNotification));
+
+ JMXConnectionNotification otherNotification = createMockNotification(TEST_JMX_UNIQUE_CONNECTION_ID, "other");
+ assertFalse(_reporter.isNotificationEnabled(otherNotification));
+ }
+
+ private JMXConnectionNotification createMockNotification(String connectionId, String notificationType)
+ {
+ JMXConnectionNotification notification = mock(JMXConnectionNotification.class);
+ when(notification.getConnectionId()).thenReturn(connectionId);
+ when(notification.getType()).thenReturn(notificationType);
+ return notification;
+ }
+}
diff --git a/java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/server/jmx/mbeans/LoggingManagementMBeanTest.java b/java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/server/jmx/mbeans/LoggingManagementMBeanTest.java
index ae1be5db00..0f33e78d03 100644
--- a/java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/server/jmx/mbeans/LoggingManagementMBeanTest.java
+++ b/java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/server/jmx/mbeans/LoggingManagementMBeanTest.java
@@ -39,7 +39,7 @@ import junit.framework.TestCase;
import org.apache.qpid.management.common.mbeans.LoggingManagement;
import org.apache.qpid.server.jmx.ManagedObjectRegistry;
-import org.apache.qpid.server.logging.log4j.LoggingFacade;
+import org.apache.qpid.server.logging.log4j.LoggingManagementFacade;
public class LoggingManagementMBeanTest extends TestCase
{
@@ -47,13 +47,13 @@ public class LoggingManagementMBeanTest extends TestCase
private static final String TEST_LEVEL2 = "LEVEL2";
private LoggingManagementMBean _loggingMBean;
- private LoggingFacade _mockLoggingFacade;
+ private LoggingManagementFacade _mockLoggingFacade;
private ManagedObjectRegistry _mockManagedObjectRegistry;
@Override
protected void setUp() throws Exception
{
- _mockLoggingFacade = mock(LoggingFacade.class);
+ _mockLoggingFacade = mock(LoggingManagementFacade.class);
final List<String> listOfLevels = new ArrayList<String>()
{{
add(TEST_LEVEL1);
diff --git a/java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/systest/management/jmx/BrokerManagementTest.java b/java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/systest/management/jmx/BrokerManagementTest.java
deleted file mode 100644
index 7473a4d3e7..0000000000
--- a/java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/systest/management/jmx/BrokerManagementTest.java
+++ /dev/null
@@ -1,124 +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.systest.management.jmx;
-
-import org.apache.qpid.exchange.ExchangeDefaults;
-import org.apache.qpid.management.common.mbeans.ManagedBroker;
-import org.apache.qpid.management.common.mbeans.ManagedExchange;
-import org.apache.qpid.test.utils.JMXTestUtils;
-import org.apache.qpid.test.utils.QpidBrokerTestCase;
-
-/**
- * Tests the JMX API for the Managed Broker.
- *
- */
-public class BrokerManagementTest extends QpidBrokerTestCase
-{
- private static final String VIRTUAL_HOST = "test";
-
- /**
- * JMX helper.
- */
- private JMXTestUtils _jmxUtils;
- private ManagedBroker _managedBroker;
-
- public void setUp() throws Exception
- {
- _jmxUtils = new JMXTestUtils(this);
- _jmxUtils.setUp();
- super.setUp();
- _jmxUtils.open();
- _managedBroker = _jmxUtils.getManagedBroker(VIRTUAL_HOST);
- }
-
- public void tearDown() throws Exception
- {
- if (_jmxUtils != null)
- {
- _jmxUtils.close();
- }
- super.tearDown();
- }
-
- /**
- * Tests queue creation/deletion also verifying the automatic binding to the default exchange.
- */
- public void testCreateQueueAndDeletion() throws Exception
- {
- final String queueName = getTestQueueName();
- final ManagedExchange defaultExchange = _jmxUtils.getManagedExchange(ExchangeDefaults.DEFAULT_EXCHANGE_NAME.asString());
-
- // Check that bind does not exist before queue creation
- assertFalse("Binding to " + queueName + " should not exist in default exchange before queue creation",
- defaultExchange.bindings().containsKey(new String[] {queueName}));
-
- _managedBroker.createNewQueue(queueName, "testowner", true);
-
- // Ensure the queue exists
- assertNotNull("Queue object name expected to exist", _jmxUtils.getQueueObjectName(VIRTUAL_HOST, queueName));
- assertNotNull("Manager queue expected to be available", _jmxUtils.getManagedQueue(queueName));
-
- // Now verify that the default exchange has been bound.
- assertTrue("Binding to " + queueName + " should exist in default exchange after queue creation",
- defaultExchange.bindings().containsKey(new String[] {queueName}));
-
- // Now delete the queue
- _managedBroker.deleteQueue(queueName);
-
- // Finally ensure that the binding has been removed.
- assertFalse("Binding to " + queueName + " should not exist in default exchange after queue deletion",
- defaultExchange.bindings().containsKey(new String[] {queueName}));
- }
-
- /**
- * Tests exchange creation/deletion via JMX API.
- */
- public void testCreateExchangeAndUnregister() throws Exception
- {
- String exchangeName = getTestName();
- _managedBroker.createNewExchange(exchangeName, "topic", true);
-
- ManagedExchange exchange = _jmxUtils.getManagedExchange(exchangeName);
- assertNotNull("Exchange should exist", exchange);
-
- _managedBroker.unregisterExchange(exchangeName);
- }
-
- /**
- * Tests that it is disallowed to unregister the default exchange.
- */
- public void testUnregisterOfDefaultExchangeDisallowed() throws Exception
- {
- String defaultExchangeName = ExchangeDefaults.DEFAULT_EXCHANGE_NAME.asString();
-
- try
- {
- _managedBroker.unregisterExchange(defaultExchangeName);
- fail("Exception not thrown");
- }
- catch (UnsupportedOperationException e)
- {
- // PASS
- 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/java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/systest/management/jmx/ConnectionManagementTest.java b/java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/systest/management/jmx/ConnectionManagementTest.java
deleted file mode 100644
index 28d7bf4aed..0000000000
--- a/java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/systest/management/jmx/ConnectionManagementTest.java
+++ /dev/null
@@ -1,283 +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.systest.management.jmx;
-
-import java.io.IOException;
-import java.util.Date;
-import java.util.Iterator;
-import java.util.List;
-
-import javax.jms.Connection;
-import javax.jms.Destination;
-import javax.jms.JMSException;
-import javax.jms.Message;
-import javax.jms.MessageConsumer;
-import javax.jms.Queue;
-import javax.jms.Session;
-import javax.management.JMException;
-import javax.management.openmbean.CompositeData;
-import javax.management.openmbean.CompositeDataSupport;
-import javax.management.openmbean.TabularData;
-
-import org.apache.commons.lang.StringUtils;
-import org.apache.qpid.common.QpidProperties;
-import org.apache.qpid.management.common.mbeans.ManagedConnection;
-import org.apache.qpid.management.common.mbeans.ManagedQueue;
-import org.apache.qpid.test.utils.JMXTestUtils;
-import org.apache.qpid.test.utils.QpidBrokerTestCase;
-
-public class ConnectionManagementTest extends QpidBrokerTestCase
-{
- private static final String VIRTUAL_HOST_NAME = "test";
-
- private JMXTestUtils _jmxUtils;
- private Connection _connection;
-
- public void setUp() throws Exception
- {
- _jmxUtils = new JMXTestUtils(this);
- _jmxUtils.setUp(); // modifies broker config therefore must be done before super.setUp()
- super.setUp();
- _jmxUtils.open();
- }
-
- public void tearDown() throws Exception
- {
- try
- {
- if (_jmxUtils != null)
- {
- _jmxUtils.close();
- }
- }
- finally
- {
- super.tearDown();
- }
- }
-
- public void testNumberOfManagedConnectionsMatchesNumberOfClientConnections() throws Exception
- {
- assertEquals("Expected no managed connections", 0, getManagedConnections().size());
-
- _connection = getConnection();
- assertEquals("Expected one managed connection", 1, getManagedConnections().size());
-
- _connection.close();
- assertEquals("Expected no managed connections after client connection closed", 0, getManagedConnections().size());
- }
-
- public void testGetAttributes() throws Exception
- {
- _connection = getConnection();
- final ManagedConnection mBean = getConnectionMBean();
-
- checkAuthorisedId(mBean);
- checkClientVersion(mBean);
- checkClientId(mBean);
- }
-
- public void testNonTransactedSession() throws Exception
- {
- _connection = getConnection();
-
- boolean transactional = false;
- boolean flowBlocked = false;
-
- _connection.createSession(transactional, Session.AUTO_ACKNOWLEDGE);
-
- final ManagedConnection mBean = getConnectionMBean();
- final CompositeDataSupport row = getTheOneChannelRow(mBean);
- assertChannelRowData(row, 0, transactional, flowBlocked);
- }
-
- public void testTransactedSessionWithUnackMessages() throws Exception
- {
- _connection = getConnection();
- _connection.start();
-
- boolean transactional = true;
- int numberOfMessages = 2;
- final Session session = _connection.createSession(transactional, Session.SESSION_TRANSACTED);
- final Destination destination = session.createQueue(getTestQueueName());
- final MessageConsumer consumer = session.createConsumer(destination);
-
- sendMessage(session, destination, numberOfMessages);
- receiveMessagesWithoutCommit(consumer, numberOfMessages);
-
- final ManagedConnection mBean = getConnectionMBean();
- final CompositeDataSupport row = getTheOneChannelRow(mBean);
- boolean flowBlocked = false;
- assertChannelRowData(row, numberOfMessages, transactional, flowBlocked);
-
- // check that commit advances the lastIoTime
- final Date initialLastIOTime = mBean.getLastIoTime();
- session.commit();
- assertTrue("commit should have caused last IO time to advance", mBean.getLastIoTime().after(initialLastIOTime));
-
- // check that channels() now returns one session with no unacknowledged messages
- final CompositeDataSupport rowAfterCommit = getTheOneChannelRow(mBean);
- final Number unackCountAfterCommit = (Number) rowAfterCommit.get(ManagedConnection.UNACKED_COUNT);
- assertEquals("Unexpected number of unacknowledged messages", 0, unackCountAfterCommit);
- }
-
-
- public void testProducerFlowBlocked() throws Exception
- {
- _connection = getConnection();
- _connection.start();
-
- String queueName = getTestQueueName();
- Session session = _connection.createSession(true, Session.SESSION_TRANSACTED);
- Queue queue = session.createQueue(queueName);
- createQueueOnBroker(session, queue);
-
- ManagedQueue managedQueue = _jmxUtils.getManagedQueue(queueName);
- managedQueue.setFlowResumeCapacity(DEFAULT_MESSAGE_SIZE * 2l);
- managedQueue.setCapacity(DEFAULT_MESSAGE_SIZE * 3l);
-
- final ManagedConnection managedConnection = getConnectionMBean();
-
- // Check that producer flow is not block before test
- final CompositeDataSupport rowBeforeSend = getTheOneChannelRow(managedConnection);
- assertFlowBlocked(rowBeforeSend, false);
-
-
- // Check that producer flow does not become block too soon
- sendMessage(session, queue, 3);
- final CompositeDataSupport rowBeforeFull = getTheOneChannelRow(managedConnection);
- assertFlowBlocked(rowBeforeFull, false);
-
- // Fourth message will over-fill the queue (but as we are not sending more messages, client thread wont't block)
- sendMessage(session, queue, 1);
- final CompositeDataSupport rowAfterFull = getTheOneChannelRow(managedConnection);
- assertFlowBlocked(rowAfterFull, true);
-
- // Consume two to bring the queue down to the resume capacity
- MessageConsumer consumer = session.createConsumer(queue);
- assertNotNull("Could not receive first message", consumer.receive(1000));
- assertNotNull("Could not receive second message", consumer.receive(1000));
- session.commit();
-
- // Check that producer flow is no longer blocked
- final CompositeDataSupport rowAfterReceive = getTheOneChannelRow(managedConnection);
- assertFlowBlocked(rowAfterReceive, false);
- }
-
- private void createQueueOnBroker(Session session, Destination destination) throws JMSException
- {
- session.createConsumer(destination).close(); // Create a consumer only to cause queue creation
- }
-
- private void assertChannelRowData(final CompositeData row, int unacknowledgedMessages, boolean isTransactional, boolean flowBlocked)
- {
- assertNotNull(row);
- assertEquals("Unexpected transactional flag", isTransactional, row.get(ManagedConnection.TRANSACTIONAL));
- assertEquals("Unexpected unacknowledged message count", unacknowledgedMessages, row.get(ManagedConnection.UNACKED_COUNT));
- assertEquals("Unexpected flow blocked", flowBlocked, row.get(ManagedConnection.FLOW_BLOCKED));
- }
-
- private void assertFlowBlocked(final CompositeData row, boolean flowBlocked)
- {
- assertNotNull(row);
- assertEquals("Unexpected flow blocked", flowBlocked, row.get(ManagedConnection.FLOW_BLOCKED));
- }
-
- private void checkAuthorisedId(ManagedConnection mBean) throws Exception
- {
- assertEquals("Unexpected authorized id", GUEST_USERNAME, mBean.getAuthorizedId());
- }
-
- private void checkClientVersion(ManagedConnection mBean) throws Exception
- {
- String expectedVersion = QpidProperties.getReleaseVersion();
- assertTrue(StringUtils.isNotBlank(expectedVersion));
-
- assertEquals("Unexpected version", expectedVersion, mBean.getVersion());
- }
-
- private void checkClientId(ManagedConnection mBean) throws Exception
- {
- String expectedClientId = _connection.getClientID();
- assertTrue(StringUtils.isNotBlank(expectedClientId));
-
- assertEquals("Unexpected ClientId", expectedClientId, mBean.getClientId());
- }
-
- private ManagedConnection getConnectionMBean()
- {
- List<ManagedConnection> connections = getManagedConnections();
- assertNotNull("Connection MBean is not found", connections);
- assertEquals("Unexpected number of connection mbeans", 1, connections.size());
- final ManagedConnection mBean = connections.get(0);
- assertNotNull("Connection MBean is null", mBean);
- return mBean;
- }
-
- private List<ManagedConnection> getManagedConnections()
- {
- return _jmxUtils.getManagedConnections(VIRTUAL_HOST_NAME);
- }
-
- private CompositeDataSupport getTheOneChannelRow(final ManagedConnection mBean) throws Exception
- {
- TabularData channelsData = getChannelsDataWithRetry(mBean);
-
- assertEquals("Unexpected number of rows in channel table", 1, channelsData.size());
-
- @SuppressWarnings("unchecked")
- final Iterator<CompositeDataSupport> rowItr = (Iterator<CompositeDataSupport>) channelsData.values().iterator();
- final CompositeDataSupport row = rowItr.next();
- return row;
- }
-
- private void receiveMessagesWithoutCommit(final MessageConsumer consumer, int numberOfMessages) throws Exception
- {
- for (int i = 0; i < numberOfMessages; i++)
- {
- final Message m = consumer.receive(1000l);
- assertNotNull("Message " + i + " is not received", m);
- }
- }
-
- private TabularData getChannelsDataWithRetry(final ManagedConnection mBean)
- throws IOException, JMException
- {
- TabularData channelsData = mBean.channels();
- int retries = 0;
- while(channelsData.size() == 0 && retries < 5)
- {
- sleep();
- channelsData = mBean.channels();
- retries++;
- }
- return channelsData;
- }
-
- private void sleep()
- {
- try
- {
- Thread.sleep(50);
- }
- catch (InterruptedException ie)
- {
- Thread.currentThread().interrupt();
- }
- }}
diff --git a/java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/systest/management/jmx/LoggingManagementTest.java b/java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/systest/management/jmx/LoggingManagementTest.java
deleted file mode 100644
index ac6730638e..0000000000
--- a/java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/systest/management/jmx/LoggingManagementTest.java
+++ /dev/null
@@ -1,149 +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.systest.management.jmx;
-
-import java.io.File;
-import java.util.List;
-
-import javax.management.openmbean.CompositeData;
-import javax.management.openmbean.TabularData;
-
-import org.apache.qpid.management.common.mbeans.LoggingManagement;
-import org.apache.qpid.server.jmx.mbeans.LoggingManagementMBeanTest;
-import org.apache.qpid.server.logging.log4j.LoggingFacadeTest;
-import org.apache.qpid.test.utils.JMXTestUtils;
-import org.apache.qpid.test.utils.QpidBrokerTestCase;
-import org.apache.qpid.util.FileUtils;
-import org.apache.qpid.util.LogMonitor;
-
-/**
- * System test for Logging Management. <b>These tests rely on value set within
- * test-profiles/log4j-test.xml</b>.
- *
- * @see LoggingManagementMBeanTest
- * @see LoggingFacadeTest
- *
- */
-public class LoggingManagementTest extends QpidBrokerTestCase
-{
- private JMXTestUtils _jmxUtils;
- private LoggingManagement _loggingManagement;
- private LogMonitor _monitor;
-
- public void setUp() throws Exception
- {
- _jmxUtils = new JMXTestUtils(this);
- _jmxUtils.setUp();
-
- // System test normally run with log for4j test config from beneath test-profiles. We need to
- // copy it as some of our tests write to this file.
-
- File tmpLogFile = File.createTempFile("log4j" + "." + getName(), ".xml");
- tmpLogFile.deleteOnExit();
- FileUtils.copy(_logConfigFile, tmpLogFile);
-
- _logConfigFile = tmpLogFile;
-
- super.setUp();
- _jmxUtils.open();
-
- _loggingManagement = _jmxUtils.getLoggingManagement();
- _monitor = new LogMonitor(_outputFile);
- }
-
- public void tearDown() throws Exception
- {
- try
- {
- if (_jmxUtils != null)
- {
- _jmxUtils.close();
- }
- }
- finally
- {
- super.tearDown();
- }
- }
-
- public void testViewEffectiveRuntimeLoggerLevels() throws Exception
- {
- final String qpidMainLogger = "org.apache.qpid";
-
- TabularData table = _loggingManagement.viewEffectiveRuntimeLoggerLevels();
- final CompositeData row = table.get(new String[] {qpidMainLogger} );
- assertChannelRow(row, qpidMainLogger, "DEBUG");
- }
-
- public void testViewConfigFileLoggerLevels() throws Exception
- {
- final String operationalLoggingLogger = "qpid.message";
-
- TabularData table = _loggingManagement.viewConfigFileLoggerLevels();
- final CompositeData row = table.get(new String[] {operationalLoggingLogger} );
- assertChannelRow(row, operationalLoggingLogger, "INFO");
- }
-
- public void testTurnOffOrgApacheQpidAtRuntime() throws Exception
- {
- final String logger = "org.apache.qpid";
- _monitor.markDiscardPoint();
- _loggingManagement.setRuntimeLoggerLevel(logger, "OFF");
-
- List<String> matches = _monitor.findMatches("Setting level to OFF for logger 'org.apache.qpid'");
- assertEquals(1, matches.size());
-
- TabularData table = _loggingManagement.viewEffectiveRuntimeLoggerLevels();
- final CompositeData row1 = table.get(new String[] {logger} );
- assertChannelRow(row1, logger, "OFF");
- }
-
- public void testChangesToConfigFileBecomeEffectiveAfterReload() throws Exception
- {
- final String operationalLoggingLogger = "qpid.message";
- assertEffectiveLoggingLevel(operationalLoggingLogger, "INFO");
-
- _monitor.markDiscardPoint();
- _loggingManagement.setConfigFileLoggerLevel(operationalLoggingLogger, "OFF");
-
- List<String> matches = _monitor.findMatches("Setting level to OFF for logger 'qpid.message'");
- assertEquals(1, matches.size());
-
- assertEffectiveLoggingLevel(operationalLoggingLogger, "INFO");
-
- _loggingManagement.reloadConfigFile();
-
- assertEffectiveLoggingLevel(operationalLoggingLogger, "OFF");
- }
-
- private void assertEffectiveLoggingLevel(String operationalLoggingLogger, String expectedLevel)
- {
- TabularData table = _loggingManagement.viewEffectiveRuntimeLoggerLevels();
- final CompositeData row1 = table.get(new String[] {operationalLoggingLogger} );
- assertChannelRow(row1, operationalLoggingLogger, expectedLevel);
- }
-
- private void assertChannelRow(final CompositeData row, String logger, String level)
- {
- assertNotNull("No row for " + logger, row);
- assertEquals("Unexpected logger name", logger, row.get(LoggingManagement.LOGGER_NAME));
- assertEquals("Unexpected level", level, row.get(LoggingManagement.LOGGER_LEVEL));
- }
-
-}
diff --git a/java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/systest/management/jmx/ManagementActorLoggingTest.java b/java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/systest/management/jmx/ManagementActorLoggingTest.java
deleted file mode 100644
index 47b38381c5..0000000000
--- a/java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/systest/management/jmx/ManagementActorLoggingTest.java
+++ /dev/null
@@ -1,480 +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.systest.management.jmx;
-
-import org.apache.qpid.management.common.mbeans.ManagedBroker;
-import org.apache.qpid.management.common.mbeans.ManagedConnection;
-import org.apache.qpid.management.common.mbeans.ManagedExchange;
-import org.apache.qpid.server.logging.AbstractTestLogging;
-import org.apache.qpid.server.logging.subjects.AbstractTestLogSubject;
-import org.apache.qpid.test.utils.JMXTestUtils;
-
-import javax.jms.Connection;
-import javax.jms.ExceptionListener;
-import javax.jms.JMSException;
-import javax.management.JMException;
-import java.io.IOException;
-import java.util.List;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Test class to test if any change in the broker JMX code is affesting the management console
- * There are some hardcoding of management feature names and parameter names to create a customized
- * look in the console.
- */
-public class ManagementActorLoggingTest extends AbstractTestLogging
-{
- private JMXTestUtils _jmxUtils;
- private boolean _closed = false;
-
- @Override
- public void setUp() throws Exception
- {
- _jmxUtils = new JMXTestUtils(this);
- _jmxUtils.setUp();
- super.setUp();
- _jmxUtils.open();
- }
-
- @Override
- public void tearDown() throws Exception
- {
- if(!_closed)
- {
- _jmxUtils.close();
- }
- super.tearDown();
- }
-
- /**
- * Description:
- * When a connected client has its connection closed via the Management Console this will be logged as a CON-1002 message.
- * Input:
- *
- * 1. Running Broker
- * 2. Connected Client
- * 3. Connection is closed via Management Console
- * Output:
- *
- * <date> CON-1002 : Close
- *
- * Validation Steps:
- * 4. The CON ID is correct
- * 5. This must be the last CON message for the Connection
- * 6. It must be preceded by a CON-1001 for this Connection
- *
- * @throws Exception - {@see ManagedConnection.closeConnection and #getConnection}
- * @throws java.io.IOException - if there is a problem reseting the log monitor
- */
- public void testConnectionCloseViaManagement() throws IOException, Exception
- {
- //Create a connection to the broker
- Connection connection = getConnection();
-
- // Monitor the connection for an exception being thrown
- // this should be a DisconnectionException but it is not this tests
- // job to valiate that. Only use the exception as a synchronisation
- // to check the log file for the Close message
- final CountDownLatch exceptionReceived = new CountDownLatch(1);
- connection.setExceptionListener(new ExceptionListener()
- {
- public void onException(JMSException e)
- {
- //Failover being attempted.
- exceptionReceived.countDown();
- }
- });
-
- //Remove the connection close from any 0-10 connections
- _monitor.markDiscardPoint();
-
- // Get a managedConnection
- ManagedConnection mangedConnection = _jmxUtils.getManagedObject(ManagedConnection.class, "org.apache.qpid:type=VirtualHost.Connection,*");
-
- //Close the connection
- mangedConnection.closeConnection();
-
- //Wait for the connection to close
- assertTrue("Timed out waiting for conneciton to report close",
- exceptionReceived.await(2, TimeUnit.SECONDS));
-
- //Validate results
- List<String> results = waitAndFindMatches("CON-1002");
-
- assertEquals("Unexpected Connection Close count", 1, results.size());
- }
-
- /**
- * Description:
- * Exchange creation is possible from the Management Console.
- * When an exchanged is created in this way then a EXH-1001 create message
- * is expected to be logged.
- * Input:
- *
- * 1. Running broker
- * 2. Connected Management Console
- * 3. Exchange Created via Management Console
- * Output:
- *
- * EXH-1001 : Create : [Durable] Type:<value> Name:<value>
- *
- * Validation Steps:
- * 4. The EXH ID is correct
- * 5. The correct tags are present in the message based on the create options
- *
- * @throws java.io.IOException - if there is a problem reseting the log monitor
- * @throws javax.management.JMException - {@see #createQueue and ManagedExchange.deleteQueue}
- */
- public void testCreateExchangeDirectTransientViaManagementConsole() throws IOException, JMException
- {
- _monitor.markDiscardPoint();
-
- _jmxUtils.createExchange("test", getName(), "direct", false);
-
- // Validate
-
- //1 - ID is correct
- List<String> results = waitAndFindMatches("EXH-1001");
-
- assertEquals("More than one exchange creation found", 1, results.size());
-
- String log = getLogMessage(results, 0);
-
- // Validate correct exchange name
- assertTrue("Incorrect exchange name created:" + log, log.endsWith(getName()));
-
- // Validate it was a management actor.
- String actor = fromActor(log);
- assertTrue("Actor is not a manangement actor:" + actor, actor.startsWith("mng"));
- }
-
- public void testCreateExchangeTopicTransientViaManagementConsole() throws IOException, JMException
- {
- //Remove any previous exchange declares
- _monitor.markDiscardPoint();
-
- _jmxUtils.createExchange("test", getName(), "topic", false);
-
- // Validate
-
- //1 - ID is correct
- List<String> results = waitAndFindMatches("EXH-1001");
-
- assertEquals("More than one exchange creation found", 1, results.size());
-
- String log = getLogMessage(results, 0);
-
- // Validate correct exchange name
- assertTrue("Incorrect exchange name created:" + log, log.endsWith(getName()));
-
- // Validate it was a management actor.
- String actor = fromActor(log);
- assertTrue("Actor is not a manangement actor:" + actor, actor.startsWith("mng"));
-
- }
-
- public void testCreateExchangeFanoutTransientViaManagementConsole() throws IOException, JMException
- {
- //Remove any previous exchange declares
- _monitor.markDiscardPoint();
-
- _jmxUtils.createExchange("test", getName(), "fanout", false);
-
- // Validate
-
- //1 - ID is correct
- List<String> results = waitAndFindMatches("EXH-1001");
-
- assertEquals("More than one exchange creation found", 1, results.size());
-
- String log = getLogMessage(results, 0);
-
- // Validate correct exchange name
- assertTrue("Incorrect exchange name created:" + log, log.endsWith(getName()));
-
- // Validate it was a management actor.
- String actor = fromActor(log);
- assertTrue("Actor is not a manangement actor:" + actor, actor.startsWith("mng"));
-
- }
-
- public void testCreateExchangeHeadersTransientViaManagementConsole() throws IOException, JMException
- {
- //Remove any previous exchange declares
- _monitor.markDiscardPoint();
-
- _jmxUtils.createExchange("test", getName(), "headers", false);
-
- // Validate
-
- //1 - ID is correct
- List<String> results = waitAndFindMatches("EXH-1001");
-
- assertEquals("More than one exchange creation found", 1, results.size());
-
- String log = getLogMessage(results, 0);
-
- // Validate correct exchange name
- assertTrue("Incorrect exchange name created:" + log, log.endsWith(getName()));
-
- // Validate it was a management actor.
- String actor = fromActor(log);
- assertTrue("Actor is not a manangement actor:" + actor, actor.startsWith("mng"));
-
- }
-
- /**
- * Description:
- * Queue creation is possible from the Management Console. When a queue is created in this way then a QUE-1001 create message is expected to be logged.
- * Input:
- *
- * 1. Running broker
- * 2. Connected Management Console
- * 3. Queue Created via Management Console
- * Output:
- *
- * <date> QUE-1001 : Create : Transient Owner:<name>
- *
- * Validation Steps:
- * 4. The QUE ID is correct
- * 5. The correct tags are present in the message based on the create options
- *
- * @throws java.io.IOException - if there is a problem reseting the log monitor
- * @throws javax.management.JMException - {@see #createQueue and ManagedExchange.deleteQueue}
- */
- public void testCreateQueueTransientViaManagementConsole() throws IOException, JMException
- {
- //Remove any previous queue declares
- _monitor.markDiscardPoint();
-
- _jmxUtils.createQueue("test", getName(), null, false);
-
- // Validate
-
- List<String> results = waitAndFindMatches("QUE-1001");
-
- assertEquals("More than one queue creation found", 1, results.size());
-
- String log = getLogMessage(results, 0);
-
- // Validate correct queue name
- String subject = fromSubject(log);
- assertEquals("Incorrect queue name created", getName(), AbstractTestLogSubject.getSlice("qu", subject));
-
- // Validate it was a management actor.
- String actor = fromActor(log);
- assertTrue("Actor is not a manangement actor:" + actor, actor.startsWith("mng"));
- }
-
- /**
- * Description:
- * The ManagementConsole can be used to delete a queue. When this is done a QUE-1002 Deleted message must be logged.
- * Input:
- *
- * 1. Running Broker
- * 2. Queue created on the broker with no subscribers
- * 3. Management Console connected
- * 4. Queue is deleted via Management Console
- * Output:
- *
- * <date> QUE-1002 : Deleted
- *
- * Validation Steps:
- * 5. The QUE ID is correct
- *
- * @throws java.io.IOException - if there is a problem reseting the log monitor
- * @throws javax.management.JMException - {@see #createQueue and ManagedExchange.deleteQueue}
- */
- public void testQueueDeleteViaManagementConsole() throws IOException, JMException
- {
- //Remove any previous queue declares
- _monitor.markDiscardPoint();
-
- _jmxUtils.createQueue("test", getName(), null, false);
-
- ManagedBroker managedBroker = _jmxUtils.getManagedBroker("test");
-
- managedBroker.deleteQueue(getName());
-
- List<String> results = waitAndFindMatches("QUE-1002");
-
- assertEquals("More than one queue deletion found", 1, results.size());
-
- String log = getLog(results.get(0));
-
- // Validate correct binding
- String subject = fromSubject(log);
- assertEquals("Incorrect queue named in delete", getName(), AbstractTestLogSubject.getSlice("qu", subject));
-
- // Validate it was a management actor.
- String actor = fromActor(log);
- assertTrue("Actor is not a manangement actor:" + actor, actor.startsWith("mng"));
-
- }
-
- /**
- * Description:
- * The binding of a Queue and an Exchange is done via a Binding. When this Binding is created via the Management Console a BND-1001 Create message will be logged.
- * Input:
- *
- * 1. Running Broker
- * 2. Connected Management Console
- * 3. Use Management Console to perform binding
- * Output:
- *
- * <date> BND-1001 : Create
- *
- * Validation Steps:
- * 4. The BND ID is correct
- * 5. This will be the first message for the given binding
- *
- * @throws java.io.IOException - if there is a problem reseting the log monitor
- * @throws javax.management.JMException - {@see #createQueue and ManagedExchange.createNewBinding}
- */
- public void testBindingCreateOnDirectViaManagementConsole() throws IOException, JMException
- {
- //Remove any previous queue declares
- _monitor.markDiscardPoint();
-
- _jmxUtils.createQueue("test", getName(), null, false);
-
- ManagedExchange managedExchange = _jmxUtils.getManagedExchange("amq.direct");
-
- managedExchange.createNewBinding(getName(), getName());
-
- List<String> results = waitAndFindMatches("BND-1001");
-
- assertEquals("Unexpected number of bindings logged", 2, results.size());
-
- String log = getLogMessage(results, 0);
-
- // Validate correct binding
- String subject = fromSubject(log);
- assertEquals("Incorrect queue named in create", getName(), AbstractTestLogSubject.getSlice("qu", subject));
- assertEquals("Incorrect routing key in create", getName(), AbstractTestLogSubject.getSlice("rk", subject));
-
- // Validate it was a management actor.
- String actor = fromActor(log);
- assertTrue("Actor is not a manangement actor:" + actor, actor.startsWith("mng"));
- }
-
- public void testBindingCreateOnTopicViaManagementConsole() throws IOException, JMException
- {
- //Remove any previous queue declares
- _monitor.markDiscardPoint();
-
- _jmxUtils.createQueue("test", getName(), null, false);
-
- ManagedExchange managedExchange = _jmxUtils.getManagedExchange("amq.topic");
-
- managedExchange.createNewBinding(getName(), getName());
-
- List<String> results = waitAndFindMatches("BND-1001");
-
- assertEquals("Unexpected number of bindings logged", 2, results.size());
-
- String log = getLogMessage(results, 0);
-
- // Validate correct binding
- String subject = fromSubject(log);
- assertEquals("Incorrect queue named in create", getName(), AbstractTestLogSubject.getSlice("qu", subject));
- assertEquals("Incorrect routing key in create", getName(), AbstractTestLogSubject.getSlice("rk", subject));
-
- // Validate it was a management actor.
- String actor = fromActor(log);
- assertTrue("Actor is not a manangement actor:" + actor, actor.startsWith("mng"));
- }
-
- public void testBindingCreateOnFanoutViaManagementConsole() throws IOException, JMException
- {
- //Remove any previous queue declares
- _monitor.markDiscardPoint();
-
- _jmxUtils.createQueue("test", getName(), null, false);
-
- ManagedExchange managedExchange = _jmxUtils.getManagedExchange("amq.fanout");
-
- managedExchange.createNewBinding(getName(), getName());
-
- List<String> results = waitAndFindMatches("BND-1001");
-
- assertEquals("Unexpected number of bindings logged", 2, results.size());
-
- String log = getLogMessage(results, 0);
-
- // Validate correct binding
- String subject = fromSubject(log);
- assertEquals("Incorrect queue named in create", getName(), AbstractTestLogSubject.getSlice("qu", subject));
- assertEquals("Incorrect routing key in create", getName(), AbstractTestLogSubject.getSlice("rk", subject));
-
- // Validate it was a management actor.
- String actor = fromActor(log);
- assertTrue("Actor is not a manangement actor:" + actor, actor.startsWith("mng"));
- }
-
- /**
- * Description:
- * Bindings can be deleted so that a queue can be rebound with a different set of values. This can be performed via the Management Console
- * Input:
- *
- * 1. Running Broker
- * 2. Management Console connected
- * 3. Management Console is used to perform unbind.
- * Output:
- *
- * <date> BND-1002 : Deleted
- *
- * Validation Steps:
- * 4. The BND ID is correct
- * 5. There must have been a BND-1001 Create message first.
- * 6. This will be the last message for the given binding
- *
- * @throws java.io.IOException - if there is a problem reseting the log monitor or an issue with the JMX Connection
- * @throws javax.management.JMException - {@see #createExchange and ManagedBroker.unregisterExchange}
- */
- public void testUnRegisterExchangeViaManagementConsole() throws IOException, JMException
- {
- //Remove any previous queue declares
- _monitor.markDiscardPoint();
-
- _jmxUtils.createExchange("test", getName(), "direct", false);
-
- ManagedBroker managedBroker = _jmxUtils.getManagedBroker("test");
-
- managedBroker.unregisterExchange(getName());
-
- List<String> results = waitAndFindMatches("EXH-1002");
-
- assertEquals("More than one exchange deletion found", 1, results.size());
-
- String log = getLog(results.get(0));
-
- // Validate correct binding
- String subject = fromSubject(log);
- assertEquals("Incorrect exchange named in delete", "direct/" + getName(), AbstractTestLogSubject.getSlice("ex", subject));
-
- // Validate it was a management actor.
- String actor = fromActor(log);
- assertTrue("Actor is not a manangement actor:" + actor, actor.startsWith("mng"));
- }
-
-}
diff --git a/java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/systest/management/jmx/ManagementLoggingTest.java b/java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/systest/management/jmx/ManagementLoggingTest.java
deleted file mode 100644
index 6100d5a23e..0000000000
--- a/java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/systest/management/jmx/ManagementLoggingTest.java
+++ /dev/null
@@ -1,317 +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.systest.management.jmx;
-
-
-import org.apache.qpid.server.configuration.ServerConfiguration;
-import org.apache.qpid.server.logging.AbstractTestLogging;
-import org.apache.qpid.test.utils.JMXTestUtils;
-import org.apache.qpid.util.LogMonitor;
-
-import java.io.File;
-import java.util.List;
-
-/**
- * Management Console Test Suite
- *
- * The Management Console test suite validates that the follow log messages as specified in the Functional Specification.
- *
- * This suite of tests validate that the management console messages occur correctly and according to the following format:
- *
- * MNG-1001 : Startup
- * MNG-1002 : Starting : <service> : Listening on port <Port>
- * MNG-1003 : Shutting down : <service> : port <Port>
- * MNG-1004 : Ready
- * MNG-1005 : Stopped
- * MNG-1006 : Using SSL Keystore : <path>
- * MNG-1007 : Open : User <username>
- * MNG-1008 : Close : User <username>
- */
-public class ManagementLoggingTest extends AbstractTestLogging
-{
- private static final String MNG_PREFIX = "MNG-";
-
- public void setUp() throws Exception
- {
- setLogMessagePrefix();
-
- // We either do this here or have a null check in tearDown.
- // As when this test is run against profiles other than java it will NPE
- _monitor = new LogMonitor(_outputFile);
- //We explicitly do not call super.setUp as starting up the broker is
- //part of the test case.
-
- }
-
- /**
- * Description:
- * Using the startup configuration validate that the management startup
- * message is logged correctly.
- * Input:
- * Standard configuration with management enabled
- * Output:
- *
- * <date> MNG-1001 : Startup
- *
- * Constraints:
- * This is the FIRST message logged by MNG
- * Validation Steps:
- *
- * 1. The BRK ID is correct
- * 2. This is the FIRST message logged by MNG
- */
- public void testManagementStartupEnabled() throws Exception
- {
- // This test only works on java brokers
- if (isJavaBroker())
- {
- startBrokerAndCreateMonitor(true, false);
-
- // Ensure we have received the MNG log msg.
- waitForMessage("MNG-1001");
-
- List<String> results = findMatches(MNG_PREFIX);
- // Validation
-
- assertTrue("MNGer message not logged", results.size() > 0);
-
- String log = getLogMessage(results, 0);
-
- //1
- validateMessageID("MNG-1001", log);
-
- //2
- //There will be 2 copies of the startup message (one via SystemOut, and one via Log4J)
- results = findMatches("MNG-1001");
- assertEquals("Unexpected startup message count.",
- 2, results.size());
-
- //3
- assertEquals("Startup log message is not 'Startup'.", "Startup",
- getMessageString(log));
- }
- }
-
- /**
- * Description:
- * Verify that when management is disabled in the configuration file the
- * startup message is not logged.
- * Input:
- * Standard configuration with management disabled
- * Output:
- * NO MNG messages
- * Validation Steps:
- *
- * 1. Validate that no MNG messages are produced.
- */
- public void testManagementStartupDisabled() throws Exception
- {
- if (isJavaBroker())
- {
- startBrokerAndCreateMonitor(false, false);
-
- List<String> results = findMatches(MNG_PREFIX);
- // Validation
-
- assertEquals("MNGer messages logged", 0, results.size());
- }
- }
-
- /**
- * The two MNG-1002 messages are logged at the same time so lets test them
- * at the same time.
- *
- * Description:
- * Using the default configuration validate that the RMI Registry socket is
- * correctly reported as being opened
- *
- * Input:
- * The default configuration file
- * Output:
- *
- * <date> MESSAGE MNG-1002 : Starting : RMI Registry : Listening on port 8999
- *
- * Constraints:
- * The RMI ConnectorServer and Registry log messages do not have a prescribed order
- * Validation Steps:
- *
- * 1. The MNG ID is correct
- * 2. The specified port is the correct '8999'
- *
- * Description:
- * Using the default configuration validate that the RMI ConnectorServer
- * socket is correctly reported as being opened
- *
- * Input:
- * The default configuration file
- * Output:
- *
- * <date> MESSAGE MNG-1002 : Starting : RMI ConnectorServer : Listening on port 9099
- *
- * Constraints:
- * The RMI ConnectorServer and Registry log messages do not have a prescribed order
- * Validation Steps:
- *
- * 1. The MNG ID is correct
- * 2. The specified port is the correct '9099'
- */
- public void testManagementStartupRMIEntries() throws Exception
- {
- if (isJavaBroker())
- {
- startBrokerAndCreateMonitor(true, false);
-
- List<String> results = waitAndFindMatches("MNG-1002");
- // Validation
-
- //There will be 4 startup messages (two via SystemOut, and two via Log4J)
- assertEquals("Unexpected MNG-1002 message count", 4, results.size());
-
- String log = getLogMessage(results, 0);
-
- //1
- validateMessageID("MNG-1002", log);
-
- //Check the RMI Registry port is as expected
- int mPort = getManagementPort(getPort());
- assertTrue("RMI Registry port not as expected(" + mPort + ").:" + getMessageString(log),
- getMessageString(log).endsWith(String.valueOf(mPort)));
-
- log = getLogMessage(results, 2);
-
- //1
- validateMessageID("MNG-1002", log);
-
- // We expect the RMI Registry port (the defined 'management port') to be
- // 100 lower than the JMX RMIConnector Server Port (the actual JMX server)
- int jmxPort = mPort + ServerConfiguration.JMXPORT_CONNECTORSERVER_OFFSET;
- assertTrue("JMX RMIConnectorServer port not as expected(" + jmxPort + ").:" + getMessageString(log),
- getMessageString(log).endsWith(String.valueOf(jmxPort)));
- }
- }
-
- /**
- * Description:
- * Using the default configuration with SSL enabled for the management port the SSL Keystore path should be reported via MNG-1006
- * Input:
- * Management SSL enabled default configuration.
- * Output:
- *
- * <date> MESSAGE MNG-1006 : Using SSL Keystore : test_resources/ssl/keystore.jks
- *
- * Validation Steps:
- *
- * 1. The MNG ID is correct
- * 2. The keystore path is as specified in the configuration
- */
- public void testManagementStartupSSLKeystore() throws Exception
- {
- if (isJavaBroker())
- {
- startBrokerAndCreateMonitor(true, true);
-
- List<String> results = waitAndFindMatches("MNG-1006");
-
- assertTrue("MNGer message not logged", results.size() > 0);
-
- String log = getLogMessage(results, 0);
-
- //1
- validateMessageID("MNG-1006", log);
-
- // Validate we only have two MNG-1002 (one via stdout, one via log4j)
- results = findMatches("MNG-1006");
- assertEquals("Upexpected SSL Keystore message count",
- 2, results.size());
-
- // Validate the keystore path is as expected
- assertTrue("SSL Keystore entry expected.:" + getMessageString(log),
- getMessageString(log).endsWith(new File(getConfigurationStringProperty("management.ssl.keyStorePath")).getName()));
- }
- }
-
- /**
- * Description: Tests the management connection open/close are logged correctly.
- *
- * Output:
- *
- * <date> MESSAGE MNG-1007 : Open : User <username>
- * <date> MESSAGE MNG-1008 : Close : User <username>
- *
- * Validation Steps:
- *
- * 1. The MNG ID is correct
- * 2. The message and username are correct
- */
- public void testManagementUserOpenClose() throws Exception
- {
- if (isJavaBroker())
- {
- startBrokerAndCreateMonitor(true, false);
-
- final JMXTestUtils jmxUtils = new JMXTestUtils(this);
- List<String> openResults = null;
- List<String> closeResults = null;
- try
- {
- jmxUtils.setUp();
- jmxUtils.open();
- openResults = waitAndFindMatches("MNG-1007");
- }
- finally
- {
- if (jmxUtils != null)
- {
- jmxUtils.close();
- closeResults = waitAndFindMatches("MNG-1008");
- }
- }
-
- assertNotNull("Management Open results null", openResults.size());
- assertEquals("Management Open logged unexpected number of times", 1, openResults.size());
-
- assertNotNull("Management Close results null", closeResults.size());
- assertEquals("Management Close logged unexpected number of times", 1, closeResults.size());
-
- final String openMessage = getMessageString(getLogMessage(openResults, 0));
- assertTrue("Unexpected open message " + openMessage, openMessage.endsWith("Open : User admin"));
- final String closeMessage = getMessageString(getLogMessage(closeResults, 0));
- assertTrue("Unexpected close message " + closeMessage, closeMessage.endsWith("Close : User admin"));
- }
- }
-
- private void startBrokerAndCreateMonitor(boolean managementEnabled, boolean useManagementSSL) throws Exception
- {
- //Ensure management is on
- setConfigurationProperty("management.enabled", String.valueOf(managementEnabled));
-
- if(useManagementSSL)
- {
- // This test requires we have an ssl connection
- setConfigurationProperty("management.ssl.enabled", "true");
- }
-
- startBroker();
-
- // Now we can create the monitor as _outputFile will now be defined
- _monitor = new LogMonitor(_outputFile);
- }
-}
diff --git a/java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/systest/management/jmx/QueueManagementTest.java b/java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/systest/management/jmx/QueueManagementTest.java
deleted file mode 100644
index 79d04b239e..0000000000
--- a/java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/systest/management/jmx/QueueManagementTest.java
+++ /dev/null
@@ -1,696 +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.systest.management.jmx;
-
-import org.apache.commons.lang.time.FastDateFormat;
-
-import org.apache.log4j.Logger;
-import org.apache.qpid.client.AMQSession;
-import org.apache.qpid.configuration.ClientProperties;
-import org.apache.qpid.framing.AMQShortString;
-import org.apache.qpid.management.common.mbeans.ManagedBroker;
-import org.apache.qpid.management.common.mbeans.ManagedQueue;
-import org.apache.qpid.server.queue.AMQQueueFactory;
-import org.apache.qpid.server.queue.NotificationCheckTest;
-import org.apache.qpid.server.queue.SimpleAMQQueueTest;
-import org.apache.qpid.test.client.destination.AddressBasedDestinationTest;
-import org.apache.qpid.test.utils.JMXTestUtils;
-import org.apache.qpid.test.utils.QpidBrokerTestCase;
-
-import javax.jms.Connection;
-import javax.jms.Destination;
-import javax.jms.JMSException;
-import javax.jms.Message;
-import javax.jms.MessageConsumer;
-import javax.jms.MessageListener;
-import javax.jms.Queue;
-import javax.jms.Session;
-import javax.jms.TextMessage;
-import javax.management.Notification;
-import javax.management.NotificationListener;
-import javax.management.openmbean.CompositeData;
-import javax.management.openmbean.TabularData;
-import javax.naming.NamingException;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.SortedSet;
-import java.util.TreeSet;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.concurrent.atomic.AtomicReference;
-
-/**
- * Tests the JMX API for the Managed Queue.
- *
- */
-public class QueueManagementTest extends QpidBrokerTestCase
-{
-
- private static final Logger LOGGER = Logger.getLogger(QueueManagementTest.class);
-
- private static final String VIRTUAL_HOST = "test";
- private static final String TEST_QUEUE_DESCRIPTION = "my description";
-
- private JMXTestUtils _jmxUtils;
- private Connection _connection;
- private Session _session;
-
- private String _sourceQueueName;
- private String _destinationQueueName;
- private Destination _sourceQueue;
- private Destination _destinationQueue;
- private ManagedQueue _managedSourceQueue;
- private ManagedQueue _managedDestinationQueue;
-
- public void setUp() throws Exception
- {
- _jmxUtils = new JMXTestUtils(this);
- _jmxUtils.setUp();
-
- super.setUp();
- _sourceQueueName = getTestQueueName() + "_src";
- _destinationQueueName = getTestQueueName() + "_dest";
-
- createConnectionAndSession();
-
- _sourceQueue = _session.createQueue(_sourceQueueName);
- _destinationQueue = _session.createQueue(_destinationQueueName);
- createQueueOnBroker(_sourceQueue);
- createQueueOnBroker(_destinationQueue);
-
- _jmxUtils.open();
-
- createManagementInterfacesForQueues();
- }
-
- public void tearDown() throws Exception
- {
- if (_jmxUtils != null)
- {
- _jmxUtils.close();
- }
- super.tearDown();
- }
-
- public void testQueueAttributes() throws Exception
- {
- Queue queue = _session.createQueue(getTestQueueName());
- createQueueOnBroker(queue);
-
- final String queueName = queue.getQueueName();
-
- final ManagedQueue managedQueue = _jmxUtils.getManagedQueue(queueName);
- assertEquals("Unexpected name", queueName, managedQueue.getName());
- assertEquals("Unexpected queue type", "standard", managedQueue.getQueueType());
- }
-
- public void testExclusiveQueueHasJmsClientIdAsOwner() throws Exception
- {
- Queue tmpQueue = _session.createTemporaryQueue();
-
- final String queueName = tmpQueue.getQueueName();
-
- final ManagedQueue managedQueue = _jmxUtils.getManagedQueue(queueName);
- assertNotNull(_connection.getClientID());
- assertEquals("Unexpected owner", _connection.getClientID(), managedQueue.getOwner());
- }
-
- public void testNonExclusiveQueueHasNoOwner() throws Exception
- {
- Queue nonExclusiveQueue = _session.createQueue(getTestQueueName());
- createQueueOnBroker(nonExclusiveQueue);
-
- final String queueName = nonExclusiveQueue.getQueueName();
-
- final ManagedQueue managedQueue = _jmxUtils.getManagedQueue(queueName);
- assertNull("Unexpected owner", managedQueue.getOwner());
- }
-
- public void testSetNewQueueDescriptionOnExistingQueue() throws Exception
- {
- Queue queue = _session.createQueue(getTestQueueName());
- createQueueOnBroker(queue);
-
- final String queueName = queue.getQueueName();
-
- final ManagedQueue managedQueue = _jmxUtils.getManagedQueue(queueName);
- assertNull("Unexpected description", managedQueue.getDescription());
-
- managedQueue.setDescription(TEST_QUEUE_DESCRIPTION);
- assertEquals(TEST_QUEUE_DESCRIPTION, managedQueue.getDescription());
- }
-
- public void testNewQueueWithDescription() throws Exception
- {
- String queueName = getTestQueueName();
- Map<String, Object> arguments = Collections.singletonMap(AMQQueueFactory.X_QPID_DESCRIPTION, (Object)TEST_QUEUE_DESCRIPTION);
- ((AMQSession<?, ?>)_session).createQueue(AMQShortString.valueOf(queueName), false, true, false, arguments);
-
- final ManagedQueue managedQueue = _jmxUtils.getManagedQueue(queueName);
- assertEquals(TEST_QUEUE_DESCRIPTION, managedQueue.getDescription());
- }
-
- /**
- * Requires persistent store.
- */
- public void testQueueDescriptionSurvivesRestart() throws Exception
- {
- String queueName = getTestQueueName();
- Map<String, Object> arguments = Collections.singletonMap(AMQQueueFactory.X_QPID_DESCRIPTION, (Object)TEST_QUEUE_DESCRIPTION);
-
- ((AMQSession<?, ?>)_session).createQueue(AMQShortString.valueOf(queueName), false, true, false, arguments);
-
- ManagedQueue managedQueue = _jmxUtils.getManagedQueue(queueName);
- assertEquals(TEST_QUEUE_DESCRIPTION, managedQueue.getDescription());
-
- restartBroker();
-
- managedQueue = _jmxUtils.getManagedQueue(queueName);
- assertEquals(TEST_QUEUE_DESCRIPTION, managedQueue.getDescription());
- }
-
- /**
- * Tests queue creation with {@link AMQQueueFactory#X_QPID_MAXIMUM_DELIVERY_COUNT} argument. Also tests
- * that the attribute is exposed correctly through {@link ManagedQueue#getMaximumDeliveryCount()}.
- */
- public void testCreateQueueWithMaximumDeliveryCountSet() throws Exception
- {
- final String queueName = getName();
- final ManagedBroker managedBroker = _jmxUtils.getManagedBroker(VIRTUAL_HOST);
-
- final Integer deliveryCount = 1;
- final Map<String, Object> arguments = Collections.singletonMap(AMQQueueFactory.X_QPID_MAXIMUM_DELIVERY_COUNT, (Object)deliveryCount);
- managedBroker.createNewQueue(queueName, null, true, arguments);
-
- // Ensure the queue exists
- assertNotNull("Queue object name expected to exist", _jmxUtils.getQueueObjectName("test", queueName));
- assertNotNull("Manager queue expected to be available", _jmxUtils.getManagedQueue(queueName));
-
- final ManagedQueue managedQueue = _jmxUtils.getManagedQueue(queueName);
- assertEquals("Unexpected maximum delivery count", deliveryCount, managedQueue.getMaximumDeliveryCount());
- }
-
- /**
- * Requires 0-10 as relies on ADDR addresses.
- * @see AddressBasedDestinationTest for the testing of message routing to the alternate exchange
- */
- public void testGetSetAlternateExchange() throws Exception
- {
- String queueName = getTestQueueName();
- String altExchange = "amq.fanout";
- String addrWithAltExch = String.format("ADDR:%s;{create:always,node:{type:queue,x-declare:{alternate-exchange:'%s'}}}", queueName, altExchange);
- Queue queue = _session.createQueue(addrWithAltExch);
-
- createQueueOnBroker(queue);
-
- final ManagedQueue managedQueue = _jmxUtils.getManagedQueue(queueName);
- assertEquals("Newly created queue does not have expected alternate exchange", altExchange, managedQueue.getAlternateExchange());
-
- String newAltExch = "amq.topic";
- managedQueue.setAlternateExchange(newAltExch);
- assertEquals("Unexpected alternate exchange after set", newAltExch, managedQueue.getAlternateExchange());
- }
-
- /**
- * Requires 0-10 as relies on ADDR addresses.
- */
- public void testRemoveAlternateExchange() throws Exception
- {
- String queueName = getTestQueueName();
- String altExchange = "amq.fanout";
- String addrWithAltExch = String.format("ADDR:%s;{create:always,node:{type:queue,x-declare:{alternate-exchange:'%s'}}}", queueName, altExchange);
- Queue queue = _session.createQueue(addrWithAltExch);
-
- createQueueOnBroker(queue);
-
- final ManagedQueue managedQueue = _jmxUtils.getManagedQueue(queueName);
- assertEquals("Newly created queue does not have expected alternate exchange", altExchange, managedQueue.getAlternateExchange());
-
- managedQueue.setAlternateExchange("");
- assertNull("Unexpected alternate exchange after set", managedQueue.getAlternateExchange());
- }
-
- /**
- * Requires persistent store
- * Requires 0-10 as relies on ADDR addresses.
- */
- public void testAlternateExchangeSurvivesRestart() throws Exception
- {
- String nonMandatoryExchangeName = "exch" + getName();
-
- final ManagedBroker managedBroker = _jmxUtils.getManagedBroker(VIRTUAL_HOST);
- managedBroker.createNewExchange(nonMandatoryExchangeName, "fanout", true);
-
- String queueName1 = getTestQueueName() + "1";
- String altExchange1 = "amq.fanout";
- String addr1WithAltExch = String.format("ADDR:%s;{create:always,node:{durable: true,type:queue,x-declare:{alternate-exchange:'%s'}}}", queueName1, altExchange1);
- Queue queue1 = _session.createQueue(addr1WithAltExch);
-
- String queueName2 = getTestQueueName() + "2";
- String addr2WithoutAltExch = String.format("ADDR:%s;{create:always,node:{durable: true,type:queue}}", queueName2);
- Queue queue2 = _session.createQueue(addr2WithoutAltExch);
-
- createQueueOnBroker(queue1);
- createQueueOnBroker(queue2);
-
- ManagedQueue managedQueue1 = _jmxUtils.getManagedQueue(queueName1);
- assertEquals("Newly created queue1 does not have expected alternate exchange", altExchange1, managedQueue1.getAlternateExchange());
-
- ManagedQueue managedQueue2 = _jmxUtils.getManagedQueue(queueName2);
- assertNull("Newly created queue2 does not have expected alternate exchange", managedQueue2.getAlternateExchange());
-
- String altExchange2 = nonMandatoryExchangeName;
- managedQueue2.setAlternateExchange(altExchange2);
-
- restartBroker();
-
- managedQueue1 = _jmxUtils.getManagedQueue(queueName1);
- assertEquals("Queue1 does not have expected alternate exchange after restart", altExchange1, managedQueue1.getAlternateExchange());
-
- managedQueue2 = _jmxUtils.getManagedQueue(queueName2);
- assertEquals("Queue2 does not have expected updated alternate exchange after restart", altExchange2, managedQueue2.getAlternateExchange());
- }
-
- /**
- * Tests the ability to receive queue alerts as JMX notifications.
- *
- * @see NotificationCheckTest
- * @see SimpleAMQQueueTest#testNotificationFiredAsync()
- * @see SimpleAMQQueueTest#testNotificationFiredOnEnqueue()
- */
- public void testQueueNotification() throws Exception
- {
- final String queueName = getName();
- final long maximumMessageCount = 3;
-
- Queue queue = _session.createQueue(queueName);
- createQueueOnBroker(queue);
-
- ManagedQueue managedQueue = _jmxUtils.getManagedQueue(queueName);
- managedQueue.setMaximumMessageCount(maximumMessageCount);
-
- RecordingNotificationListener listener = new RecordingNotificationListener(1);
-
- _jmxUtils.addNotificationListener(_jmxUtils.getQueueObjectName(VIRTUAL_HOST, queueName), listener, null, null);
-
- // Send two messages - this should *not* trigger the notification
- sendMessage(_session, queue, 2);
-
- assertEquals("Premature notification received", 0, listener.getNumberOfNotificationsReceived());
-
- // A further message should trigger the message count alert
- sendMessage(_session, queue, 1);
-
- listener.awaitExpectedNotifications(5, TimeUnit.SECONDS);
-
- assertEquals("Unexpected number of JMX notifications received", 1, listener.getNumberOfNotificationsReceived());
-
- Notification notification = listener.getLastNotification();
- assertEquals("Unexpected notification message", "MESSAGE_COUNT_ALERT 3: Maximum count on queue threshold (3) breached.", notification.getMessage());
- }
-
- /**
- * Tests {@link ManagedQueue#viewMessages(long, long)} interface.
- */
- public void testViewSingleMessage() throws Exception
- {
- final List<Message> sentMessages = sendMessage(_session, _sourceQueue, 1);
- syncSession(_session);
- final Message sentMessage = sentMessages.get(0);
-
- assertEquals("Unexpected queue depth", 1, _managedSourceQueue.getMessageCount().intValue());
-
- // Check the contents of the message
- final TabularData tab = _managedSourceQueue.viewMessages(1l, 1l);
- assertEquals("Unexpected number of rows in table", 1, tab.size());
- final Iterator<CompositeData> rowItr = (Iterator<CompositeData>) tab.values().iterator();
-
- final CompositeData row1 = rowItr.next();
- assertNotNull("Message should have AMQ message id", row1.get(ManagedQueue.MSG_AMQ_ID));
- assertEquals("Unexpected queue position", 1l, row1.get(ManagedQueue.MSG_QUEUE_POS));
- assertEquals("Unexpected redelivered flag", Boolean.FALSE, row1.get(ManagedQueue.MSG_REDELIVERED));
-
- // Check the contents of header (encoded in a string array)
- final String[] headerArray = (String[]) row1.get(ManagedQueue.MSG_HEADER);
- assertNotNull("Expected message header array", headerArray);
- final Map<String, String> headers = headerArrayToMap(headerArray);
-
- final String expectedJMSMessageID = isBroker010() ? sentMessage.getJMSMessageID().replace("ID:", "") : sentMessage.getJMSMessageID();
- final String expectedFormattedJMSTimestamp = FastDateFormat.getInstance(ManagedQueue.JMSTIMESTAMP_DATETIME_FORMAT).format(sentMessage.getJMSTimestamp());
- assertEquals("Unexpected JMSMessageID within header", expectedJMSMessageID, headers.get("JMSMessageID"));
- assertEquals("Unexpected JMSPriority within header", String.valueOf(sentMessage.getJMSPriority()), headers.get("JMSPriority"));
- assertEquals("Unexpected JMSTimestamp within header", expectedFormattedJMSTimestamp, headers.get("JMSTimestamp"));
- }
-
- /**
- * Tests {@link ManagedQueue#moveMessages(long, long, String)} interface.
- */
- public void testMoveMessagesBetweenQueues() throws Exception
- {
- final int numberOfMessagesToSend = 10;
-
- sendMessage(_session, _sourceQueue, numberOfMessagesToSend);
- syncSession(_session);
- assertEquals("Unexpected queue depth after send", numberOfMessagesToSend, _managedSourceQueue.getMessageCount().intValue());
-
- List<Long> amqMessagesIds = getAMQMessageIdsOn(_managedSourceQueue, 1, numberOfMessagesToSend);
-
- // Move first three messages to destination
- long fromMessageId = amqMessagesIds.get(0);
- long toMessageId = amqMessagesIds.get(2);
- _managedSourceQueue.moveMessages(fromMessageId, toMessageId, _destinationQueueName);
-
- assertEquals("Unexpected queue depth on destination queue after first move", 3, _managedDestinationQueue.getMessageCount().intValue());
- assertEquals("Unexpected queue depth on source queue after first move", 7, _managedSourceQueue.getMessageCount().intValue());
-
- // Now move a further two messages to destination
- fromMessageId = amqMessagesIds.get(7);
- toMessageId = amqMessagesIds.get(8);
- _managedSourceQueue.moveMessages(fromMessageId, toMessageId, _destinationQueueName);
- assertEquals("Unexpected queue depth on destination queue after second move", 5, _managedDestinationQueue.getMessageCount().intValue());
- assertEquals("Unexpected queue depth on source queue after second move", 5, _managedSourceQueue.getMessageCount().intValue());
-
- assertMessageIndicesOn(_destinationQueue, 0, 1, 2, 7, 8);
- }
-
- /**
- * Tests {@link ManagedQueue#copyMessages(long, long, String)} interface.
- */
- public void testCopyMessagesBetweenQueues() throws Exception
- {
- final int numberOfMessagesToSend = 10;
- sendMessage(_session, _sourceQueue, numberOfMessagesToSend);
- syncSession(_session);
- assertEquals("Unexpected queue depth after send", numberOfMessagesToSend, _managedSourceQueue.getMessageCount().intValue());
-
- List<Long> amqMessagesIds = getAMQMessageIdsOn(_managedSourceQueue, 1, numberOfMessagesToSend);
-
- // Copy first three messages to destination
- long fromMessageId = amqMessagesIds.get(0);
- long toMessageId = amqMessagesIds.get(2);
- _managedSourceQueue.copyMessages(fromMessageId, toMessageId, _destinationQueueName);
-
- assertEquals("Unexpected queue depth on destination queue after first copy", 3, _managedDestinationQueue.getMessageCount().intValue());
- assertEquals("Unexpected queue depth on source queue after first copy", numberOfMessagesToSend, _managedSourceQueue.getMessageCount().intValue());
-
- // Now copy a further two messages to destination
- fromMessageId = amqMessagesIds.get(7);
- toMessageId = amqMessagesIds.get(8);
- _managedSourceQueue.copyMessages(fromMessageId, toMessageId, _destinationQueueName);
- assertEquals("Unexpected queue depth on destination queue after second copy", 5, _managedDestinationQueue.getMessageCount().intValue());
- assertEquals("Unexpected queue depth on source queue after second copy", numberOfMessagesToSend, _managedSourceQueue.getMessageCount().intValue());
-
- assertMessageIndicesOn(_destinationQueue, 0, 1, 2, 7, 8);
- }
-
- public void testMoveMessagesBetweenQueuesWithActiveConsumerOnSourceQueue() throws Exception
- {
- setTestClientSystemProperty(ClientProperties.MAX_PREFETCH_PROP_NAME, new Integer(1).toString());
- Connection asyncConnection = getConnection();
- asyncConnection.start();
-
- final int numberOfMessagesToSend = 50;
- sendMessage(_session, _sourceQueue, numberOfMessagesToSend);
- syncSession(_session);
- assertEquals("Unexpected queue depth after send", numberOfMessagesToSend, _managedSourceQueue.getMessageCount().intValue());
-
- List<Long> amqMessagesIds = getAMQMessageIdsOn(_managedSourceQueue, 1, numberOfMessagesToSend);
-
- long fromMessageId = amqMessagesIds.get(0);
- long toMessageId = amqMessagesIds.get(numberOfMessagesToSend - 1);
-
- CountDownLatch consumerReadToHalfwayLatch = new CountDownLatch(numberOfMessagesToSend / 2);
- AtomicInteger totalConsumed = new AtomicInteger(0);
- startAsyncConsumerOn(_sourceQueue, asyncConnection, consumerReadToHalfwayLatch, totalConsumed);
-
- boolean halfwayPointReached = consumerReadToHalfwayLatch.await(5000, TimeUnit.MILLISECONDS);
- assertTrue("Did not read half of messages within time allowed", halfwayPointReached);
-
- _managedSourceQueue.moveMessages(fromMessageId, toMessageId, _destinationQueueName);
-
- asyncConnection.stop();
-
- // The exact number of messages moved will be non deterministic, as the number of messages processed
- // by the consumer cannot be predicted. There is also the possibility that a message can remain
- // on the source queue. This situation will arise if a message has been acquired by the consumer, but not
- // yet delivered to the client application (i.e. MessageListener#onMessage()) when the Connection#stop() occurs.
- //
- // The number of messages moved + the number consumed + any messages remaining on source should
- // *always* be equal to the number we originally sent.
-
- int numberOfMessagesReadByConsumer = totalConsumed.intValue();
- int numberOfMessagesOnDestinationQueue = _managedDestinationQueue.getMessageCount().intValue();
- int numberOfMessagesRemainingOnSourceQueue = _managedSourceQueue.getMessageCount().intValue();
-
- LOGGER.debug("Async consumer read : " + numberOfMessagesReadByConsumer
- + " Number of messages moved to destination : " + numberOfMessagesOnDestinationQueue
- + " Number of messages remaining on source : " + numberOfMessagesRemainingOnSourceQueue);
- assertEquals("Unexpected number of messages after move", numberOfMessagesToSend, numberOfMessagesReadByConsumer + numberOfMessagesOnDestinationQueue + numberOfMessagesRemainingOnSourceQueue);
- }
-
- public void testMoveMessagesBetweenQueuesWithActiveConsumerOnDestinationQueue() throws Exception
- {
- setTestClientSystemProperty(ClientProperties.MAX_PREFETCH_PROP_NAME, new Integer(1).toString());
- Connection asyncConnection = getConnection();
- asyncConnection.start();
-
- final int numberOfMessagesToSend = 50;
- sendMessage(_session, _sourceQueue, numberOfMessagesToSend);
- syncSession(_session);
- assertEquals("Unexpected queue depth after send", numberOfMessagesToSend, _managedSourceQueue.getMessageCount().intValue());
-
- List<Long> amqMessagesIds = getAMQMessageIdsOn(_managedSourceQueue, 1, numberOfMessagesToSend);
- long fromMessageId = amqMessagesIds.get(0);
- long toMessageId = amqMessagesIds.get(numberOfMessagesToSend - 1);
-
- AtomicInteger totalConsumed = new AtomicInteger(0);
- CountDownLatch allMessagesConsumedLatch = new CountDownLatch(numberOfMessagesToSend);
- startAsyncConsumerOn(_destinationQueue, asyncConnection, allMessagesConsumedLatch, totalConsumed);
-
- _managedSourceQueue.moveMessages(fromMessageId, toMessageId, _destinationQueueName);
-
- allMessagesConsumedLatch.await(5000, TimeUnit.MILLISECONDS);
- assertEquals("Did not consume all messages from destination queue", numberOfMessagesToSend, totalConsumed.intValue());
- }
-
- /**
- * Tests {@link ManagedQueue#moveMessages(long, long, String)} interface.
- */
- public void testMoveMessageBetweenQueuesWithBrokerRestart() throws Exception
- {
- final int numberOfMessagesToSend = 1;
-
- sendMessage(_session, _sourceQueue, numberOfMessagesToSend);
- syncSession(_session);
- assertEquals("Unexpected queue depth after send", numberOfMessagesToSend, _managedSourceQueue.getMessageCount().intValue());
-
- restartBroker();
-
- createManagementInterfacesForQueues();
- createConnectionAndSession();
-
- List<Long> amqMessagesIds = getAMQMessageIdsOn(_managedSourceQueue, 1, numberOfMessagesToSend);
-
- // Move messages to destination
- long messageId = amqMessagesIds.get(0);
- _managedSourceQueue.moveMessages(messageId, messageId, _destinationQueueName);
-
- assertEquals("Unexpected queue depth on destination queue after move", 1, _managedDestinationQueue.getMessageCount().intValue());
- assertEquals("Unexpected queue depth on source queue after move", 0, _managedSourceQueue.getMessageCount().intValue());
-
- assertMessageIndicesOn(_destinationQueue, 0);
- }
-
- /**
- * Tests {@link ManagedQueue#copyMessages(long, long, String)} interface.
- */
- public void testCopyMessageBetweenQueuesWithBrokerRestart() throws Exception
- {
- final int numberOfMessagesToSend = 1;
-
- sendMessage(_session, _sourceQueue, numberOfMessagesToSend);
- syncSession(_session);
- assertEquals("Unexpected queue depth after send", numberOfMessagesToSend, _managedSourceQueue.getMessageCount().intValue());
-
- restartBroker();
-
- createManagementInterfacesForQueues();
- createConnectionAndSession();
-
- List<Long> amqMessagesIds = getAMQMessageIdsOn(_managedSourceQueue, 1, numberOfMessagesToSend);
-
- // Move messages to destination
- long messageId = amqMessagesIds.get(0);
- _managedSourceQueue.copyMessages(messageId, messageId, _destinationQueueName);
-
- assertEquals("Unexpected queue depth on destination queue after copy", 1, _managedDestinationQueue.getMessageCount().intValue());
- assertEquals("Unexpected queue depth on source queue after copy", 1, _managedSourceQueue.getMessageCount().intValue());
-
- assertMessageIndicesOn(_destinationQueue, 0);
- }
-
- @Override
- public Message createNextMessage(Session session, int messageNumber) throws JMSException
- {
- Message message = session.createTextMessage(getContentForMessageNumber(messageNumber));
- message.setIntProperty(INDEX, messageNumber);
- return message;
- }
-
- private void startAsyncConsumerOn(Destination queue, Connection asyncConnection,
- final CountDownLatch requiredNumberOfMessagesRead, final AtomicInteger totalConsumed) throws Exception
- {
- Session session = asyncConnection.createSession(false, Session.AUTO_ACKNOWLEDGE);
- MessageConsumer consumer = session.createConsumer(queue);
- consumer.setMessageListener(new MessageListener()
- {
-
- @Override
- public void onMessage(Message arg0)
- {
- totalConsumed.incrementAndGet();
- requiredNumberOfMessagesRead.countDown();
- }
- });
- }
-
- private void assertMessageIndicesOn(Destination queue, int... expectedIndices) throws Exception
- {
- MessageConsumer consumer = _session.createConsumer(queue);
-
- for (int i : expectedIndices)
- {
- TextMessage message = (TextMessage)consumer.receive(1000);
- assertNotNull("Expected message with index " + i, message);
- assertEquals("Expected message with index " + i, i, message.getIntProperty(INDEX));
- assertEquals("Expected message content", getContentForMessageNumber(i), message.getText());
- }
-
- assertNull("Unexpected message encountered", consumer.receive(1000));
- }
-
- private List<Long> getAMQMessageIdsOn(ManagedQueue managedQueue, long startIndex, long endIndex) throws Exception
- {
- final SortedSet<Long> messageIds = new TreeSet<Long>();
-
- final TabularData tab = managedQueue.viewMessages(startIndex, endIndex);
- final Iterator<CompositeData> rowItr = (Iterator<CompositeData>) tab.values().iterator();
- while(rowItr.hasNext())
- {
- final CompositeData row = rowItr.next();
- long amqMessageId = (Long)row.get(ManagedQueue.MSG_AMQ_ID);
- messageIds.add(amqMessageId);
- }
-
- return new ArrayList<Long>(messageIds);
- }
-
- /**
- *
- * Utility method to convert array of Strings in the form x = y into a
- * map with key/value x =&gt; y.
- *
- */
- private Map<String,String> headerArrayToMap(final String[] headerArray)
- {
- final Map<String, String> headerMap = new HashMap<String, String>();
- final List<String> headerList = Arrays.asList(headerArray);
- for (Iterator<String> iterator = headerList.iterator(); iterator.hasNext();)
- {
- final String nameValuePair = iterator.next();
- final String[] nameValue = nameValuePair.split(" *= *", 2);
- headerMap.put(nameValue[0], nameValue[1]);
- }
- return headerMap;
- }
-
- private void createQueueOnBroker(Destination destination) throws JMSException
- {
- _session.createConsumer(destination).close(); // Create a consumer only to cause queue creation
- }
-
- private void syncSession(Session session) throws Exception
- {
- ((AMQSession<?,?>)session).sync();
- }
-
- private void createConnectionAndSession() throws JMSException,
- NamingException
- {
- _connection = getConnection();
- _connection.start();
- _session = _connection.createSession(true, Session.SESSION_TRANSACTED);
- }
-
- private void createManagementInterfacesForQueues()
- {
- _managedSourceQueue = _jmxUtils.getManagedQueue(_sourceQueueName);
- _managedDestinationQueue = _jmxUtils.getManagedQueue(_destinationQueueName);
- }
-
- private String getContentForMessageNumber(int msgCount)
- {
- return "Message count " + msgCount;
- }
-
- private final class RecordingNotificationListener implements NotificationListener
- {
- private final CountDownLatch _notificationReceivedLatch;
- private final AtomicInteger _numberOfNotifications;
- private final AtomicReference<Notification> _lastNotification;
-
- private RecordingNotificationListener(int expectedNumberOfNotifications)
- {
- _notificationReceivedLatch = new CountDownLatch(expectedNumberOfNotifications);
- _numberOfNotifications = new AtomicInteger(0);
- _lastNotification = new AtomicReference<Notification>();
- }
-
- @Override
- public void handleNotification(Notification notification, Object handback)
- {
- _lastNotification.set(notification);
- _numberOfNotifications.incrementAndGet();
- _notificationReceivedLatch.countDown();
- }
-
- public int getNumberOfNotificationsReceived()
- {
- return _numberOfNotifications.get();
- }
-
- public Notification getLastNotification()
- {
- return _lastNotification.get();
- }
-
- public void awaitExpectedNotifications(long timeout, TimeUnit timeunit) throws InterruptedException
- {
- _notificationReceivedLatch.await(timeout, timeunit);
- }
- }
-
-}
diff --git a/java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/systest/management/jmx/StatisticsTest.java b/java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/systest/management/jmx/StatisticsTest.java
deleted file mode 100644
index c3fff94923..0000000000
--- a/java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/systest/management/jmx/StatisticsTest.java
+++ /dev/null
@@ -1,204 +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.systest.management.jmx;
-
-import java.util.List;
-
-import javax.jms.Connection;
-import javax.jms.MessageConsumer;
-import javax.jms.Queue;
-import javax.jms.Session;
-
-import org.apache.qpid.client.AMQConnection;
-import org.apache.qpid.client.AMQSession;
-import org.apache.qpid.management.common.mbeans.ManagedBroker;
-import org.apache.qpid.management.common.mbeans.ManagedConnection;
-import org.apache.qpid.management.common.mbeans.ServerInformation;
-import org.apache.qpid.test.utils.JMXTestUtils;
-import org.apache.qpid.test.utils.QpidBrokerTestCase;
-
-public class StatisticsTest extends QpidBrokerTestCase
-{
- private static final String TEST_USER = "admin";
- private static final String TEST_PASSWORD = "admin";
- private static final int MESSAGE_COUNT_TEST = 5;
- private static final int MESSAGE_COUNT_DEV = 9;
-
- private JMXTestUtils _jmxUtils;
- private Connection _test1, _dev;
- private Session _testSession, _developmentSession;
- private Queue _developmentQueue, _testQueue;
- protected String _brokerUrl;
-
- @Override
- public void setUp() throws Exception
- {
- _jmxUtils = new JMXTestUtils(this, TEST_USER, TEST_PASSWORD);
- _jmxUtils.setUp();
-
- super.setUp();
-
- _brokerUrl = getBroker().toString();
- _test1 = new AMQConnection(_brokerUrl, TEST_USER, TEST_PASSWORD, "clientid", "test");
- _dev = new AMQConnection(_brokerUrl, TEST_USER, TEST_PASSWORD, "clientid", "development");
- _test1.start();
- _dev.start();
-
- _testSession = _test1.createSession(true, Session.SESSION_TRANSACTED);
- _developmentSession = _dev.createSession(true, Session.SESSION_TRANSACTED);
-
- _developmentQueue = _developmentSession.createQueue(getTestQueueName());
- _testQueue = _testSession.createQueue(getTestQueueName());
-
- //Create queues by opening and closing consumers
- final MessageConsumer testConsumer = _testSession.createConsumer(_testQueue);
- testConsumer.close();
- final MessageConsumer developmentConsumer = _developmentSession.createConsumer(_developmentQueue);
- developmentConsumer.close();
-
- _jmxUtils.open();
- }
-
- @Override
- public void tearDown() throws Exception
- {
- _jmxUtils.close();
-
- super.tearDown();
- }
-
- public void testInitialStatisticValues() throws Exception
- {
- //Check initial values
- checkSingleConnectionOnVHostStatistics("test", 0, 0, 0, 0);
- checkVHostStatistics("test", 0, 0, 0, 0);
- checkSingleConnectionOnVHostStatistics("development", 0, 0, 0, 0);
- checkVHostStatistics("development", 0, 0, 0, 0);
- checkBrokerStatistics(0, 0, 0, 0);
- }
-
- public void testSendOnSingleVHost() throws Exception
- {
- sendMessagesAndSync(_testSession, _testQueue, MESSAGE_COUNT_TEST);
-
- //Check values
- checkSingleConnectionOnVHostStatistics("test", MESSAGE_COUNT_TEST, 0, MESSAGE_COUNT_TEST * DEFAULT_MESSAGE_SIZE, 0);
- checkVHostStatistics("test", MESSAGE_COUNT_TEST, 0, MESSAGE_COUNT_TEST * DEFAULT_MESSAGE_SIZE, 0);
- checkSingleConnectionOnVHostStatistics("development", 0, 0, 0, 0);
- checkVHostStatistics("development", 0, 0, 0, 0);
- checkBrokerStatistics(MESSAGE_COUNT_TEST, 0, MESSAGE_COUNT_TEST * DEFAULT_MESSAGE_SIZE, 0);
- }
-
- public void testSendOnTwoVHosts() throws Exception
- {
- sendMessagesAndSync(_testSession, _testQueue, MESSAGE_COUNT_TEST);
- sendMessagesAndSync(_developmentSession, _developmentQueue, MESSAGE_COUNT_DEV);
-
- //Check values
- checkSingleConnectionOnVHostStatistics("test", MESSAGE_COUNT_TEST, 0, MESSAGE_COUNT_TEST * DEFAULT_MESSAGE_SIZE, 0);
- checkVHostStatistics("test", MESSAGE_COUNT_TEST, 0, MESSAGE_COUNT_TEST * DEFAULT_MESSAGE_SIZE, 0);
- checkSingleConnectionOnVHostStatistics("development", MESSAGE_COUNT_DEV, 0, MESSAGE_COUNT_DEV * DEFAULT_MESSAGE_SIZE, 0);
- checkVHostStatistics("development", MESSAGE_COUNT_DEV, 0, MESSAGE_COUNT_DEV * DEFAULT_MESSAGE_SIZE, 0);
- checkBrokerStatistics(MESSAGE_COUNT_TEST + MESSAGE_COUNT_DEV, 0, (MESSAGE_COUNT_TEST + MESSAGE_COUNT_DEV) * DEFAULT_MESSAGE_SIZE, 0);
- }
-
- public void testSendAndConsumeOnSingleVHost() throws Exception
- {
- sendMessagesAndSync(_testSession, _testQueue, MESSAGE_COUNT_TEST);
- consumeMessages(_testSession, _testQueue, MESSAGE_COUNT_TEST);
-
- //Check values
- checkSingleConnectionOnVHostStatistics("test", MESSAGE_COUNT_TEST, MESSAGE_COUNT_TEST, MESSAGE_COUNT_TEST * DEFAULT_MESSAGE_SIZE, MESSAGE_COUNT_TEST * DEFAULT_MESSAGE_SIZE);
- checkVHostStatistics("test", MESSAGE_COUNT_TEST, MESSAGE_COUNT_TEST, MESSAGE_COUNT_TEST * DEFAULT_MESSAGE_SIZE, MESSAGE_COUNT_TEST * DEFAULT_MESSAGE_SIZE);
- checkSingleConnectionOnVHostStatistics("development", 0, 0, 0, 0);
- checkVHostStatistics("development", 0, 0, 0, 0);
- checkBrokerStatistics(MESSAGE_COUNT_TEST, MESSAGE_COUNT_TEST, MESSAGE_COUNT_TEST * DEFAULT_MESSAGE_SIZE, MESSAGE_COUNT_TEST * DEFAULT_MESSAGE_SIZE);
- }
-
- public void testSendAndConsumeOnTwoVHosts() throws Exception
- {
- sendMessagesAndSync(_testSession, _testQueue, MESSAGE_COUNT_TEST);
- sendMessagesAndSync(_developmentSession, _developmentQueue, MESSAGE_COUNT_DEV);
- consumeMessages(_testSession, _testQueue, MESSAGE_COUNT_TEST);
- consumeMessages(_developmentSession, _developmentQueue, MESSAGE_COUNT_DEV);
-
- //Check values
- checkSingleConnectionOnVHostStatistics("test", MESSAGE_COUNT_TEST, MESSAGE_COUNT_TEST, MESSAGE_COUNT_TEST * DEFAULT_MESSAGE_SIZE, MESSAGE_COUNT_TEST * DEFAULT_MESSAGE_SIZE);
- checkVHostStatistics("test", MESSAGE_COUNT_TEST, MESSAGE_COUNT_TEST, MESSAGE_COUNT_TEST * DEFAULT_MESSAGE_SIZE, MESSAGE_COUNT_TEST * DEFAULT_MESSAGE_SIZE);
- checkSingleConnectionOnVHostStatistics("development", MESSAGE_COUNT_DEV, MESSAGE_COUNT_DEV, MESSAGE_COUNT_DEV * DEFAULT_MESSAGE_SIZE, MESSAGE_COUNT_DEV * DEFAULT_MESSAGE_SIZE);
- checkVHostStatistics("development", MESSAGE_COUNT_DEV, MESSAGE_COUNT_DEV, MESSAGE_COUNT_DEV * DEFAULT_MESSAGE_SIZE, MESSAGE_COUNT_DEV * DEFAULT_MESSAGE_SIZE);
- checkBrokerStatistics(MESSAGE_COUNT_TEST + MESSAGE_COUNT_DEV, MESSAGE_COUNT_TEST + MESSAGE_COUNT_DEV, (MESSAGE_COUNT_TEST + MESSAGE_COUNT_DEV) * DEFAULT_MESSAGE_SIZE, (MESSAGE_COUNT_TEST + MESSAGE_COUNT_DEV) * DEFAULT_MESSAGE_SIZE);
- }
-
- private void sendMessagesAndSync(Session session, Queue queue, int numberOfMessages) throws Exception
- {
- //Send messages via connection on and sync
- sendMessage(session, queue, numberOfMessages);
- ((AMQSession<?,?>)session).sync();
- }
-
- private void consumeMessages(Session session, Queue queue, int numberOfMessages) throws Exception
- {
- //consume the messages on the virtual host
- final MessageConsumer consumer = session.createConsumer(queue);
- for (int i = 0 ; i < numberOfMessages ; i++)
- {
- assertNotNull("an expected message was not received", consumer.receive(1500));
- }
- session.commit();
- consumer.close();
- }
-
- private void checkSingleConnectionOnVHostStatistics(String vHostName, long messagesSent, long messagesReceived, long dataSent, long dataReceived)
- {
- List<ManagedConnection> managedConnections = _jmxUtils.getManagedConnections(vHostName);
- assertEquals(1, managedConnections.size());
-
- ManagedConnection managedConnection = managedConnections.get(0);
-
- assertEquals(messagesSent, managedConnection.getTotalMessagesReceived());
- assertEquals(messagesReceived, managedConnection.getTotalMessagesDelivered());
-
- assertEquals(dataSent, managedConnection.getTotalDataReceived());
- assertEquals(dataReceived, managedConnection.getTotalDataDelivered());
- }
-
- private void checkVHostStatistics(String vHostName, long messagesSent, long messagesReceived, long dataSent, long dataReceived)
- {
- ManagedBroker vhost = _jmxUtils.getManagedBroker(vHostName);
-
- assertEquals(messagesSent, vhost.getTotalMessagesReceived());
- assertEquals(messagesReceived, vhost.getTotalMessagesDelivered());
-
- assertEquals(dataSent, vhost.getTotalDataReceived());
- assertEquals(dataReceived, vhost.getTotalDataDelivered());
- }
-
- private void checkBrokerStatistics(long messagesSent, long messagesReceived, long dataSent, long dataReceived)
- {
- ServerInformation broker = _jmxUtils.getServerInformation();
-
- assertEquals(messagesSent, broker.getTotalMessagesReceived());
- assertEquals(messagesReceived, broker.getTotalMessagesDelivered());
-
- assertEquals(dataSent, broker.getTotalDataReceived());
- assertEquals(dataReceived, broker.getTotalDataDelivered());
- }
-}
diff --git a/java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/systest/management/jmx/UserManagementTest.java b/java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/systest/management/jmx/UserManagementTest.java
deleted file mode 100644
index 62b1b554a9..0000000000
--- a/java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/systest/management/jmx/UserManagementTest.java
+++ /dev/null
@@ -1,251 +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.systest.management.jmx;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileReader;
-import java.io.FileWriter;
-import java.io.IOException;
-
-import javax.jms.Connection;
-import javax.jms.JMSException;
-
-import org.apache.qpid.management.common.mbeans.UserManagement;
-import org.apache.qpid.server.security.auth.database.PlainPasswordFilePrincipalDatabase;
-import org.apache.qpid.server.security.auth.database.PrincipalDatabase;
-import org.apache.qpid.test.utils.JMXTestUtils;
-import org.apache.qpid.test.utils.QpidBrokerTestCase;
-import org.apache.qpid.tools.security.Passwd;
-
-/**
- * System test for User Management.
- *
- */
-public class UserManagementTest extends QpidBrokerTestCase
-{
- private static final String TEST_NEWPASSWORD = "newpassword";
- private static final String TEST_PASSWORD = "password";
- private JMXTestUtils _jmxUtils;
- private String _testUserName;
- private File _passwordFile;
- private UserManagement _userManagement;
- private Passwd _passwd;
-
- public void setUp() throws Exception
- {
- _passwd = createPasswordEncodingUtility();
- _passwordFile = createTemporaryPasswordFileWithJmxAdminUser();
-
- setConfigurationProperty("security.pd-auth-manager.principal-database.class", getPrincipalDatabaseImplClass().getName());
- setConfigurationProperty("security.pd-auth-manager.principal-database.attributes.attribute.name", "passwordFile");
- setConfigurationProperty("security.pd-auth-manager.principal-database.attributes.attribute.value", _passwordFile.getAbsolutePath());
-
- _jmxUtils = new JMXTestUtils(this);
- _jmxUtils.setUp();
-
- super.setUp();
- _jmxUtils.open();
-
- _testUserName = getTestName() + System.currentTimeMillis();
-
- _userManagement = _jmxUtils.getUserManagement();
- }
-
-
- public void tearDown() throws Exception
- {
- try
- {
- if (_jmxUtils != null)
- {
- _jmxUtils.close();
- }
- }
- finally
- {
- super.tearDown();
- }
- }
-
- public void testCreateUser() throws Exception
- {
- final int initialNumberOfUsers = _userManagement.viewUsers().size();
- assertFileDoesNotContainsPasswordForUser(_testUserName);
-
- boolean success = _userManagement.createUser(_testUserName, TEST_PASSWORD);
- assertTrue("Should have been able to create new user " + _testUserName, success);
- assertEquals("Unexpected number of users after add", initialNumberOfUsers + 1, _userManagement.viewUsers().size());
-
- assertFileContainsPasswordForUser(_testUserName);
- }
-
- public void testJmsLoginForNewUser() throws Exception
- {
- assertJmsConnectionFails(_testUserName, TEST_PASSWORD);
- testCreateUser();
-
- assertJmsConnectionSucceeds(_testUserName, TEST_PASSWORD);
- }
-
- public void testDeleteUser() throws Exception
- {
- final int initialNumberOfUsers = _userManagement.viewUsers().size();
-
- testCreateUser();
-
- boolean success = _userManagement.deleteUser(_testUserName);
- assertTrue("Should have been able to delete new user " + _testUserName, success);
- assertEquals("Unexpected number of users after delete", initialNumberOfUsers, _userManagement.viewUsers().size());
- assertFileDoesNotContainsPasswordForUser(_testUserName);
- }
-
- public void testJmsLoginNotPossibleForDeletedUser() throws Exception
- {
- testDeleteUser();
-
- assertJmsConnectionFails(_testUserName, TEST_PASSWORD);
- }
-
- public void testSetPassword() throws Exception
- {
- testCreateUser();
-
- _userManagement.setPassword(_testUserName, TEST_NEWPASSWORD);
-
- assertFileContainsPasswordForUser(_testUserName);
- }
-
- public void testJmsLoginForPasswordChangedUser() throws Exception
- {
- testSetPassword();
-
- assertJmsConnectionSucceeds(_testUserName, TEST_NEWPASSWORD);
- assertJmsConnectionFails(_testUserName, TEST_PASSWORD);
- }
-
- public void testReload() throws Exception
- {
- writePasswordFile(_passwordFile, JMXTestUtils.DEFAULT_USERID, JMXTestUtils.DEFAULT_PASSWORD, _testUserName, TEST_PASSWORD);
-
- assertJmsConnectionFails(_testUserName, TEST_PASSWORD);
-
- _userManagement.reloadData();
-
- assertJmsConnectionSucceeds(_testUserName, TEST_PASSWORD);
- }
-
- protected Passwd createPasswordEncodingUtility()
- {
- return new Passwd()
- {
- @Override
- public String getOutput(String username, String password)
- {
- return username + ":" + password;
- }
- };
- }
-
- protected Class<? extends PrincipalDatabase> getPrincipalDatabaseImplClass()
- {
- return PlainPasswordFilePrincipalDatabase.class;
- }
-
- private File createTemporaryPasswordFileWithJmxAdminUser() throws Exception
- {
- File passwordFile = File.createTempFile("passwd", "pwd");
- passwordFile.deleteOnExit();
- writePasswordFile(passwordFile, JMXTestUtils.DEFAULT_USERID, JMXTestUtils.DEFAULT_PASSWORD);
- return passwordFile;
- }
-
- private void writePasswordFile(File passwordFile, String... userNamePasswordPairs) throws Exception
- {
- FileWriter writer = null;
- try
- {
- writer = new FileWriter(passwordFile);
- for (int i = 0; i < userNamePasswordPairs.length; i=i+2)
- {
- String username = userNamePasswordPairs[i];
- String password = userNamePasswordPairs[i+1];
- writer.append(_passwd.getOutput(username, password) + "\n");
- }
- }
- finally
- {
- writer.close();
- }
- }
-
-
- private void assertFileContainsPasswordForUser(String username) throws IOException
- {
- assertTrue("Could not find password for user " + username + " within " + _passwordFile, passwordFileContainsUser(username));
- }
-
- private void assertFileDoesNotContainsPasswordForUser(String username) throws IOException
- {
- assertFalse("Could not find password for user " + username + " within " + _passwordFile, passwordFileContainsUser(username));
- }
-
- private boolean passwordFileContainsUser(String username) throws IOException
- {
- BufferedReader reader = null;
- try
- {
- reader = new BufferedReader(new FileReader(_passwordFile));
- String line = reader.readLine();
- while(line != null)
- {
- if (line.startsWith(username))
- {
- return true;
- }
- line = reader.readLine();
- }
-
- return false;
- }
- finally
- {
- reader.close();
- }
- }
-
- private void assertJmsConnectionSucceeds(String username, String password) throws Exception
- {
- Connection connection = getConnection(username, password);
- assertNotNull(connection);
- }
-
- private void assertJmsConnectionFails(String username, String password) throws Exception
- {
- try
- {
- getConnection(username, password);
- fail("Exception not thrown");
- }
- catch (JMSException e)
- {
- // PASS
- }
- }
-}