You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by or...@apache.org on 2012/11/01 10:48:57 UTC
svn commit: r1404521 [1/6] - in
/qpid/branches/java-broker-config-qpid-4390/qpid/java: ./
broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/
broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/
bro...
Author: orudyy
Date: Thu Nov 1 09:48:52 2012
New Revision: 1404521
URL: http://svn.apache.org/viewvc?rev=1404521&view=rev
Log:
QPID-4390: WIP - Add ConfigurationEntryStore, implement XMLConfigurationEntryStore for existing broker XML configuration, add Recoverers to recover broker configured objects from the store
Added:
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/CustomRMIServerSocketFactory.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/ManagementLogonLogoffReporter.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/UsernameAccessor.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/UsernameCachingRMIJRMPServer.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/server/jmx/ManagementLogonLogoffReporterTest.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker/src/main/java/org/apache/qpid/server/BrokerLauncher.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfigurationEntry.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfigurationEntryStore.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfigurationEntryStoreException.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/IllegalConfigurationException.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/AttributeMap.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/AuthenticationProviderRecoverer.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/BrokerRecoverer.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/GroupProviderRecoverer.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/PortRecoverer.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/VirtualHostRecoverer.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/store/
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/store/PortConfigurationHelper.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/store/XMLConfigurationEntryStore.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker/src/main/java/org/apache/qpid/server/model/ConfiguredObjectType.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AuthenticationProviderFactory.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/PortAttributeDestringifier.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/PortFactory.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/AmqpPortAdapter.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker/src/main/java/org/apache/qpid/server/util/MapValueConverter.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/startup/
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/startup/BrokerRecovererTest.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/startup/GroupProviderRecovererTest.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/startup/VirtualHostRecovererTest.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/store/
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/store/PortConfigurationHelperTest.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker/src/test/java/org/apache/qpid/server/model/adapter/
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker/src/test/java/org/apache/qpid/server/model/adapter/AuthenticationProviderFactoryTest.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker/src/test/java/org/apache/qpid/server/model/adapter/PortAttributeDestringifierTest.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker/src/test/java/org/apache/qpid/server/model/adapter/PortFactoryTest.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker/src/test/java/org/apache/qpid/server/model/configuration/
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker/src/test/java/org/apache/qpid/server/model/configuration/ConfigurationEntryTest.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/manager/TestAuthenticationManagerFactory.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker/src/test/resources/
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker/src/test/resources/META-INF/
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker/src/test/resources/META-INF/services/
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker/src/test/resources/META-INF/services/org.apache.qpid.server.plugin.AuthenticationManagerFactory
Removed:
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/server/jmx/ManagementLogActorTest.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker/src/main/java/org/apache/qpid/server/Broker.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/ServerNetworkTransportConfiguration.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/HTTPPortAdapter.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AuthenticationManagerRegistry.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/IAuthenticationManagerRegistry.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/QpidAcceptor.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/manager/AuthenticationManagerRegistryTest.java
Modified:
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagement.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagedObjectRegistry.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagement.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/MBeanInvocationHandlerImpl.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/mbeans/VirtualHostMBean.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker/src/main/java/org/apache/qpid/server/Main.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/ServerConfiguration.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker/src/main/java/org/apache/qpid/server/model/AuthenticationProvider.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker/src/main/java/org/apache/qpid/server/model/Broker.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker/src/main/java/org/apache/qpid/server/model/ConfiguredObject.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker/src/main/java/org/apache/qpid/server/model/GroupProvider.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker/src/main/java/org/apache/qpid/server/model/Port.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker/src/main/java/org/apache/qpid/server/model/Protocol.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker/src/main/java/org/apache/qpid/server/model/Transport.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AbstractAdapter.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AuthenticationProviderAdapter.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/BindingAdapter.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/ConnectionAdapter.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/ConsumerAdapter.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/ExchangeAdapter.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/GroupProviderAdapter.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/PortAdapter.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/QueueAdapter.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/SessionAdapter.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/VirtualHostAdapter.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/VirtualHostAliasAdapter.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker/src/main/java/org/apache/qpid/server/plugin/AuthenticationManagerFactory.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker/src/main/java/org/apache/qpid/server/plugin/GroupManagerFactory.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/MultiVersionProtocolEngine.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/MultiVersionProtocolEngineFactory.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/ProtocolEngine_0_10.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/ApplicationRegistry.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/IApplicationRegistry.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AnonymousAuthenticationManagerFactory.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationManagerFactory.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/KerberosAuthenticationManagerFactory.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthManagerFactory.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationManagerFactory.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker/src/main/java/org/apache/qpid/server/security/group/FileGroupManagerFactory.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker/src/main/java/org/apache/qpid/server/security/group/GroupPrincipalAccessor.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHost.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostImpl.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostRegistry.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/ServerConfigurationTest.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker/src/test/java/org/apache/qpid/server/logging/actors/ManagementActorTest.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker/src/test/java/org/apache/qpid/server/protocol/MultiVersionProtocolEngineFactoryTest.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/SimpleAMQQueueTest.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthManagerFactoryTest.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationManagerFactoryTest.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker/src/test/java/org/apache/qpid/server/security/group/FileGroupManagerFactoryTest.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker/src/test/java/org/apache/qpid/server/security/group/GroupPrincipalAccessorTest.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker/src/test/java/org/apache/qpid/server/store/MessageStoreTest.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker/src/test/java/org/apache/qpid/server/subscription/SubscriptionFactoryImplTest.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker/src/test/java/org/apache/qpid/server/util/TestApplicationRegistry.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker/src/test/java/org/apache/qpid/server/virtualhost/MockVirtualHost.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/broker/src/test/java/org/apache/qpid/server/virtualhost/VirtualHostImplTest.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/common/src/main/java/org/apache/qpid/transport/NetworkTransportConfiguration.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/common/src/main/java/org/apache/qpid/transport/network/io/IoNetworkTransport.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/module.xml
qpid/branches/java-broker-config-qpid-4390/qpid/java/systests/src/main/java/org/apache/qpid/server/logging/VirtualHostLoggingTest.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/systests/src/main/java/org/apache/qpid/systest/management/jmx/BrokerManagementTest.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/systests/src/main/java/org/apache/qpid/systest/rest/Asserts.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/systests/src/main/java/org/apache/qpid/systest/rest/StructureRestTest.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/systests/src/main/java/org/apache/qpid/test/utils/InternalBrokerHolder.java
qpid/branches/java-broker-config-qpid-4390/qpid/java/systests/src/main/java/org/apache/qpid/test/utils/QpidBrokerTestCase.java
Modified: qpid/branches/java-broker-config-qpid-4390/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagement.java
URL: http://svn.apache.org/viewvc/qpid/branches/java-broker-config-qpid-4390/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagement.java?rev=1404521&r1=1404520&r2=1404521&view=diff
==============================================================================
--- qpid/branches/java-broker-config-qpid-4390/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagement.java (original)
+++ qpid/branches/java-broker-config-qpid-4390/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagement.java Thu Nov 1 09:48:52 2012
@@ -21,8 +21,9 @@
package org.apache.qpid.server.management.plugin;
import java.io.File;
-import java.util.ArrayList;
import java.util.Collection;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.log4j.Logger;
@@ -50,7 +51,7 @@ 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.State;
import org.apache.qpid.server.model.User;
import org.apache.qpid.server.model.VirtualHost;
import org.eclipse.jetty.server.Connector;
@@ -72,79 +73,135 @@ public class HttpManagement implements M
private final Broker _broker;
- private final Collection<Server> _servers = new ArrayList<Server>();
+ private final Map<Integer, Server> _servers = new ConcurrentHashMap<Integer, Server>();
- private final String _keyStorePassword;
- private final String _keyStorePath;
- private final int _sessionTimeout;
+ private String _keyStorePassword;
+ private String _keyStorePath;
+ private int _sessionTimeout;
+ // XXX refactor back to use a single instance of server and add connectors for different ports
public HttpManagement(Broker broker, String keyStorePath, String keyStorePassword, int sessionTimeout) throws ConfigurationException
{
_broker = broker;
_keyStorePassword = keyStorePassword;
_keyStorePath = keyStorePath;
_sessionTimeout = sessionTimeout;
+ }
+
+ @Override
+ public void start() throws Exception
+ {
+ CurrentActor.get().message(ManagementConsoleMessages.STARTUP(OPERATIONAL_LOGGING_NAME));
- Collection<Port> ports = broker.getPorts();
- int httpPort = -1, httpsPort = -1;
+ Collection<Port> ports = _broker.getPorts();
for (Port port : ports)
{
- if (port.getProtocols().contains(Protocol.HTTP))
+ if (isManagementHttp(port))
{
- if (port.getTransports().contains(Transport.TCP))
+ if(port.getActualState() == State.ACTIVE)
{
- httpPort = port.getPort();
- }
- }
- if (port.getProtocols().contains(Protocol.HTTPS))
- {
- if (port.getTransports().contains(Transport.SSL))
- {
- httpsPort = port.getPort();
+ startServer(port);
}
}
}
- if (httpPort != -1 || httpsPort != -1)
+ CurrentActor.get().message(ManagementConsoleMessages.READY(OPERATIONAL_LOGGING_NAME));
+ }
+
+ @Override
+ public void stop() throws Exception
+ {
+ Collection<Port> ports = _broker.getPorts();
+ for (Port port : ports)
{
- _servers.add(createServer(httpPort, httpsPort));
- if (_logger.isDebugEnabled())
+ if (isManagementHttp(port))
{
- _logger.debug(_servers.size() + " server(s) defined");
+ stopServer(port);
}
}
- else
+ CurrentActor.get().message(ManagementConsoleMessages.STOPPED(OPERATIONAL_LOGGING_NAME));
+ }
+
+ /** Added for testing purposes */
+ Broker getBroker()
+ {
+ return _broker;
+ }
+
+ /** Added for testing purposes */
+ String getKeyStorePassword()
+ {
+ return _keyStorePassword;
+ }
+
+ /** Added for testing purposes */
+ String getKeyStorePath()
+ {
+ return _keyStorePath;
+ }
+
+ /** Added for testing purposes */
+ int getSessionTimeout()
+ {
+ return _sessionTimeout;
+ }
+
+ protected void stopServer(Port port)
+ {
+ Server server = _servers.remove(port.getPort());
+ if (server != null)
{
- if (_logger.isInfoEnabled())
+ try
+ {
+ server.stop();
+ logOperationalShutdownMessage(server);
+ }
+ catch (Exception e)
{
- _logger.info("Cannot create web server as neither HTTP nor HTTPS port specified");
+ throw new RuntimeException("Failed to stop http management on port " + port.getPort());
}
}
}
+ private void startServer(Port port)
+ {
+ Server server = createServer(port);
+ try
+ {
+ server.start();
+
+ logOperationalListenMessages(server);
+
+ _servers.put(port.getPort(), server);
+ }
+ catch (Exception e)
+ {
+ throw new RuntimeException("Failed to start http management on port " + port.getPort());
+ }
+ }
+
+ private boolean isManagementHttp(Port port)
+ {
+ return port.getProtocols().contains(Protocol.HTTP) || port.getProtocols().contains(Protocol.HTTPS);
+ }
+
@SuppressWarnings("unchecked")
- private Server createServer(int port, int sslPort) throws ConfigurationException
+ private Server createServer(Port port)
{
if (_logger.isInfoEnabled())
{
- _logger.info("Starting up web server on" + (port == -1 ? "" : " HTTP port " + port)
- + (sslPort == -1 ? "" : " HTTPS port " + sslPort));
+ _logger.info("Starting up web server on " + port.getPort());
}
Server server = new Server();
- if (port != -1)
+ final Collection<Protocol> protocols = port.getProtocols();
+ Connector connector = null;
+ if (protocols.contains(Protocol.HTTP))
{
- SelectChannelConnector connector = new SelectChannelConnector();
- connector.setPort(port);
- if (sslPort != -1)
- {
- connector.setConfidentialPort(sslPort);
- }
- server.addConnector(connector);
+ connector = new SelectChannelConnector();
}
-
- if (sslPort != -1)
+ else if (protocols.contains(Protocol.HTTPS))
{
checkKeyStorePath(_keyStorePath);
@@ -152,10 +209,14 @@ public class HttpManagement implements M
factory.setKeyStorePath(_keyStorePath);
factory.setKeyStorePassword(_keyStorePassword);
- SslSocketConnector connector = new SslSocketConnector(factory);
- connector.setPort(sslPort);
- server.addConnector(connector);
+ 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("/");
@@ -209,50 +270,22 @@ public class HttpManagement implements M
root.addServlet(new ServletHolder(new RestServlet(_broker, hierarchy)), "/rest/" + name + "/*");
}
- @Override
- public void start() throws Exception
- {
- CurrentActor.get().message(ManagementConsoleMessages.STARTUP(OPERATIONAL_LOGGING_NAME));
-
- for (Server server : _servers)
- {
- server.start();
-
- logOperationalListenMessages(server);
- }
-
- CurrentActor.get().message(ManagementConsoleMessages.READY(OPERATIONAL_LOGGING_NAME));
- }
-
- @Override
- public void stop() throws Exception
- {
- for (Server server : _servers)
- {
- logOperationalShutdownMessage(server);
-
- server.stop();
- }
-
- CurrentActor.get().message(ManagementConsoleMessages.STOPPED(OPERATIONAL_LOGGING_NAME));
- }
-
- private void checkKeyStorePath(String keyStorePath) throws ConfigurationException
+ private void checkKeyStorePath(String keyStorePath)
{
if (keyStorePath == null)
{
- throw new ConfigurationException("Management SSL keystore path not defined, unable to start SSL protected HTTP connector");
+ throw new RuntimeException("Management SSL keystore path not defined, unable to start SSL protected HTTP connector");
}
else
{
File ksf = new File(keyStorePath);
if (!ksf.exists())
{
- throw new ConfigurationException("Cannot find management SSL keystore file: " + ksf);
+ throw new RuntimeException("Cannot find management SSL keystore file: " + ksf);
}
if (!ksf.canRead())
{
- throw new ConfigurationException("Cannot read management SSL keystore file: " + ksf + ". Check permissions.");
+ throw new RuntimeException("Cannot read management SSL keystore file: " + ksf + ". Check permissions.");
}
}
}
@@ -287,28 +320,4 @@ public class HttpManagement implements M
{
return connector instanceof SslSocketConnector ? "HTTPS" : "HTTP";
}
-
- /** Added for testing purposes */
- Broker getBroker()
- {
- return _broker;
- }
-
- /** Added for testing purposes */
- String getKeyStorePassword()
- {
- return _keyStorePassword;
- }
-
- /** Added for testing purposes */
- String getKeyStorePath()
- {
- return _keyStorePath;
- }
-
- /** Added for testing purposes */
- int getSessionTimeout()
- {
- return _sessionTimeout;
- }
}
Added: qpid/branches/java-broker-config-qpid-4390/qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/CustomRMIServerSocketFactory.java
URL: http://svn.apache.org/viewvc/qpid/branches/java-broker-config-qpid-4390/qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/CustomRMIServerSocketFactory.java?rev=1404521&view=auto
==============================================================================
--- qpid/branches/java-broker-config-qpid-4390/qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/CustomRMIServerSocketFactory.java (added)
+++ qpid/branches/java-broker-config-qpid-4390/qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/CustomRMIServerSocketFactory.java Thu Nov 1 09:48:52 2012
@@ -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
Modified: qpid/branches/java-broker-config-qpid-4390/qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagedObjectRegistry.java
URL: http://svn.apache.org/viewvc/qpid/branches/java-broker-config-qpid-4390/qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagedObjectRegistry.java?rev=1404521&r1=1404520&r2=1404521&view=diff
==============================================================================
--- qpid/branches/java-broker-config-qpid-4390/qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagedObjectRegistry.java (original)
+++ qpid/branches/java-broker-config-qpid-4390/qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagedObjectRegistry.java Thu Nov 1 09:48:52 2012
@@ -26,50 +26,40 @@ import org.apache.qpid.AMQException;
import org.apache.qpid.server.configuration.ServerConfiguration;
import org.apache.qpid.server.logging.actors.CurrentActor;
import org.apache.qpid.server.logging.messages.ManagementConsoleMessages;
-
+import org.apache.qpid.server.model.Port;
+import org.apache.qpid.server.model.Transport;
import org.apache.qpid.server.registry.ApplicationRegistry;
-import org.apache.qpid.server.security.auth.AuthenticatedPrincipal;
+import org.apache.qpid.server.registry.IApplicationRegistry;
import org.apache.qpid.server.security.auth.rmi.RMIPasswordAuthenticator;
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.MalformedURLException;
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
@@ -82,20 +72,21 @@ public class JMXManagedObjectRegistry im
private static final String OPERATIONAL_LOGGING_NAME = "JMX";
private final MBeanServer _mbeanServer;
+ private final boolean _useCustomSocketFactory;
+ private final ServerConfiguration _serverConfiguration;
+
private JMXConnectorServer _cs;
private Registry _rmiRegistry;
- private boolean _useCustomSocketFactory;
- private final int _jmxPortRegistryServer;
- private final int _jmxPortConnectorServer;
-
- private final ServerConfiguration _serverConfiguration;
+ private Port _registryPort;
+ private Port _connectorPort;
- public JMXManagedObjectRegistry(ServerConfiguration serverConfiguration) throws AMQException
+ // XXX get rid from ServerConfiguration
+ public JMXManagedObjectRegistry(ServerConfiguration serverConfiguration, Port connectorPort, Port registryPort) throws AMQException
{
- _log.info("Initialising managed object registry using platform MBean server");
-
_serverConfiguration = serverConfiguration;
+ _registryPort = registryPort;
+ _connectorPort = connectorPort;
// Retrieve the config parameters
_useCustomSocketFactory = _serverConfiguration.getUseCustomRMISocketFactory();
@@ -104,11 +95,9 @@ public class JMXManagedObjectRegistry im
_mbeanServer =
platformServer ? ManagementFactory.getPlatformMBeanServer()
: MBeanServerFactory.createMBeanServer(ManagedObject.DOMAIN);
-
- _jmxPortRegistryServer = _serverConfiguration.getJMXPortRegistryServer();
- _jmxPortConnectorServer = _serverConfiguration.getJMXConnectorServerPort();
}
+ @Override
public void start() throws IOException, ConfigurationException
{
CurrentActor.get().message(ManagementConsoleMessages.STARTUP(OPERATIONAL_LOGGING_NAME));
@@ -117,48 +106,33 @@ public class JMXManagedObjectRegistry im
if (areOutOfTheBoxJMXOptionsSet())
{
CurrentActor.get().message(ManagementConsoleMessages.READY(OPERATIONAL_LOGGING_NAME));
- return;
}
+ else
+ {
+ startRegistryAndConnector();
+ }
+ }
- //Socket factories for the RMIConnectorServer, either default or SLL depending on configuration
+ private void startRegistryAndConnector() throws ConfigurationException,
+ FileNotFoundException, RemoteException, IOException,
+ MalformedURLException
+ {
+ //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 = _serverConfiguration.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
String keyStorePath = _serverConfiguration.getManagementKeyStorePath();
+ checkKeyStorePathExistsAndIsReadable(keyStorePath);
- //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 (for use by SslRMIClientSocketFactory and SslRMIServerSocketFactory)
- 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()));
- }
+ CurrentActor.get().message(ManagementConsoleMessages.SSL_KEYSTORE(keyStorePath));
if (_serverConfiguration.getManagementKeyStorePassword() == null)
{
@@ -167,8 +141,7 @@ public class JMXManagedObjectRegistry im
}
else
{
- System.setProperty("javax.net.ssl.keyStorePassword",
- _serverConfiguration.getManagementKeyStorePassword());
+ System.setProperty("javax.net.ssl.keyStorePassword", _serverConfiguration.getManagementKeyStorePassword());
}
//create the SSL RMI socket factories
@@ -182,10 +155,14 @@ public class JMXManagedObjectRegistry im
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(ApplicationRegistry.getInstance(), new InetSocketAddress(_jmxPortRegistryServer));
- HashMap<String,Object> env = new HashMap<String,Object>();
- env.put(JMXConnectorServer.AUTHENTICATOR, rmipa);
+ final IApplicationRegistry appRegistry = ApplicationRegistry.getInstance();
+ RMIPasswordAuthenticator rmipa = new RMIPasswordAuthenticator(appRegistry, new InetSocketAddress(jmxPortRegistryServer));
+ HashMap<String,Object> connectorEnv = new HashMap<String,Object>();
+ connectorEnv.put(JMXConnectorServer.AUTHENTICATOR, rmipa);
/*
* Start a RMI registry on the management port, to hold the JMX RMI ConnectorServer stub.
@@ -193,18 +170,7 @@ public class JMXManagedObjectRegistry im
* 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)
- {
- _log.debug("Using custom RMIServerSocketFactory");
- _rmiRegistry = LocateRegistry.createRegistry(_jmxPortRegistryServer, null, new CustomRMIServerSocketFactory());
- }
- else
- {
- _log.debug("Using default RMIServerSocketFactory");
- _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
@@ -212,57 +178,16 @@ public class JMXManagedObjectRegistry im
* 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)
- {
+ final UsernameCachingRMIJRMPServer usernameCachingRmiServer = new UsernameCachingRMIJRMPServer(jmxPortConnectorServer, csf, ssf, connectorEnv);
- /**
- * 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 JMX 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 AuthenticatedPrincipal authenticatedPrincipalFromSubject = AuthenticatedPrincipal.getAuthenticatedPrincipalFromSubject(subject);
- connectionIdUsernameMap.put(connectionId, authenticatedPrincipalFromSubject.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);
- }
- };
-
- 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
@@ -270,7 +195,7 @@ public class JMXManagedObjectRegistry im
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)
{
@@ -298,7 +223,6 @@ public class JMXManagedObjectRegistry im
}
catch (NotBoundException nbe)
{
- // TODO consider if we want to keep new logging
_log.error("Failed to unbind jmxrmi", nbe);
//ignore
}
@@ -313,97 +237,104 @@ public class JMXManagedObjectRegistry im
//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();
_cs.setMBeanServerForwarder(mbsf);
+ // Install a ManagementLogonLogoffReporter so we can report as users logon/logoff
+ ManagementLogonLogoffReporter jmxManagementUserLogonLogoffReporter = new ManagementLogonLogoffReporter(appRegistry.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));
-
+ 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());
}
+ else
+ {
+ _log.debug("Using default RMIServerSocketFactory");
+ rmiRegistry = LocateRegistry.createRegistry(jmxPortRegistryServer, null, null);
+ }
+
+ CurrentActor.get().message(ManagementConsoleMessages.LISTENING("RMI Registry", jmxPortRegistryServer));
+ return rmiRegistry;
+ }
- private static class NoLocalAddressServerSocket extends ServerSocket
+ private void checkKeyStorePathExistsAndIsReadable(String keyStorePath)
+ throws ConfigurationException, FileNotFoundException
+ {
+ //check the keystore path value is valid
+ if (keyStorePath == null)
{
- NoLocalAddressServerSocket(int port) throws IOException
- {
- super(port);
- }
+ throw new ConfigurationException("JMX management SSL keystore path not defined, " +
+ "unable to start SSL protected JMX ConnectorServer");
+ }
+ else
+ {
+ //ensure the system property is set (for use by SslRMIClientSocketFactory and SslRMIServerSocketFactory)
+ System.setProperty("javax.net.ssl.keyStore", keyStorePath);
- @Override
- public Socket accept() throws IOException
+ //check the file is usable
+ File ksf = new File(keyStorePath);
+
+ if (!ksf.exists())
{
- Socket s = new NoLocalAddressSocket();
- super.implAccept(s);
- return s;
+ throw new FileNotFoundException("Cannot find JMX management SSL keystore file: " + ksf);
}
- }
-
- private static class NoLocalAddressSocket extends Socket
- {
- @Override
- public InetAddress getInetAddress()
+ if (!ksf.canRead())
{
- return null;
+ 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()
{
@@ -420,29 +351,26 @@ public class JMXManagedObjectRegistry im
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);
@@ -455,8 +383,36 @@ public class JMXManagedObjectRegistry im
{
_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
@@ -479,8 +435,6 @@ public class JMXManagedObjectRegistry im
_log.error("Exception unregistering MBean '"+ name +"': " + e.getMessage());
}
}
-
- CurrentActor.get().message(ManagementConsoleMessages.STOPPED(OPERATIONAL_LOGGING_NAME));
}
}
Modified: qpid/branches/java-broker-config-qpid-4390/qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagement.java
URL: http://svn.apache.org/viewvc/qpid/branches/java-broker-config-qpid-4390/qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagement.java?rev=1404521&r1=1404520&r2=1404521&view=diff
==============================================================================
--- qpid/branches/java-broker-config-qpid-4390/qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagement.java (original)
+++ qpid/branches/java-broker-config-qpid-4390/qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagement.java Thu Nov 1 09:48:52 2012
@@ -21,6 +21,7 @@
package org.apache.qpid.server.jmx;
+import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import javax.management.JMException;
@@ -35,10 +36,13 @@ import org.apache.qpid.server.jmx.mbeans
import org.apache.qpid.server.jmx.mbeans.VirtualHostMBean;
import org.apache.qpid.server.logging.log4j.LoggingManagementFacade;
import org.apache.qpid.server.management.plugin.ManagementPlugin;
+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.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.plugin.QpidServiceLoader;
@@ -47,6 +51,9 @@ public class JMXManagement implements Co
{
private static final Logger LOGGER = Logger.getLogger(JMXManagement.class);
+ private static final String REGISTRY_PORT_NAME = "registry";
+ private static final String CONNECTOR_PORT_NAME = "connector";
+
private final Broker _broker;
private JMXManagedObjectRegistry _objectRegistry;
@@ -63,16 +70,56 @@ public class JMXManagement implements Co
@Override
public void start() throws Exception
{
- _objectRegistry = new JMXManagedObjectRegistry(_serverConfiguration);
+ Port connectorPort = null;
+ Port registryPort = null;
+ Collection<Port> ports = _broker.getPorts();
+ for (Port port : ports)
+ {
+ if (port.getProtocols().contains(Protocol.JMX_RMI))
+ {
+ if(REGISTRY_PORT_NAME.equals(port.getName()))
+ {
+ registryPort = port;
+ }
+ else if(CONNECTOR_PORT_NAME.equals(port.getName()))
+ {
+ connectorPort = port;
+ }
+ }
+ }
+ if(connectorPort == null)
+ {
+ throw new IllegalStateException("No JMX port found with name " + CONNECTOR_PORT_NAME);
+ }
+ if(registryPort == null)
+ {
+ throw new IllegalStateException("No JMX port found with name " + REGISTRY_PORT_NAME);
+ }
+
+ //XXX review MBean creation process
+ _objectRegistry = new JMXManagedObjectRegistry(_serverConfiguration, connectorPort, registryPort);
_broker.addChangeListener(this);
+
synchronized (_children)
{
for(VirtualHost virtualHost : _broker.getVirtualHosts())
{
if(!_children.containsKey(virtualHost))
{
- _children.put(virtualHost, new VirtualHostMBean(virtualHost, _objectRegistry));
+ VirtualHostMBean mbean = new VirtualHostMBean(virtualHost, _objectRegistry);
+ 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);
}
}
}
@@ -86,16 +133,37 @@ public class JMXManagement implements Co
@Override
public 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)
@@ -130,7 +198,7 @@ public class JMXManagement implements Co
}
}
-
+ @Override
public void childRemoved(ConfiguredObject object, ConfiguredObject child)
{
// TODO - implement vhost removal (possibly just removing the instanceof check below)
Modified: qpid/branches/java-broker-config-qpid-4390/qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/MBeanInvocationHandlerImpl.java
URL: http://svn.apache.org/viewvc/qpid/branches/java-broker-config-qpid-4390/qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/MBeanInvocationHandlerImpl.java?rev=1404521&r1=1404520&r2=1404521&view=diff
==============================================================================
--- qpid/branches/java-broker-config-qpid-4390/qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/MBeanInvocationHandlerImpl.java (original)
+++ qpid/branches/java-broker-config-qpid-4390/qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/MBeanInvocationHandlerImpl.java Thu Nov 1 09:48:52 2012
@@ -22,10 +22,8 @@ package org.apache.qpid.server.jmx;
import org.apache.log4j.Logger;
-import org.apache.qpid.server.logging.LogActor;
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.security.SecurityManager;
@@ -37,11 +35,8 @@ 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.MBeanServerForwarder;
import javax.security.auth.Subject;
import java.lang.reflect.InvocationHandler;
@@ -51,13 +46,12 @@ import java.lang.reflect.Proxy;
import java.security.AccessControlContext;
import java.security.AccessController;
import java.util.Arrays;
-import java.util.Map;
/**
* 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);
@@ -361,51 +355,5 @@ public class MBeanInvocationHandlerImpl
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)
- {
- @SuppressWarnings("unchecked")
- 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));
- }
- }
}
Added: qpid/branches/java-broker-config-qpid-4390/qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/ManagementLogonLogoffReporter.java
URL: http://svn.apache.org/viewvc/qpid/branches/java-broker-config-qpid-4390/qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/ManagementLogonLogoffReporter.java?rev=1404521&view=auto
==============================================================================
--- qpid/branches/java-broker-config-qpid-4390/qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/ManagementLogonLogoffReporter.java (added)
+++ qpid/branches/java-broker-config-qpid-4390/qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/ManagementLogonLogoffReporter.java Thu Nov 1 09:48:52 2012
@@ -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);
+ }
+
+}
Added: qpid/branches/java-broker-config-qpid-4390/qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/UsernameAccessor.java
URL: http://svn.apache.org/viewvc/qpid/branches/java-broker-config-qpid-4390/qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/UsernameAccessor.java?rev=1404521&view=auto
==============================================================================
--- qpid/branches/java-broker-config-qpid-4390/qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/UsernameAccessor.java (added)
+++ qpid/branches/java-broker-config-qpid-4390/qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/UsernameAccessor.java Thu Nov 1 09:48:52 2012
@@ -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);
+
+}
Added: qpid/branches/java-broker-config-qpid-4390/qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/UsernameCachingRMIJRMPServer.java
URL: http://svn.apache.org/viewvc/qpid/branches/java-broker-config-qpid-4390/qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/UsernameCachingRMIJRMPServer.java?rev=1404521&view=auto
==============================================================================
--- qpid/branches/java-broker-config-qpid-4390/qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/UsernameCachingRMIJRMPServer.java (added)
+++ qpid/branches/java-broker-config-qpid-4390/qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/UsernameCachingRMIJRMPServer.java Thu Nov 1 09:48:52 2012
@@ -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
Modified: qpid/branches/java-broker-config-qpid-4390/qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/mbeans/VirtualHostMBean.java
URL: http://svn.apache.org/viewvc/qpid/branches/java-broker-config-qpid-4390/qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/mbeans/VirtualHostMBean.java?rev=1404521&r1=1404520&r2=1404521&view=diff
==============================================================================
--- qpid/branches/java-broker-config-qpid-4390/qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/mbeans/VirtualHostMBean.java (original)
+++ qpid/branches/java-broker-config-qpid-4390/qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/mbeans/VirtualHostMBean.java Thu Nov 1 09:48:52 2012
@@ -65,7 +65,7 @@ public class VirtualHostMBean extends AM
_managerMBean = new VirtualHostManagerMBean(this);
}
- private void initQueues() throws JMException
+ private void initQueues()
{
synchronized (_children)
{
@@ -73,13 +73,20 @@ public class VirtualHostMBean extends AM
{
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 AM
{
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 AM
{
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 AM
public void stateChanged(ConfiguredObject object, State oldState, State newState)
{
- // ignore
+ // no-op
}
public void childAdded(ConfiguredObject object, ConfiguredObject child)
@@ -208,4 +229,29 @@ public class VirtualHostMBean extends AM
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();
+ }
+
}
Added: qpid/branches/java-broker-config-qpid-4390/qpid/java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/server/jmx/ManagementLogonLogoffReporterTest.java
URL: http://svn.apache.org/viewvc/qpid/branches/java-broker-config-qpid-4390/qpid/java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/server/jmx/ManagementLogonLogoffReporterTest.java?rev=1404521&view=auto
==============================================================================
--- qpid/branches/java-broker-config-qpid-4390/qpid/java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/server/jmx/ManagementLogonLogoffReporterTest.java (added)
+++ qpid/branches/java-broker-config-qpid-4390/qpid/java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/server/jmx/ManagementLogonLogoffReporterTest.java Thu Nov 1 09:48:52 2012
@@ -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;
+ }
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org