summaryrefslogtreecommitdiff
path: root/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin
diff options
context:
space:
mode:
Diffstat (limited to 'java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin')
-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.java41
-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
18 files changed, 1081 insertions, 928 deletions
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-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagementFactory.java b/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagementFactory.java
new file mode 100644
index 0000000000..ccf5373234
--- /dev/null
+++ b/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagementFactory.java
@@ -0,0 +1,41 @@
+/*
+ * 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.util.Map;
+import java.util.UUID;
+
+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
+ public Plugin createInstance(UUID id, Map<String, Object> attributes, Broker broker)
+ {
+ 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;
+ }
+ });
+ }
+
+}