diff options
Diffstat (limited to 'qpid/java/management/common/src/main/java/org/apache')
22 files changed, 2821 insertions, 0 deletions
diff --git a/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/JMXConnnectionFactory.java b/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/JMXConnnectionFactory.java new file mode 100644 index 0000000000..40202c2679 --- /dev/null +++ b/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/JMXConnnectionFactory.java @@ -0,0 +1,290 @@ +/* + * + * 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.management.common; + +import java.io.IOException; +import java.security.Security; +import java.util.HashMap; +import java.util.Map; + +import javax.management.remote.JMXConnector; +import javax.management.remote.JMXConnectorFactory; +import javax.management.remote.JMXServiceURL; +import javax.net.ssl.SSLException; +import javax.security.auth.callback.CallbackHandler; +import javax.security.sasl.SaslClientFactory; + +import org.apache.qpid.management.common.sasl.CRAMMD5HashedSaslClientFactory; +import org.apache.qpid.management.common.sasl.Constants; +import org.apache.qpid.management.common.sasl.JCAProvider; +import org.apache.qpid.management.common.sasl.SaslProvider; +import org.apache.qpid.management.common.sasl.UserPasswordCallbackHandler; +import org.apache.qpid.management.common.sasl.UsernameHashedPasswordCallbackHandler; + +public class JMXConnnectionFactory { + + private static final String NON_JRMP_SERVER = "non-JRMP server at remote endpoint"; + private static final String SERVER_SUPPORTED_PROFILES = "The server supported profiles"; + private static final String CLIENT_REQUIRED_PROFILES = "do not match the client required profiles"; + + public static JMXConnector getJMXConnection(long timeout, String host, int port, String username, String password) + throws SSLException, IOException, Exception + { + //auto-negotiate an RMI or JMXMP (SASL/CRAM-MD5 or SASL/PLAIN) JMX connection to broker + try + { + return createJMXconnector("RMI", timeout, host, port, username, password); + } + catch (IOException rmiIOE) + { + // check if the ioe was raised because we tried connecting to a non RMI-JRMP based JMX server + boolean jrmpServer = !rmiIOE.getMessage().contains(NON_JRMP_SERVER); + + if (jrmpServer) + { + //it was an RMI-JRMP based JMX server, so something else went wrong. Check for SSL issues. + Throwable rmiIOECause = rmiIOE.getCause(); + boolean isSSLException = false; + if (rmiIOECause != null) + { + isSSLException = rmiIOECause instanceof SSLException; + } + + //if it was an SSLException based cause, throw it + if (isSSLException) + { + throw (SSLException) rmiIOECause; + } + else + { + //can't determine cause, throw new IOE citing the original as cause + IOException nioe = new IOException(); + nioe.initCause(rmiIOE); + throw nioe; + } + } + else + { + try + { + //It wasnt an RMI ConnectorServer at the broker end. Try to establish a JMXMP SASL/CRAM-MD5 connection instead. + return createJMXconnector("JMXMP_CRAM-MD5", timeout, host, port, username, password); + } + catch (IOException cramIOE) + { + // check if the IOE was raised because we tried connecting to a SASL/PLAIN server using SASL/CRAM-MD5 + boolean plainProfileServer = cramIOE.getMessage().contains(SERVER_SUPPORTED_PROFILES + + " [" + Constants.SASL_PLAIN + "] " + CLIENT_REQUIRED_PROFILES + " [" + Constants.SASL_CRAMMD5 + "]"); + + if (!plainProfileServer) + { + IOException nioe = new IOException(); + nioe.initCause(cramIOE); + throw nioe; + } + else + { + try + { + // Try to establish a JMXMP SASL/PLAIN connection instead. + return createJMXconnector("JMXMP_PLAIN", timeout, host, port, username, password); + } + catch (IOException plainIOE) + { + /* Out of options now. Check that the IOE was raised because we tried connecting to a server + * which didnt support SASL/PLAIN. If so, signal an unknown profile type. If not, raise the exception. */ + boolean unknownProfile = plainIOE.getMessage().contains(CLIENT_REQUIRED_PROFILES + " [" + Constants.SASL_PLAIN + "]"); + + if (unknownProfile) + { + throw new Exception("Unknown JMXMP authentication mechanism, unable to connect."); + } + else + { + IOException nioe = new IOException(); + nioe.initCause(plainIOE); + throw nioe; + } + } + } + } + } + } + } + + private static JMXConnector createJMXconnector(String connectionType, long timeout, String host, int port, + String userName, String password) throws IOException, Exception + { + Map<String, Object> env = new HashMap<String, Object>(); + JMXServiceURL jmxUrl = null; + + if (connectionType.equalsIgnoreCase("RMI")) + { + jmxUrl = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://" + host + ":" + port + "/jmxrmi"); + + //Add user credential's to environment map for RMIConnector startup. + //These will be used for authentication by the remote RMIConnectorServer if supported, or ignored otherwise. + env.put(JMXConnector.CREDENTIALS, new String[] {userName,password}); + } + else if (connectionType.contains("JMXMP")) + { + // Check that the JMXMPConnector is available to provide SASL support + final String jmxmpcClass = "javax.management.remote.jmxmp.JMXMPConnector"; + + try + { + Class.forName(jmxmpcClass); + } + catch (ClassNotFoundException cnfe) + { + throw new Exception("JMXMPConnector class not found, unable to connect to specified server.\n\n" + + "Please add the jmxremote_optional.jar to the jmxremote.sasl plugin folder, or the classpath."); + } + + jmxUrl = new JMXServiceURL("jmxmp", host, port); + env = new HashMap<String, Object>(); + + /* set the package in which to find the JMXMP ClientProvider.class file loaded by the + * jmxremote.sasl plugin (from the jmxremote_optional.jar) */ + env.put("jmx.remote.protocol.provider.pkgs", "com.sun.jmx.remote.protocol"); + + if (connectionType.equalsIgnoreCase("JMXMP_CRAM-MD5")) + { + Map<String, Class<? extends SaslClientFactory>> map = new HashMap<String, Class<? extends SaslClientFactory>>(); + map.put("CRAM-MD5-HASHED", CRAMMD5HashedSaslClientFactory.class); + Security.addProvider(new JCAProvider(map)); + + CallbackHandler handler = new UsernameHashedPasswordCallbackHandler( + userName, password); + env.put("jmx.remote.profiles", Constants.SASL_CRAMMD5); + env.put("jmx.remote.sasl.callback.handler", handler); + } + else if (connectionType.equalsIgnoreCase("JMXMP_PLAIN")) + { + Security.addProvider(new SaslProvider()); + CallbackHandler handler = new UserPasswordCallbackHandler(userName, password); + env.put("jmx.remote.profiles", Constants.SASL_PLAIN); + env.put("jmx.remote.sasl.callback.handler", handler); + } + else + { + throw new Exception("Unknown JMXMP authentication mechanism"); + } + } + else + { + throw new Exception("Unknown connection type"); + } + + ConnectWaiter connector = new ConnectWaiter(jmxUrl, env); + Thread connectorThread = new Thread(connector); + connectorThread.start(); + connectorThread.join(timeout); + + if(connector.getJmxc() == null) + { + if (connector.getConnectionException() != null) + { + throw connector.getConnectionException(); + } + else + { + throw new IOException("Timed out connecting to " + host + ":" + port); + } + } + + return connector.getJmxc(); + } + + private static class ConnectWaiter implements Runnable + { + private Exception _connectionException; + private JMXConnector _jmxc; + private JMXServiceURL _jmxUrl; + private Map<String, ?> _env; + private boolean _connectionRetrieved; + + public ConnectWaiter(JMXServiceURL url, Map<String, ?> env) + { + _jmxUrl = url; + _env = env; + } + + public void run() + { + try + { + synchronized (this) + { + if(_connectionRetrieved) + { + _jmxc = null; + _connectionRetrieved = false; + _connectionException = null; + } + } + + JMXConnector conn = JMXConnectorFactory.connect(_jmxUrl, _env); + + synchronized (this) + { + if(_connectionRetrieved) + { + //The app thread already timed out the attempt and retrieved the + //null connection, so just close this orphaned connection + try + { + conn.close(); + } + catch (IOException e) + { + //ignore + } + } + else + { + _jmxc = conn; + } + } + } + catch (Exception ex) + { + _connectionException = ex; + } + } + + public Exception getConnectionException() + { + return _connectionException; + } + + public JMXConnector getJmxc() + { + synchronized (this) + { + _connectionRetrieved = true; + + return _jmxc; + } + } + } +} diff --git a/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/mbeans/ConfigurationManagement.java b/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/mbeans/ConfigurationManagement.java new file mode 100644 index 0000000000..a21a6713cc --- /dev/null +++ b/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/mbeans/ConfigurationManagement.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.management.common.mbeans; + +import javax.management.MBeanOperationInfo; + +import org.apache.qpid.management.common.mbeans.annotations.MBeanOperation; + +public interface ConfigurationManagement +{ + + String TYPE = "ConfigurationManagement"; + + /** + * Reload the + * @throws ConfigurationException + */ + @MBeanOperation(name="reloadSecurityConfiguration", + description = "Force a reload of the security configuration sections", + impact = MBeanOperationInfo.ACTION) + void reloadSecurityConfiguration() throws Exception; + +} diff --git a/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/mbeans/LoggingManagement.java b/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/mbeans/LoggingManagement.java new file mode 100644 index 0000000000..6d15869f0c --- /dev/null +++ b/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/mbeans/LoggingManagement.java @@ -0,0 +1,164 @@ +/* + * 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.management.common.mbeans; + +import java.io.IOException; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import org.apache.qpid.management.common.mbeans.annotations.MBeanAttribute; +import org.apache.qpid.management.common.mbeans.annotations.MBeanOperation; +import org.apache.qpid.management.common.mbeans.annotations.MBeanOperationParameter; + +import javax.management.MBeanOperationInfo; +import javax.management.openmbean.TabularData; + +/** + * Interface for the LoggingManagement MBean + * @since Qpid JMX API 1.2 + */ +public interface LoggingManagement +{ + String TYPE = "LoggingManagement"; + + //TabularType and contained CompositeType key/description information + //For compatibility reasons, DONT MODIFY the existing key values if expanding the set. + String LOGGER_NAME = "LoggerName"; + String LOGGER_LEVEL = "Level"; + List<String> COMPOSITE_ITEM_NAMES = Collections.unmodifiableList(Arrays.asList(LOGGER_NAME, LOGGER_LEVEL)); + List<String> COMPOSITE_ITEM_DESCRIPTIONS = Collections.unmodifiableList(Arrays.asList("Name of the logger", "Level of the logger")); + List<String> TABULAR_UNIQUE_INDEX = Collections.unmodifiableList(Arrays.asList(LOGGER_NAME)); + + /** + * Attribute to represent the log4j xml configuration file's LogWatch interval. + * @return The logwatch interval in seconds. + * @since Qpid JMX API 1.2 + */ + @MBeanAttribute(name="Log4jLogWatchInterval", + description = "The log4j xml configuration file LogWatch interval (in seconds). 0 indicates not being checked.") + Integer getLog4jLogWatchInterval(); + + /** + * Attribute to represent the available log4j logger output levels. + * @return The logging level names. + * @since Qpid JMX API 1.2 + */ + @MBeanAttribute(name="AvailableLoggerLevels", description = "The values to which log output level can be set.") + String[] getAvailableLoggerLevels(); + + + //****** log4j runtime operations ****** // + + /** + * Sets the level of an active Log4J logger + * @param logger The name of the logger + * @param level The level to set the logger to + * @return True if successful, false if unsuccessful (eg if an invalid level is specified) + * @since Qpid JMX API 1.2 + */ + @MBeanOperation(name = "setRuntimeLoggerLevel", description = "Set the runtime logging level for an active log4j logger.", + impact = MBeanOperationInfo.ACTION) + boolean setRuntimeLoggerLevel(@MBeanOperationParameter(name = "logger", description = "Logger name")String logger, + @MBeanOperationParameter(name = "level", description = "Logger level")String level); + + /** + * Retrieves a TabularData set of the active log4j loggers and their levels + * @return TabularData set of CompositeData rows with logger name and level, or null if there is a problem with the TabularData type + * @since Qpid JMX API 1.2 + */ + @MBeanOperation(name = "viewEffectiveRuntimeLoggerLevels", description = "View the effective runtime logging level " + + "for active log4j logger's.", impact = MBeanOperationInfo.INFO) + TabularData viewEffectiveRuntimeLoggerLevels(); + + /** + * Sets the level of the active Log4J RootLogger + * @param level The level to set the RootLogger to + * @return True if successful, false if unsuccessful (eg if an invalid level is specified) + * @since Qpid JMX API 1.2 + */ + @MBeanOperation(name = "setRuntimeRootLoggerLevel", description = "Set the runtime logging level for the active log4j Root Logger.", + impact = MBeanOperationInfo.ACTION) + boolean setRuntimeRootLoggerLevel(@MBeanOperationParameter(name = "level", description = "Logger level")String level); + + /** + * Attribute to represent the level of the active Log4J RootLogger + * @return The level of the RootLogger. + * @since Qpid JMX API 1.2 + */ + @MBeanAttribute(name = "getRuntimeRootLoggerLevel", description = "Get the runtime logging level for the active log4j Root Logger.") + String getRuntimeRootLoggerLevel(); + + + //****** log4j XML configuration file operations ****** // + + /** + * Reloads the log4j configuration file, applying any changes made. + * + * @throws IOException + * @since Qpid JMX API 1.4 + */ + @MBeanOperation(name = "reloadConfigFile", description = "Reload the log4j xml configuration file", impact = MBeanOperationInfo.ACTION) + void reloadConfigFile() throws IOException; + + /** + * Updates the level of an existing Log4J logger within the xml configuration file + * @param logger The name of the logger + * @param level The level to set the logger to + * @return True if successful, false if unsuccessful (eg if an invalid logger or level is specified) + * @throws IOException if there is an error parsing the configuration file. + * @since Qpid JMX API 1.2 + */ + @MBeanOperation(name = "setConfigFileLoggerLevel", description = "Set the logging level for an existing logger " + + "in the log4j xml configuration file", impact = MBeanOperationInfo.ACTION) + boolean setConfigFileLoggerLevel(@MBeanOperationParameter(name = "logger", description = "logger name")String logger, + @MBeanOperationParameter(name = "level", description = "Logger level")String level) throws IOException; + + /** + * Retrieves a TabularData set of the existing Log4J loggers within the xml configuration file + * @return TabularData set of CompositeData rows with logger name and level, or null if there is a problem with the TabularData type + * @throws IOException if there is an error parsing the configuration file. + * @since Qpid JMX API 1.2 + */ + @MBeanOperation(name = "viewConfigFileLoggerLevels", description = "Get the logging level defined for the logger's " + + "in the log4j xml configuration file.", impact = MBeanOperationInfo.INFO) + TabularData viewConfigFileLoggerLevels() throws IOException; + + /** + * Updates the level of the Log4J RootLogger within the xml configuration file if it is present + * @param level The level to set the logger to + * @return True if successful, false if not (eg an invalid level is specified, or root logger level isnt already defined) + * @throws IOException if there is an error parsing the configuration file. + * @since Qpid JMX API 1.2 + */ + @MBeanOperation(name = "setConfigFileRootLoggerLevel", description = "Set the logging level for the Root Logger " + + "in the log4j xml configuration file.", impact = MBeanOperationInfo.ACTION) + boolean setConfigFileRootLoggerLevel(@MBeanOperationParameter(name = "level", description = "Logger level")String level) throws IOException; + + /** + * Attribute to represent the level of the Log4J RootLogger within the xml configuration file + * @return The level of the RootLogger, or null if it is not present + * @since Qpid JMX API 1.2 + */ + @MBeanAttribute(name = "getConfigFileRootLoggerLevel", description = "Get the logging level for the Root Logger " + + "in the log4j xml configuration file.") + String getConfigFileRootLoggerLevel() throws IOException; +} diff --git a/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/mbeans/ManagedBroker.java b/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/mbeans/ManagedBroker.java new file mode 100644 index 0000000000..b5c80a4fed --- /dev/null +++ b/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/mbeans/ManagedBroker.java @@ -0,0 +1,248 @@ +/* + * + * 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.management.common.mbeans; + +import java.io.IOException; +import java.util.List; + +import javax.management.JMException; +import javax.management.MBeanException; +import javax.management.MBeanOperationInfo; + +import org.apache.qpid.management.common.mbeans.annotations.MBeanAttribute; +import org.apache.qpid.management.common.mbeans.annotations.MBeanOperation; +import org.apache.qpid.management.common.mbeans.annotations.MBeanOperationParameter; + +/** + * The ManagedBroker is the management interface to expose management + * features of the Broker. + * + * @version Qpid JMX API 2.2 + * @since Qpid JMX API 1.3 + */ +public interface ManagedBroker +{ + static final String TYPE = "VirtualHostManager"; + + /** + * Returns an array of the exchange types available for creation. + * @since Qpid JMX API 1.3 + * @throws IOException + */ + @MBeanAttribute(name="ExchangeTypes", description = "The types of Exchange available for creation.") + String[] getExchangeTypes() throws IOException; + + /** + * Returns a list containing the names of the attributes available for the Queue mbeans. + * @since Qpid JMX API 1.3 + * @throws IOException + */ + @MBeanOperation(name = "retrieveQueueAttributeNames", description = "Retrieve the attribute names for queues in this virtualhost", + impact = MBeanOperationInfo.INFO) + List<String> retrieveQueueAttributeNames() throws IOException; + + /** + * Returns a List of Object Lists containing the requested attribute values (in the same sequence requested) for each queue in the virtualhost. + * If a particular attribute cant be found or raises an mbean/reflection exception whilst being gathered its value is substituted with the String "-". + * @since Qpid JMX API 1.3 + * @throws IOException + */ + @MBeanOperation(name = "retrieveQueueAttributeValues", description = "Retrieve the indicated attributes for queues in this virtualhost", + impact = MBeanOperationInfo.INFO) + List<List<Object>> retrieveQueueAttributeValues(@MBeanOperationParameter(name="attributes", description="Attributes to retrieve") String[] attributes) throws IOException; + + /** + * Creates a new Exchange. + * + * @param name + * @param type + * @param durable + * @throws IOException + * @throws JMException + * @throws MBeanException + */ + @MBeanOperation(name="createNewExchange", description="Creates a new Exchange", impact= MBeanOperationInfo.ACTION) + void createNewExchange(@MBeanOperationParameter(name="name", description="Name of the new exchange")String name, + @MBeanOperationParameter(name="ExchangeType", description="Type of the exchange")String type, + @MBeanOperationParameter(name="durable", description="true if the Exchang should be durable")boolean durable) + throws IOException, JMException, MBeanException; + + /** + * unregisters all the channels, queuebindings etc and unregisters + * this exchange from managed objects. + * + * @param exchange + * @throws IOException + * @throws JMException + * @throws MBeanException + */ + @MBeanOperation(name="unregisterExchange", + description="Unregisters all the related channels and queuebindings of this exchange", + impact= MBeanOperationInfo.ACTION) + void unregisterExchange(@MBeanOperationParameter(name= ManagedExchange.TYPE, description="Exchange Name")String exchange) + throws IOException, JMException, MBeanException; + + /** + * Create a new Queue on the Broker server. + * + * @param queueName + * @param durable + * @param owner + * @throws IOException + * @throws JMException + * @throws MBeanException + */ + @MBeanOperation(name="createNewQueue", description="Create a new Queue on the Broker server", impact= MBeanOperationInfo.ACTION) + void createNewQueue(@MBeanOperationParameter(name="queue name", description="Name of the new queue")String queueName, + @MBeanOperationParameter(name="owner", description="Owner name")String owner, + @MBeanOperationParameter(name="durable", description="true if the queue should be durable")boolean durable) + throws IOException, JMException, MBeanException; + + /** + * Unregisters the Queue bindings, removes the subscriptions and unregisters + * from the managed objects. + * + * @param queueName + * @throws IOException + * @throws JMException + * @throws MBeanException + */ + @MBeanOperation(name="deleteQueue", + description="Unregisters the Queue bindings, removes the subscriptions and deletes the queue", + impact= MBeanOperationInfo.ACTION) + void deleteQueue(@MBeanOperationParameter(name= ManagedQueue.TYPE, description="Queue Name")String queueName) + throws IOException, JMException, MBeanException; + + /** + * Resets all message and data statistics for the virtual host. + * + * @since Qpid JMX API 2.2 + */ + @MBeanOperation(name="resetStatistics", + description="Resets all message and data statistics for the virtual host", + impact= MBeanOperationInfo.ACTION) + void resetStatistics() throws Exception; + + /** + * Peak rate of messages delivered per second for the virtual host. + * + * @since Qpid JMX API 2.2 + */ + @MBeanAttribute(name="PeakMessageDeliveryRate", description=TYPE + " Peak Message Delivery Rate") + double getPeakMessageDeliveryRate(); + + /** + * Peak rate of bytes delivered per second for the virtual host. + * + * @since Qpid JMX API 2.2 + */ + @MBeanAttribute(name="PeakDataDeliveryRate", description=TYPE + " Peak Data Delivery Rate") + double getPeakDataDeliveryRate(); + + /** + * Rate of messages delivered per second for the virtual host. + * + * @since Qpid JMX API 2.2 + */ + @MBeanAttribute(name="MessageDeliveryRate", description=TYPE + " Message Delivery Rate") + double getMessageDeliveryRate(); + + /** + * Rate of bytes delivered per second for the virtual host. + * + * @since Qpid JMX API 2.2 + */ + @MBeanAttribute(name="DataDeliveryRate", description=TYPE + " Data Delivery Rate") + double getDataDeliveryRate(); + + /** + * Total count of messages delivered for the virtual host. + * + * @since Qpid JMX API 2.2 + */ + @MBeanAttribute(name="TotalMessagesDelivered", description=TYPE + " Total Messages Delivered") + long getTotalMessagesDelivered(); + + /** + * Total count of bytes for the virtual host. + * + * @since Qpid JMX API 2.2 + */ + @MBeanAttribute(name="TotalDataDelivered", description=TYPE + " Total Data Delivered") + long getTotalDataDelivered(); + + /** + * Peak rate of messages received per second for the virtual host. + * + * @since Qpid JMX API 2.2 + */ + @MBeanAttribute(name="PeakMessageReceiptRate", description=TYPE + " Peak Message Receipt Rate") + double getPeakMessageReceiptRate(); + + /** + * Peak rate of bytes received per second for the virtual host. + * + * @since Qpid JMX API 2.2 + */ + @MBeanAttribute(name="PeakDataReceiptRate", description=TYPE + " Peak Data Receipt Rate") + double getPeakDataReceiptRate(); + + /** + * Rate of messages received per second for the virtual host. + * + * @since Qpid JMX API 2.2 + */ + @MBeanAttribute(name="MessageReceiptRate", description=TYPE + " Message Receipt Rate") + double getMessageReceiptRate(); + + /** + * Rate of bytes received per second for the virtual host. + * + * @since Qpid JMX API 2.2 + */ + @MBeanAttribute(name="DataReceiptRate", description=TYPE + " Data Receipt Rate") + double getDataReceiptRate(); + + /** + * Total count of messages received for the virtual host. + * + * @since Qpid JMX API 2.2 + */ + @MBeanAttribute(name="TotalMessagesReceived", description=TYPE + " Total Messages Received") + long getTotalMessagesReceived(); + + /** + * Total count of bytes received for the virtual host. + * + * @since Qpid JMX API 2.2 + */ + @MBeanAttribute(name="TotalDataReceived", description=TYPE + " Total Data Received") + long getTotalDataReceived(); + + /** + * Is statistics collection enabled for this connection. + * + * @since Qpid JMX API 2.2 + */ + @MBeanAttribute(name="StatisticsEnabled", description=TYPE + " Statistics Enabled") + boolean isStatisticsEnabled(); +} diff --git a/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/mbeans/ManagedConnection.java b/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/mbeans/ManagedConnection.java new file mode 100644 index 0000000000..d16db65d5d --- /dev/null +++ b/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/mbeans/ManagedConnection.java @@ -0,0 +1,271 @@ +/* + * + * 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.management.common.mbeans; + +import java.io.IOException; +import java.util.Arrays; +import java.util.Collections; +import java.util.Date; +import java.util.List; + +import javax.management.JMException; +import javax.management.MBeanOperationInfo; +import javax.management.openmbean.TabularData; + +import org.apache.qpid.management.common.mbeans.annotations.MBeanAttribute; +import org.apache.qpid.management.common.mbeans.annotations.MBeanOperation; +import org.apache.qpid.management.common.mbeans.annotations.MBeanOperationParameter; + +/** + * The management interface exposed to allow management of Connections. + * + * @version Qpid JMX API 2.2 + * @since Qpid JMX API 1.3 + */ +public interface ManagedConnection +{ + static final String TYPE = "Connection"; + + //TabularType and contained CompositeType key/description information + //For compatibility reasons, DONT MODIFY the existing key values if expanding the set. + //"Flow Blocked" added in Qpid JMX API 1.5 + String CHAN_ID = "Channel Id"; + String TRANSACTIONAL = "Transactional"; + String DEFAULT_QUEUE = "Default Queue"; + String UNACKED_COUNT = "Unacknowledged Message Count"; + String FLOW_BLOCKED = "Flow Blocked"; + List<String> COMPOSITE_ITEM_NAMES_DESC = Collections.unmodifiableList(Arrays.asList(CHAN_ID, TRANSACTIONAL, DEFAULT_QUEUE, UNACKED_COUNT, FLOW_BLOCKED)); + List<String> TABULAR_UNIQUE_INDEX = Collections.unmodifiableList(Arrays.asList(CHAN_ID)); + + @MBeanAttribute(name = "ClientId", description = "Client Id") + String getClientId(); + + @MBeanAttribute(name = "AuthorizedId", description = "User Name") + String getAuthorizedId(); + + @MBeanAttribute(name = "Version", description = "Client Version") + String getVersion(); + + /** + * Tells the remote address of this connection. + * @return remote address + */ + @MBeanAttribute(name="RemoteAddress", description=TYPE + " Address") + String getRemoteAddress(); + + /** + * Tells the last time, the IO operation was done. + * @return last IO time. + */ + @MBeanAttribute(name="LastIOTime", description="The last time, the IO operation was done") + Date getLastIoTime(); + + /** + * Tells the total number of bytes written till now. + * @return number of bytes written. + * + @MBeanAttribute(name="WrittenBytes", description="The total number of bytes written till now") + Long getWrittenBytes(); + */ + /** + * Tells the total number of bytes read till now. + * @return number of bytes read. + * + @MBeanAttribute(name="ReadBytes", description="The total number of bytes read till now") + Long getReadBytes(); + */ + + /** + * Threshold high value for no of channels. This is useful in setting notifications or + * taking required action is there are more channels being created. + * @return threshold limit for no of channels + */ + Long getMaximumNumberOfChannels(); + + /** + * Sets the threshold high value for number of channels for a connection + * @param value + */ + @MBeanAttribute(name="MaximumNumberOfChannels", description="The threshold high value for number of channels for this connection") + void setMaximumNumberOfChannels(Long value); + + //********** Operations *****************// + + /** + * channel details of all the channels opened for this connection. + * @return general channel details + * @throws IOException + * @throws JMException + */ + @MBeanOperation(name="channels", description="Channel details for this connection") + TabularData channels() throws IOException, JMException; + + /** + * Commits the transactions if the channel is transactional. + * @param channelId + * @throws JMException + */ + @MBeanOperation(name="commitTransaction", + description="Commits the transactions for given channel Id, if the channel is transactional", + impact= MBeanOperationInfo.ACTION) + void commitTransactions(@MBeanOperationParameter(name="channel Id", description="channel Id")int channelId) throws JMException; + + /** + * Rollsback the transactions if the channel is transactional. + * @param channelId + * @throws JMException + */ + @MBeanOperation(name="rollbackTransactions", + description="Rollsback the transactions for given channel Id, if the channel is transactional", + impact= MBeanOperationInfo.ACTION) + void rollbackTransactions(@MBeanOperationParameter(name="channel Id", description="channel Id")int channelId) throws JMException; + + /** + * Closes all the related channels and unregisters this connection from managed objects. + */ + @MBeanOperation(name="closeConnection", + description="Closes this connection and all related channels", + impact= MBeanOperationInfo.ACTION) + void closeConnection() throws Exception; + + /** + * Resets message and data statistics for this connection. + * + * @since Qpid JMX API 2.2 + */ + @MBeanOperation(name="resetStatistics", + description="Resets message and data statistics for this connection", + impact= MBeanOperationInfo.ACTION) + void resetStatistics() throws Exception; + + /** + * Peak rate of messages delivered per second for the virtual host. + * + * @since Qpid JMX API 2.2 + */ + @MBeanAttribute(name="PeakMessageDeliveryRate", description=TYPE + " Peak Message Delivery Rate") + double getPeakMessageDeliveryRate(); + + /** + * Peak rate of bytes delivered per second for the virtual host. + * + * @since Qpid JMX API 2.2 + */ + @MBeanAttribute(name="PeakDataDeliveryRate", description=TYPE + " Peak Data Delivery Rate") + double getPeakDataDeliveryRate(); + + /** + * Rate of messages delivered per second for the virtual host. + * + * @since Qpid JMX API 2.2 + */ + @MBeanAttribute(name="MessageDeliveryRate", description=TYPE + " Message Delivery Rate") + double getMessageDeliveryRate(); + + /** + * Rate of bytes delivered per second for the virtual host. + * + * @since Qpid JMX API 2.2 + */ + @MBeanAttribute(name="DataDeliveryRate", description=TYPE + " Data Delivery Rate") + double getDataDeliveryRate(); + + /** + * Total count of messages delivered for the virtual host. + * + * @since Qpid JMX API 2.2 + */ + @MBeanAttribute(name="TotalMessagesDelivered", description=TYPE + " Total Messages Delivered") + long getTotalMessagesDelivered(); + + /** + * Total count of bytes for the virtual host. + * + * @since Qpid JMX API 2.2 + */ + @MBeanAttribute(name="TotalDataDelivered", description=TYPE + " Total Data Delivered") + long getTotalDataDelivered(); + + /** + * Peak rate of messages received per second for this connection. + * + * @since Qpid JMX API 2.2 + */ + @MBeanAttribute(name="PeakMessageReceiptRate", description=TYPE + " Peak Message Receipt Rate") + double getPeakMessageReceiptRate(); + + /** + * Peak rate of bytes received per second for this connection. + * + * @since Qpid JMX API 2.2 + */ + @MBeanAttribute(name="PeakDataReceiptRate", description=TYPE + " Peak Data Receipt Rate") + double getPeakDataReceiptRate(); + + /** + * Rate of messages received per second for this connection. + * + * @since Qpid JMX API 2.2 + */ + @MBeanAttribute(name="MessageReceiptRate", description=TYPE + " Message Receipt Rate") + double getMessageReceiptRate(); + + /** + * Rate of bytes received per second for this connection. + * + * @since Qpid JMX API 2.2 + */ + @MBeanAttribute(name="DataReceiptRate", description=TYPE + " Data Receipt Rate") + double getDataReceiptRate(); + + /** + * Total count of messages received for this connection. + * + * @since Qpid JMX API 2.2 + */ + @MBeanAttribute(name="TotalMessagesReceived", description=TYPE + " Total Messages Received") + long getTotalMessagesReceived(); + + /** + * Total count of bytes received for this connection. + * + * @since Qpid JMX API 2.2 + */ + @MBeanAttribute(name="TotalDataReceived", description=TYPE + " Total Data Received") + long getTotalDataReceived(); + + /** + * Is statistics collection enabled for this connection. + * + * @since Qpid JMX API 2.2 + */ + @MBeanAttribute(name="StatisticsEnabled", description=TYPE + " Statistics Enabled") + boolean isStatisticsEnabled(); + + /** + * Sets statistics collection enabled/disabled for this connection. + * + * @param enabled + * @since Qpid JMX API 2.2 + */ + void setStatisticsEnabled(boolean enabled); +} diff --git a/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/mbeans/ManagedExchange.java b/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/mbeans/ManagedExchange.java new file mode 100644 index 0000000000..78a1eb964f --- /dev/null +++ b/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/mbeans/ManagedExchange.java @@ -0,0 +1,133 @@ +/* + * + * 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.management.common.mbeans; + +import java.io.IOException; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import javax.management.JMException; +import javax.management.MBeanOperationInfo; +import javax.management.openmbean.TabularData; + +import org.apache.qpid.management.common.mbeans.annotations.MBeanAttribute; +import org.apache.qpid.management.common.mbeans.annotations.MBeanOperation; +import org.apache.qpid.management.common.mbeans.annotations.MBeanOperationParameter; + +/** + * The management interface exposed to allow management of an Exchange. + * + * @version 1.8 + */ +public interface ManagedExchange +{ + static final String TYPE = "Exchange"; + + //TabularType and contained CompositeType key/description info for DIRECT/TOPIC/FANOUT exchanges. + //For compatibility reasons, DONT MODIFY the existing key values if expanding the set. + String BINDING_KEY = "Binding Key"; + String QUEUE_NAMES = "Queue Names"; + + List<String> COMPOSITE_ITEM_NAMES = Collections.unmodifiableList(Arrays.asList(BINDING_KEY, QUEUE_NAMES)); + List<String> COMPOSITE_ITEM_DESCRIPTIONS = Collections.unmodifiableList(Arrays.asList(BINDING_KEY, QUEUE_NAMES)); + List<String> TABULAR_UNIQUE_INDEX = Collections.unmodifiableList(Arrays.asList(BINDING_KEY)); + + //TabularType and contained CompositeType key/description info for HEADERS exchange only. + //For compatibility reasons, DONT MODIFY the existing key values if expanding the set. + String HDR_BINDING_NUMBER = "Binding No"; + String HDR_QUEUE_NAME = "Queue Name"; + String HDR_QUEUE_BINDINGS = "Queue Bindings"; + + List<String> HEADERS_COMPOSITE_ITEM_NAMES = Collections.unmodifiableList(Arrays.asList(HDR_BINDING_NUMBER, HDR_QUEUE_NAME, HDR_QUEUE_BINDINGS)); + List<String> HEADERS_COMPOSITE_ITEM_DESC = Collections.unmodifiableList(Arrays.asList(HDR_BINDING_NUMBER, HDR_QUEUE_NAME, HDR_QUEUE_BINDINGS)); + List<String> HEADERS_TABULAR_UNIQUE_INDEX = Collections.unmodifiableList(Arrays.asList(HDR_BINDING_NUMBER)); + + /** + * Returns the name of the managed exchange. + * @return the name of the exchange. + * @throws IOException + */ + @MBeanAttribute(name="Name", description=TYPE + " Name") + String getName() throws IOException; + + @MBeanAttribute(name="ExchangeType", description="Exchange Type") + String getExchangeType() throws IOException; + + @MBeanAttribute(name="TicketNo", description="Exchange Ticket No") + Integer getTicketNo() throws IOException; + + /** + * Tells if the exchange is durable or not. + * @return true if the exchange is durable. + * @throws IOException + */ + @MBeanAttribute(name="Durable", description="true if Exchange is durable") + boolean isDurable() throws IOException; + + /** + * Tells if the exchange is set for autodelete or not. + * @return true if the exchange is set as autodelete. + * @throws IOException + */ + @MBeanAttribute(name="AutoDelete", description="true if Exchange is AutoDelete") + boolean isAutoDelete() throws IOException; + + // Operations + + /** + * Returns all the bindings this exchange has with the queues. + * @return the bindings with the exchange. + * @throws IOException + * @throws JMException + */ + @MBeanOperation(name="bindings", description="view the queue bindings for this exchange") + TabularData bindings() throws IOException, JMException; + + /** + * Creates new binding with the given queue and binding. + * @param queueName + * @param binding + * @throws JMException + */ + @MBeanOperation(name="createNewBinding", + description="create a new binding with this exchange", + impact= MBeanOperationInfo.ACTION) + void createNewBinding(@MBeanOperationParameter(name= ManagedQueue.TYPE, description="Queue name") String queueName, + @MBeanOperationParameter(name="Binding", description="New binding")String binding) + throws JMException; + + /** + * Removes an exchange binding from a queue. + * + * @param exchangeName the Exchange name + * @param routingKey the routing key + * @throws IOException + * @throws JMException + * @since Qpid JMX API 1.8 + */ + @MBeanOperation(name="removeBinding", + description="Removes an exchange binding from the Queue", + impact= MBeanOperationInfo.ACTION) + void removeBinding(@MBeanOperationParameter(name= ManagedQueue.TYPE, description="Queue name") String queueName, + @MBeanOperationParameter(name="Binding", description="Binding key")String binding) + throws IOException, JMException; +} diff --git a/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/mbeans/ManagedQueue.java b/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/mbeans/ManagedQueue.java new file mode 100644 index 0000000000..be31d8ef88 --- /dev/null +++ b/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/mbeans/ManagedQueue.java @@ -0,0 +1,438 @@ +/* + * + * 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.management.common.mbeans; + +import java.io.IOException; +import java.util.*; + +import javax.management.JMException; +import javax.management.MBeanOperationInfo; +import javax.management.openmbean.CompositeData; +import javax.management.openmbean.TabularData; + +import org.apache.qpid.management.common.mbeans.annotations.MBeanAttribute; +import org.apache.qpid.management.common.mbeans.annotations.MBeanOperation; +import org.apache.qpid.management.common.mbeans.annotations.MBeanOperationParameter; + +/** + * The management interface exposed to allow management of a queue. + * @author Robert J. Greig + * @author Bhupendra Bhardwaj + * @version 0.1 + */ +public interface ManagedQueue +{ + static final String TYPE = "Queue"; + + //TabularType and contained CompositeType key/description information for message list + //For compatibility reasons, DONT MODIFY the existing key values if expanding the set. + //"Queue Position" added in Qpid JMX API 1.3 + String MSG_AMQ_ID = "AMQ MessageId"; + String MSG_HEADER = "Header"; + String MSG_SIZE = "Size(bytes)"; + String MSG_REDELIVERED = "Redelivered"; + String MSG_QUEUE_POS = "Queue Position"; + List<String> VIEW_MSGS_COMPOSITE_ITEM_NAMES_DESC = Collections.unmodifiableList(Arrays.asList(MSG_AMQ_ID, MSG_HEADER, MSG_SIZE, MSG_REDELIVERED, MSG_QUEUE_POS)); + List<String> VIEW_MSGS_TABULAR_UNIQUE_INDEX = Collections.unmodifiableList(Arrays.asList(MSG_QUEUE_POS)); + + //CompositeType key/description information for message content + //For compatibility reasons, DONT MODIFY the existing key values if expanding the set. + String MIME = "MimeType"; + String ENCODING = "Encoding"; + String CONTENT = "Content"; + List<String> VIEW_MSG_CONTENT_COMPOSITE_ITEM_NAMES_DESC = Collections.unmodifiableList(Arrays.asList(MSG_AMQ_ID, MIME, ENCODING, CONTENT)); + + //Individual attribute name constants + static final String ATTR_NAME = "Name"; + static final String ATTR_OWNER = "Owner"; + static final String ATTR_MAX_MSG_AGE = "MaximumMessageAge"; + static final String ATTR_MAX_MSG_COUNT = "MaximumMessageCount"; + static final String ATTR_MAX_QUEUE_DEPTH = "MaximumQueueDepth"; + static final String ATTR_MAX_MSG_SIZE = "MaximumMessageSize"; + static final String ATTR_DURABLE = "Durable"; + static final String ATTR_AUTODELETE = "AutoDelete"; + static final String ATTR_CONSUMER_COUNT = "ConsumerCount"; + static final String ATTR_ACTIVE_CONSUMER_COUNT = "ActiveConsumerCount"; + static final String ATTR_MSG_COUNT = "MessageCount"; + static final String ATTR_QUEUE_DEPTH = "QueueDepth"; + static final String ATTR_RCVD_MSG_COUNT = "ReceivedMessageCount"; + static final String ATTR_CAPACITY = "Capacity"; + static final String ATTR_FLOW_OVERFULL = "FlowOverfull"; + static final String ATTR_FLOW_RESUME_CAPACITY = "FlowResumeCapacity"; + static final String ATTR_EXCLUSIVE = "Exclusive"; + + //All attribute names constant + static final List<String> QUEUE_ATTRIBUTES + = Collections.unmodifiableList( + new ArrayList<String>( + new HashSet<String>( + Arrays.asList( + ATTR_NAME, + ATTR_OWNER, + ATTR_MAX_MSG_AGE, + ATTR_MAX_MSG_COUNT, + ATTR_MAX_QUEUE_DEPTH, + ATTR_MAX_MSG_SIZE, + ATTR_DURABLE, + ATTR_AUTODELETE, + ATTR_CONSUMER_COUNT, + ATTR_ACTIVE_CONSUMER_COUNT, + ATTR_MSG_COUNT, + ATTR_QUEUE_DEPTH, + ATTR_RCVD_MSG_COUNT, + ATTR_CAPACITY, + ATTR_FLOW_OVERFULL, + ATTR_FLOW_RESUME_CAPACITY, + ATTR_EXCLUSIVE)))); + + /** + * Returns the Name of the ManagedQueue. + * @return the name of the managedQueue. + * @throws IOException + */ + @MBeanAttribute(name="Name", description = TYPE + " Name") + String getName() throws IOException; + + /** + * Total number of messages on the queue, which are yet to be delivered to the consumer(s). + * @return number of undelivered message in the Queue. + * @throws IOException + */ + @MBeanAttribute(name="MessageCount", description = "Total number of undelivered messages on the queue") + Integer getMessageCount() throws IOException; + + /** + * Tells the total number of messages receieved by the queue since startup. + * @return total number of messages received. + * @throws IOException + */ + @MBeanAttribute(name="ReceivedMessageCount", description="The total number of messages receieved by the queue since startup") + Long getReceivedMessageCount() throws IOException; + + /** + * Size of messages in the queue + * + * Since Qpid JMX API 1.2 this operation returns in units of bytes. Prior to this, the result was in units of kilobytes. + * @return + * @throws IOException + */ + @MBeanAttribute(name="QueueDepth", description="The total size(Bytes) of messages in the queue") + Long getQueueDepth() throws IOException, JMException; + + /** + * Returns the total number of active subscribers to the queue. + * @return the number of active subscribers + * @throws IOException + */ + @MBeanAttribute(name="ActiveConsumerCount", description="The total number of active subscribers to the queue") + Integer getActiveConsumerCount() throws IOException; + + /** + * Returns the total number of subscribers to the queue. + * @return the number of subscribers. + * @throws IOException + */ + @MBeanAttribute(name="ConsumerCount", description="The total number of subscribers to the queue") + Integer getConsumerCount() throws IOException; + + /** + * Tells the Owner of the ManagedQueue. + * @return the owner's name. + * @throws IOException + */ + @MBeanAttribute(name="Owner", description = "Owner") + String getOwner() throws IOException; + + /** + * Tells whether this ManagedQueue is durable or not. + * @return true if this ManagedQueue is a durable queue. + * @throws IOException + */ + @MBeanAttribute(name="Durable", description = "true if the AMQQueue is durable") + boolean isDurable() throws IOException; + + /** + * Tells if the ManagedQueue is set to AutoDelete. + * @return true if the ManagedQueue is set to AutoDelete. + * @throws IOException + */ + @MBeanAttribute(name="AutoDelete", description = "true if the AMQQueue is AutoDelete") + boolean isAutoDelete() throws IOException; + + /** + * Returns the maximum age of a message (expiration time) in milliseconds + * @return the maximum age + * @throws IOException + */ + Long getMaximumMessageAge() throws IOException; + + /** + * Sets the maximum age of a message in milliseconds + * @param age maximum age of message. + * @throws IOException + */ + @MBeanAttribute(name="MaximumMessageAge", description="Threshold high value(milliseconds) for message age") + void setMaximumMessageAge(Long age) throws IOException; + + /** + * Returns the maximum size of a message (in Bytes) allowed to be accepted by the + * ManagedQueue. This is useful in setting notifications or taking + * appropriate action, if the size of the message received is more than + * the allowed size. + * @return the maximum size of a message allowed to be aceepted by the + * ManagedQueue. + * @throws IOException + */ + Long getMaximumMessageSize() throws IOException; + + /** + * Sets the maximum size of the message (in Bytes) that is allowed to be + * accepted by the Queue. + * @param size maximum size of message. + * @throws IOException + */ + @MBeanAttribute(name="MaximumMessageSize", description="Threshold high value(Bytes) for a message size") + void setMaximumMessageSize(Long size) throws IOException; + + /** + * Tells the maximum number of messages that can be stored in the queue. + * This is useful in setting the notifications or taking required + * action is the number of message increase this limit. + * @return maximum muber of message allowed to be stored in the queue. + * @throws IOException + */ + Long getMaximumMessageCount() throws IOException; + + /** + * Sets the maximum number of messages allowed to be stored in the queue. + * @param value the maximum number of messages allowed to be stored in the queue. + * @throws IOException + */ + @MBeanAttribute(name="MaximumMessageCount", description="Threshold high value for number of undelivered messages in the queue") + void setMaximumMessageCount(Long value) throws IOException; + + /** + * This is useful for setting notifications or taking required action if the size of messages + * stored in the queue increases over this limit. + * + * Since Qpid JMX API 1.2 this operation returns in units of bytes. Prior to this, the result was in units of kilobytes. + * @return threshold high value for Queue Depth + * @throws IOException + */ + Long getMaximumQueueDepth() throws IOException; + + /** + * Sets the maximum size of all the messages together, that can be stored + * in the queue. + * @param value + * @throws IOException + */ + @MBeanAttribute(name="MaximumQueueDepth", description="The threshold high value(Bytes) for Queue Depth") + void setMaximumQueueDepth(Long value) throws IOException; + + + /** + * Returns the current flow control Capacity of the queue in bytes. + * + * @since Qpid JMX API 1.6 + * @return Capacity at which flow control is enforced + * @throws IOException + */ + Long getCapacity() throws IOException; + + /** + * Sets the Capacity in bytes above which flow is blocked. + * + * @since Qpid JMX API 1.6 + * @param value the capacity in bytes + * @throws IOException + * @throws IllegalArgumentException If the given value is less than the queue FloeResumeCapacity + */ + @MBeanAttribute(name="Capacity", description="The flow control Capacity (Bytes) of the queue") + void setCapacity(Long value) throws IOException, IllegalArgumentException; + + /** + * Returns the current flow control FlowResumeCapacity of the queue in bytes. + * + * @since Qpid JMX API 1.6 + * @return Capacity below which flow resumes in bytes + * @throws IOException + */ + Long getFlowResumeCapacity() throws IOException; + + /** + * Sets the FlowResumeCapacity in bytes below which flow resumes. + * + * @since Qpid JMX API 1.6 + * @param value of the resume capacity in bytes + * @throws IOException + * @throws IllegalArgumentException If the given value exceeds the queue Capacity + */ + @MBeanAttribute(name="FlowResumeCapacity", description="The flow resume Capacity (Bytes) of the queue") + void setFlowResumeCapacity(Long value) throws IOException, IllegalArgumentException; + + /** + * Indicates whether the Queue is currently considered overfull by the FlowControl system + * + * @since Qpid JMX API 1.6 + * @throws IOException + */ + @MBeanAttribute(name="FlowOverfull", description="true if the queue is considered overfull by the Flow Control system") + boolean isFlowOverfull() throws IOException; + + /** + * Returns whether the queue is exclusive or not. + * + * @since Qpid JMX API 2.0 + * @return whether the queue is exclusive. + * @throws IOException + */ + boolean isExclusive() throws IOException; + + /** + * Sets whether the queue is exclusive or not. + * + * @since Qpid JMX API 2.0 + * @param exclusive the capacity in bytes + * @throws IOException + * @throws JMException + */ + @MBeanAttribute(name="Exclusive", description="Whether the queue is Exclusive or not") + void setExclusive(boolean exclusive) throws IOException, JMException; + + //********** Operations *****************// + + + /** + * Returns a subset of all the messages stored in the queue. The messages + * are returned based on the given index numbers. + * + * Deprecated as of Qpid JMX API 1.3 + * @param fromIndex + * @param toIndex + * @return + * @throws IOException + * @throws JMException + */ + @Deprecated + @MBeanOperation(name="viewMessages", + description="Message headers for messages in this queue within given index range. eg. from index 1 - 100") + TabularData viewMessages(@MBeanOperationParameter(name="from index", description="from index")int fromIndex, + @MBeanOperationParameter(name="to index", description="to index")int toIndex) + throws IOException, JMException; + + /** + * Returns a subset (up to 2^31 messages at a time) of all the messages stored on the queue. + * The messages are returned based on the given queue position range. + * @param startPosition + * @param endPosition + * @return + * @throws IOException + * @throws JMException + */ + @MBeanOperation(name="viewMessages", + description="Message headers for messages in this queue within given queue positions range. eg. from index 1 - 100") + TabularData viewMessages(@MBeanOperationParameter(name="start position", description="start position")long startPosition, + @MBeanOperationParameter(name="end position", description="end position")long endPosition) + throws IOException, JMException; + + /** + * Returns the content for the given AMQ Message ID. + * + * @throws IOException + * @throws JMException + */ + @MBeanOperation(name="viewMessageContent", description="The message content for given Message Id") + CompositeData viewMessageContent(@MBeanOperationParameter(name="Message Id", description="Message Id")long messageId) + throws IOException, JMException; + + /** + * Deletes the first message from top. + * + * Deprecated as of Qpid JMX API 1.3 + * @throws IOException + * @throws JMException + */ + @Deprecated + @MBeanOperation(name="deleteMessageFromTop", description="Deletes the first message from top", + impact= MBeanOperationInfo.ACTION) + void deleteMessageFromTop() throws IOException, JMException; + + /** + * Clears the queue by deleting all the messages from the queue that have not been acquired by consumers" + * + * Since Qpid JMX API 1.3 this returns the number of messages deleted. Prior to this, the return type was void. + * @return the number of messages deleted + * @throws IOException + * @throws JMException + */ + @MBeanOperation(name="clearQueue", + description="Clears the queue by deleting all the messages from the queue " + + "that have not been acquired by consumers", + impact= MBeanOperationInfo.ACTION) + Long clearQueue() throws IOException, JMException; + + /** + * Moves the messages in given range of message Ids to given Queue. QPID-170 + * @param fromMessageId first in the range of message ids + * @param toMessageId last in the range of message ids + * @param toQueue where the messages are to be moved + * @throws IOException + * @throws JMException + */ + @MBeanOperation(name="moveMessages", + description="You can move messages to another queue from this queue ", + impact= MBeanOperationInfo.ACTION) + void moveMessages(@MBeanOperationParameter(name="from MessageId", description="from MessageId")long fromMessageId, + @MBeanOperationParameter(name="to MessageId", description="to MessageId")long toMessageId, + @MBeanOperationParameter(name= ManagedQueue.TYPE, description="to Queue Name")String toQueue) + throws IOException, JMException; + + /** + * Deletes the messages in given range of AMQ message Ids in the given Queue. + * @param fromMessageId first in the range of message ids + * @param toMessageId last in the range of message ids + * @throws IOException + * @throws JMException + */ + @MBeanOperation(name="deleteMessages", + description="Delete a range of messages from a specified queue", + impact= MBeanOperationInfo.ACTION) + void deleteMessages(@MBeanOperationParameter(name="from MessageId", description="from MessageId")long fromMessageId, + @MBeanOperationParameter(name="to MessageId", description="to MessageId")long toMessageId) + throws IOException, JMException; + + /** + * Copies the messages in given range of AMQ message Ids to a given Queue. + * @param fromMessageId first in the range of message ids + * @param toMessageId last in the range of message ids + * @param toQueue where the messages are to be copied + * @throws IOException + * @throws JMException + */ + @MBeanOperation(name="copyMessages", + description="Copies a range of messages to a specified queue", + impact= MBeanOperationInfo.ACTION) + void copyMessages(@MBeanOperationParameter(name="from MessageId", description="from MessageId")long fromMessageId, + @MBeanOperationParameter(name="to MessageId", description="to MessageId")long toMessageId, + @MBeanOperationParameter(name= ManagedQueue.TYPE, description="to Queue Name")String toQueue) + throws IOException, JMException; +} diff --git a/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/mbeans/ServerInformation.java b/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/mbeans/ServerInformation.java new file mode 100644 index 0000000000..12ae69571e --- /dev/null +++ b/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/mbeans/ServerInformation.java @@ -0,0 +1,202 @@ +/* + * 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.management.common.mbeans; + +import java.io.IOException; + +import javax.management.MBeanOperationInfo; + +import org.apache.qpid.management.common.mbeans.annotations.MBeanAttribute; +import org.apache.qpid.management.common.mbeans.annotations.MBeanOperation; + +/** + * Interface for the ServerInformation MBean + * + * @version Qpid JMX API 2.3 + * @since Qpid JMX API 1.3 + */ +public interface ServerInformation +{ + String TYPE = "ServerInformation"; + + /* API version info for the brokers JMX management interface + * + * As the ServerInformation MBean was only introduced in Qpid JMX API 1.3 it is not possible to use it + * for identifying earlier broker JMX APIs for compatibility purposes. However, this can be accomplished + * by inspecting the 'version' property key of the UserManagement MBean JMX ObjectName. This was first + * introduced in Qpid JMX API 1.2 and so if present in the absence of the ServerInformation MBean + * indicates that version. If it is not present then a null value will be returned upon inspection and + * Qpid JMX API 1.1 can be assumed. + */ + int QPID_JMX_API_MAJOR_VERSION = 2; + int QPID_JMX_API_MINOR_VERSION = 3; + + + /** + * Attribute to represent the major version number for the management API. + * @return The major management version number. + * @since Qpid JMX API 1.3 + */ + @MBeanAttribute(name="ManagementApiMajorVersion", + description = "The major version number for the broker management API") + Integer getManagementApiMajorVersion() throws IOException; + + /** + * Attribute to represent the minor version number for the management API. + * @return The minor management version number. + * @since Qpid JMX API 1.3 + */ + @MBeanAttribute(name="ManagementApiMinorVersion", + description = "The minor version number for the broker management API") + Integer getManagementApiMinorVersion() throws IOException; + + /** + * Attribute to represent the build version string. + * @return The build version string + * @since Qpid JMX API 1.3 + */ + @MBeanAttribute(name="BuildVersion", + description = "The repository build version string") + String getBuildVersion() throws IOException; + + /** + * Attribute to represent the product version string. + * @return The product version string + * @since Qpid JMX API 1.3 + */ + @MBeanAttribute(name="ProductVersion", + description = "The product version string") + String getProductVersion() throws IOException; + + /** + * Resets all message and data statistics for the broker. + * + * @since Qpid JMX API 2.2 + */ + @MBeanOperation(name="resetStatistics", + description="Resets all message and data statistics for the broker", + impact= MBeanOperationInfo.ACTION) + void resetStatistics() throws Exception; + + /** + * Peak rate of messages delivered per second for the virtual host. + * + * @since Qpid JMX API 2.2 + */ + @MBeanAttribute(name="PeakMessageDeliveryRate", description=TYPE + " Peak Message Delivery Rate") + double getPeakMessageDeliveryRate(); + + /** + * Peak rate of bytes delivered per second for the broker. + * + * @since Qpid JMX API 2.2 + */ + @MBeanAttribute(name="PeakDataDeliveryRate", description=TYPE + " Peak Data Delivery Rate") + double getPeakDataDeliveryRate(); + + /** + * Rate of messages delivered per second for the broker. + * + * @since Qpid JMX API 2.2 + */ + @MBeanAttribute(name="MessageDeliveryRate", description=TYPE + " Message Delivery Rate") + double getMessageDeliveryRate(); + + /** + * Rate of bytes delivered per second for the broker. + * + * @since Qpid JMX API 2.2 + */ + @MBeanAttribute(name="DataDeliveryRate", description=TYPE + " Data Delivery Rate") + double getDataDeliveryRate(); + + /** + * Total count of messages delivered for the broker. + * + * @since Qpid JMX API 2.2 + */ + @MBeanAttribute(name="TotalMessagesDelivered", description=TYPE + " Total Messages Delivered") + long getTotalMessagesDelivered(); + + /** + * Total count of bytes for the broker. + * + * @since Qpid JMX API 2.2 + */ + @MBeanAttribute(name="TotalDataDelivered", description=TYPE + " Total Data Delivered") + long getTotalDataDelivered(); + + /** + * Peak rate of messages received per second for the broker. + * + * @since Qpid JMX API 2.2 + */ + @MBeanAttribute(name="PeakMessageReceiptRate", description=TYPE + " Peak Message Receipt Rate") + double getPeakMessageReceiptRate(); + + /** + * Peak rate of bytes received per second for the broker. + * + * @since Qpid JMX API 2.2 + */ + @MBeanAttribute(name="PeakDataReceiptRate", description=TYPE + " Peak Data Receipt Rate") + double getPeakDataReceiptRate(); + + /** + * Rate of messages received per second for the broker. + * + * @since Qpid JMX API 2.2 + */ + @MBeanAttribute(name="MessageReceiptRate", description=TYPE + " Message Receipt Rate") + double getMessageReceiptRate(); + + /** + * Rate of bytes received per second for the broker. + * + * @since Qpid JMX API 2.2 + */ + @MBeanAttribute(name="DataReceiptRate", description=TYPE + " Data Receipt Rate") + double getDataReceiptRate(); + + /** + * Total count of messages received for the broker. + * + * @since Qpid JMX API 2.2 + */ + @MBeanAttribute(name="TotalMessagesReceived", description=TYPE + " Total Messages Received") + long getTotalMessagesReceived(); + + /** + * Total count of bytes received for the broker. + * + * @since Qpid JMX API 2.2 + */ + @MBeanAttribute(name="TotalDataReceived", description=TYPE + " Total Data Received") + long getTotalDataReceived(); + + /** + * Is statistics collection enabled for this connection. + * + * @since Qpid JMX API 2.2 + */ + @MBeanAttribute(name="StatisticsEnabled", description=TYPE + " Statistics Enabled") + boolean isStatisticsEnabled(); +} diff --git a/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/mbeans/UserManagement.java b/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/mbeans/UserManagement.java new file mode 100644 index 0000000000..194bd83752 --- /dev/null +++ b/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/mbeans/UserManagement.java @@ -0,0 +1,214 @@ +/* + * 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.management.common.mbeans; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import org.apache.qpid.management.common.mbeans.annotations.MBeanOperation; +import org.apache.qpid.management.common.mbeans.annotations.MBeanOperationParameter; + +import javax.management.openmbean.TabularData; +import javax.management.MBeanOperationInfo; + +public interface UserManagement +{ + + String TYPE = "UserManagement"; + + //TabularType and contained CompositeType key/description information. + //For compatibility reasons, DONT MODIFY the existing key values if expanding the set. + String USERNAME = "Username"; + String RIGHTS_READ_ONLY = "read"; // item deprecated + String RIGHTS_READ_WRITE = "write"; // item deprecated + String RIGHTS_ADMIN = "admin"; // item deprecated + + List<String> COMPOSITE_ITEM_NAMES = Collections.unmodifiableList(Arrays.asList(USERNAME, RIGHTS_READ_ONLY, RIGHTS_READ_WRITE, RIGHTS_ADMIN)); + List<String> COMPOSITE_ITEM_DESCRIPTIONS = Collections.unmodifiableList( + Arrays.asList("Broker Login username", + "Item no longer used", + "Item no longer used", + "Item no longer used")); + + List<String> TABULAR_UNIQUE_INDEX = Collections.unmodifiableList(Arrays.asList(USERNAME)); + + //********** Operations *****************// + /** + * set password for user. + * + * Since Qpid JMX API 1.2 this operation expects plain text passwords to be provided. Prior to this, MD5 hashed passwords were supplied. + * + * @deprecated since Qpid JMX API 1.7 + * + * @param username The username for which the password is to be set + * @param password The password for the user + * + * @return The result of the operation + */ + @Deprecated + @MBeanOperation(name = "setPassword", description = "Set password for user.", + impact = MBeanOperationInfo.ACTION) + boolean setPassword(@MBeanOperationParameter(name = "username", description = "Username")String username, + //NOTE: parameter name was changed to 'passwd' in Qpid JMX API 1.7 to protect against older, incompatible management clients + @MBeanOperationParameter(name = "passwd", description = "Password")char[] password); + + /** + * Set password for a given user. + * + * @since Qpid JMX API 1.7 + * + * @param username The username to create + * @param password The password for the user + * + * @return The result of the operation + */ + @MBeanOperation(name = "setPassword", description = "Set password for user.", + impact = MBeanOperationInfo.ACTION) + boolean setPassword(@MBeanOperationParameter(name = "username", description = "Username")String username, + @MBeanOperationParameter(name = "password", description = "Password")String password); + + /** + * Set rights for users with given details. + * Since Qpid JMX API 2.3 all invocations will cause an exception to be thrown + * as access rights can no longer be maintain via this interface. + * + * @deprecated since Qpid JMX API 2.3 + * + * @param username The username to create + * @param read The set of permission to give the new user + * @param write The set of permission to give the new user + * @param admin The set of permission to give the new user + * + * @return The result of the operation + */ + @Deprecated + @MBeanOperation(name = "setRights", description = "Set access rights for user.", + impact = MBeanOperationInfo.ACTION) + boolean setRights(@MBeanOperationParameter(name = "username", description = "Username")String username, + @MBeanOperationParameter(name = "read", description = "Administration read")boolean read, + @MBeanOperationParameter(name = "readAndWrite", description = "Administration write")boolean write, + @MBeanOperationParameter(name = "admin", description = "Administration rights")boolean admin); + + /** + * Create users with given details. + * Since Qpid JMX API 2.3 if the user passes true for parameters read, write, or admin, a + * exception will be thrown as access rights can no longer be maintain via this interface. + * + * Since Qpid JMX API 1.2 this operation expects plain text passwords to be provided. Prior to this, MD5 hashed passwords were supplied. + * + * @deprecated since Qpid JMX API 1.7 + * + * @param username The username to create + * @param password The password for the user + * @param read The set of permission to give the new user + * @param write The set of permission to give the new user + * @param admin The set of permission to give the new user + * + * @return true if the user was created successfully, or false otherwise + */ + @Deprecated + @MBeanOperation(name = "createUser", description = "Create new user from system.", + impact = MBeanOperationInfo.ACTION) + boolean createUser(@MBeanOperationParameter(name = "username", description = "Username")String username, + //NOTE: parameter name was changed to 'passwd' in Qpid JMX API 1.7 to protect against older, incompatible management clients + @MBeanOperationParameter(name = "passwd", description = "Password")char[] password, + @MBeanOperationParameter(name = "read", description = "Administration read")boolean read, + @MBeanOperationParameter(name = "readAndWrite", description = "Administration write")boolean write, + @MBeanOperationParameter(name = "admin", description = "Administration rights")boolean admin); + + /** + * Create users with given details. + * Since Qpid JMX API 2.3 if the user passes true for parameters read, write, or admin, a + * exception will be thrown as access rights can no longer be maintain via this interface. + * + * @deprecated since Qpid JMX API 2.3 + * @since Qpid JMX API 1.7 + * + * @param username The username to create + * @param password The password for the user + * @param read The set of permission to give the new user + * @param write The set of permission to give the new user + * @param admin The set of permission to give the new user + * + * @return true if the user was created successfully, or false otherwise + */ + @Deprecated + @MBeanOperation(name = "createUser", description = "Create a new user.", + impact = MBeanOperationInfo.ACTION) + boolean createUser(@MBeanOperationParameter(name = "username", description = "Username")String username, + @MBeanOperationParameter(name = "password", description = "Password")String password, + @MBeanOperationParameter(name = "read", description = "Administration read")boolean read, + @MBeanOperationParameter(name = "readAndWrite", description = "Administration write")boolean write, + @MBeanOperationParameter(name = "admin", description = "Administration rights")boolean admin); + + /** + * Create users with given details. + * + * @since Qpid JMX API 2.3 + * + * @param username The username to create + * @param password The password for the user + * + * @return true if the user was created successfully, or false otherwise + */ + @MBeanOperation(name = "createUser", description = "Create a new user.", + impact = MBeanOperationInfo.ACTION) + boolean createUser(@MBeanOperationParameter(name = "username", description = "Username")String username, + @MBeanOperationParameter(name = "password", description = "Password")String password); + + /** + * View users returns all the users that are currently available to the system. + * + * @param username The user to delete + * + * @return The result of the operation + */ + @MBeanOperation(name = "deleteUser", description = "Delete user from system.", + impact = MBeanOperationInfo.ACTION) + boolean deleteUser(@MBeanOperationParameter(name = "username", description = "Username")String username); + + + /** + * Reload the date from disk + * + * Since Qpid JMX API 1.2 this operation reloads the password and authorisation files. Prior to this, only the authorisation file was reloaded. + * + * @return The result of the operation + */ + @MBeanOperation(name = "reloadData", description = "Reload the authentication and authorisation files from disk.", + impact = MBeanOperationInfo.ACTION) + boolean reloadData(); + + /** + * View users returns all the users that are currently available to the system. + * + * Since Qpid JMX API 2.3 the items that corresponded to read, write and admin flags + * are deprecated and always return false. + * + * @return a table of users data (Username, read, write, admin) + */ + @MBeanOperation(name = "viewUsers", description = "All users that are currently available to the system.", + impact = MBeanOperationInfo.INFO) + TabularData viewUsers(); + + +} diff --git a/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/mbeans/annotations/MBeanAttribute.java b/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/mbeans/annotations/MBeanAttribute.java new file mode 100644 index 0000000000..14e7211049 --- /dev/null +++ b/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/mbeans/annotations/MBeanAttribute.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.management.common.mbeans.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Annotation for MBean attributes. This should be used with getter or setter + * methods of attributes. + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +@Inherited +public @interface MBeanAttribute +{ + String name(); + String description(); +} diff --git a/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/mbeans/annotations/MBeanConstructor.java b/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/mbeans/annotations/MBeanConstructor.java new file mode 100644 index 0000000000..3131969813 --- /dev/null +++ b/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/mbeans/annotations/MBeanConstructor.java @@ -0,0 +1,39 @@ +/* + * 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.management.common.mbeans.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Annotation for MBean constructors. + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.CONSTRUCTOR) +@Inherited +public @interface MBeanConstructor +{ + String value(); +} diff --git a/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/mbeans/annotations/MBeanDescription.java b/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/mbeans/annotations/MBeanDescription.java new file mode 100644 index 0000000000..d70c7dd8f3 --- /dev/null +++ b/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/mbeans/annotations/MBeanDescription.java @@ -0,0 +1,38 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + * + */ + +package org.apache.qpid.management.common.mbeans.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Annotation for MBean class. + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +@Inherited +public @interface MBeanDescription { + String value(); +} diff --git a/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/mbeans/annotations/MBeanOperation.java b/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/mbeans/annotations/MBeanOperation.java new file mode 100644 index 0000000000..c608f64817 --- /dev/null +++ b/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/mbeans/annotations/MBeanOperation.java @@ -0,0 +1,43 @@ +/* + * 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.management.common.mbeans.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import javax.management.MBeanOperationInfo; + +/** + * Annotation for MBean operations. + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +@Inherited +public @interface MBeanOperation +{ + String name(); + String description(); + int impact() default MBeanOperationInfo.INFO; +} diff --git a/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/mbeans/annotations/MBeanOperationParameter.java b/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/mbeans/annotations/MBeanOperationParameter.java new file mode 100644 index 0000000000..25f2d09608 --- /dev/null +++ b/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/mbeans/annotations/MBeanOperationParameter.java @@ -0,0 +1,37 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + * + */ + +package org.apache.qpid.management.common.mbeans.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Annotation for MBean operation parameters. + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.PARAMETER) +public @interface MBeanOperationParameter { + String name(); + String description(); +} diff --git a/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/sasl/CRAMMD5HashedSaslClientFactory.java b/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/sasl/CRAMMD5HashedSaslClientFactory.java new file mode 100644 index 0000000000..be4897d6c4 --- /dev/null +++ b/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/sasl/CRAMMD5HashedSaslClientFactory.java @@ -0,0 +1,60 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.common.sasl; + +import java.util.Map; + +import javax.security.auth.callback.CallbackHandler; +import javax.security.sasl.Sasl; +import javax.security.sasl.SaslClient; +import javax.security.sasl.SaslClientFactory; +import javax.security.sasl.SaslException; + +public class CRAMMD5HashedSaslClientFactory implements SaslClientFactory +{ + /** The name of this mechanism */ + public static final String MECHANISM = "CRAM-MD5-HASHED"; + + public SaslClient createSaslClient(String[] mechanisms, String authorizationId, String protocol, + String serverName, Map<String, ?> props, CallbackHandler cbh) + throws SaslException + { + for (int i = 0; i < mechanisms.length; i++) + { + if (mechanisms[i].equals(MECHANISM)) + { + if (cbh == null) + { + throw new SaslException("CallbackHandler must not be null"); + } + + String[] mechs = {"CRAM-MD5"}; + return Sasl.createSaslClient(mechs, authorizationId, protocol, serverName, props, cbh); + } + } + return null; + } + + public String[] getMechanismNames(Map props) + { + return new String[]{MECHANISM}; + } +} diff --git a/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/sasl/ClientSaslFactory.java b/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/sasl/ClientSaslFactory.java new file mode 100644 index 0000000000..ee5803a220 --- /dev/null +++ b/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/sasl/ClientSaslFactory.java @@ -0,0 +1,54 @@ +/* + * + * 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.management.common.sasl; + +import java.util.Map; + +import javax.security.auth.callback.CallbackHandler; +import javax.security.sasl.SaslClient; +import javax.security.sasl.SaslClientFactory; +import javax.security.sasl.SaslException; + +public class ClientSaslFactory implements SaslClientFactory +{ + public SaslClient createSaslClient(String[] mechs, String authorizationId, String protocol, + String serverName, Map props, CallbackHandler cbh) + throws SaslException + { + for (int i = 0; i < mechs.length; i++) + { + if (mechs[i].equals("PLAIN")) + { + return new PlainSaslClient(authorizationId, cbh); + } + } + return null; + } + + /** + * Simple-minded implementation that ignores props + */ + public String[] getMechanismNames(Map props) + { + return new String[]{"PLAIN"}; + } + +} diff --git a/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/sasl/Constants.java b/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/sasl/Constants.java new file mode 100644 index 0000000000..31010baf8b --- /dev/null +++ b/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/sasl/Constants.java @@ -0,0 +1,33 @@ +/* + * + * 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.management.common.sasl; + +public class Constants +{ + + public final static String MECH_CRAMMD5 = "CRAM-MD5"; + public final static String MECH_PLAIN = "PLAIN"; + public final static String SASL_CRAMMD5 = "SASL/CRAM-MD5"; + public final static String SASL_PLAIN = "SASL/PLAIN"; + +} + diff --git a/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/sasl/JCAProvider.java b/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/sasl/JCAProvider.java new file mode 100644 index 0000000000..f5a3ca8ccc --- /dev/null +++ b/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/sasl/JCAProvider.java @@ -0,0 +1,56 @@ +/* + * + * 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.management.common.sasl; + +import java.security.Provider; +import java.util.Map; + +import javax.security.sasl.SaslClientFactory; + +public class JCAProvider extends Provider +{ + private static final long serialVersionUID = 1L; + + /** + * Creates the security provider with a map from SASL mechanisms to implementing factories. + * + * @param providerMap The map from SASL mechanims to implementing factory classes. + */ + public JCAProvider(Map<String, Class<? extends SaslClientFactory>> providerMap) + { + super("AMQSASLProvider", 1.0, "A JCA provider that registers all " + + "AMQ SASL providers that want to be registered"); + register(providerMap); + } + + /** + * Registers client factory classes for a map of mechanism names to client factory classes. + * + * @param providerMap The map from SASL mechanims to implementing factory classes. + */ + private void register(Map<String, Class<? extends SaslClientFactory>> providerMap) + { + for (Map.Entry<String, Class<? extends SaslClientFactory>> me : providerMap.entrySet()) + { + put("SaslClientFactory." + me.getKey(), me.getValue().getName()); + } + } +} diff --git a/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/sasl/PlainSaslClient.java b/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/sasl/PlainSaslClient.java new file mode 100644 index 0000000000..806975c32f --- /dev/null +++ b/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/sasl/PlainSaslClient.java @@ -0,0 +1,203 @@ +/* + * + * 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.management.common.sasl; + +import java.io.*; +import javax.security.auth.callback.*; +import javax.security.sasl.*; + +public class PlainSaslClient implements SaslClient +{ + + private boolean completed; + private CallbackHandler cbh; + private String authorizationID; + private String authenticationID; + private byte password[]; + private static byte SEPARATOR = 0; + + public PlainSaslClient(String authorizationID, CallbackHandler cbh) throws SaslException + { + completed = false; + this.cbh = cbh; + Object[] userInfo = getUserInfo(); + this.authorizationID = authorizationID; + this.authenticationID = (String) userInfo[0]; + this.password = (byte[]) userInfo[1]; + if (authenticationID == null || password == null) + { + throw new SaslException("PLAIN: authenticationID and password must be specified"); + } + } + + public byte[] evaluateChallenge(byte[] challenge) throws SaslException + { + if (completed) + { + throw new IllegalStateException("PLAIN: authentication already " + + "completed"); + } + completed = true; + try + { + byte authzid[] = + authorizationID == null ? null : authorizationID.getBytes("UTF8"); + byte authnid[] = authenticationID.getBytes("UTF8"); + byte response[] = + new byte[ + password.length + + authnid.length + + 2 + // SEPARATOR + (authzid != null ? authzid.length : 0) + ]; + int size = 0; + if (authzid != null) { + System.arraycopy(authzid, 0, response, 0, authzid.length); + size = authzid.length; + } + response[size++] = SEPARATOR; + System.arraycopy(authnid, 0, response, size, authnid.length); + size += authnid.length; + response[size++] = SEPARATOR; + System.arraycopy(password, 0, response, size, password.length); + clearPassword(); + return response; + } catch (UnsupportedEncodingException e) { + throw new SaslException("PLAIN: Cannot get UTF-8 encoding of ids", + e); + } + } + + public String getMechanismName() + { + return "PLAIN"; + } + + public boolean hasInitialResponse() + { + return true; + } + + public boolean isComplete() + { + return completed; + } + + public byte[] unwrap(byte[] incoming, int offset, int len) throws SaslException + { + if (completed) { + throw new IllegalStateException("PLAIN: this mechanism supports " + + "neither integrity nor privacy"); + } else { + throw new IllegalStateException("PLAIN: authentication not " + + "completed"); + } + } + + public byte[] wrap(byte[] outgoing, int offset, int len) throws SaslException + { + if (completed) + { + throw new IllegalStateException("PLAIN: this mechanism supports " + + "neither integrity nor privacy"); + } + else + { + throw new IllegalStateException("PLAIN: authentication not " + + "completed"); + } + } + + public Object getNegotiatedProperty(String propName) + { + if (completed) + { + if (propName.equals(Sasl.QOP)) + { + return "auth"; + } + else + { + return null; + } + } + else + { + throw new IllegalStateException("PLAIN: authentication not " + + "completed"); + } + } + + private void clearPassword() + { + if (password != null) + { + for (int i = 0 ; i < password.length ; i++) + { + password[i] = 0; + } + password = null; + } + } + + public void dispose() throws SaslException + { + clearPassword(); + } + + protected void finalize() + { + clearPassword(); + } + + private Object[] getUserInfo() throws SaslException + { + try + { + final String userPrompt = "PLAIN authentication id: "; + final String pwPrompt = "PLAIN password: "; + NameCallback nameCb = new NameCallback(userPrompt); + PasswordCallback passwordCb = new PasswordCallback(pwPrompt, false); + cbh.handle(new Callback[] { nameCb, passwordCb }); + String userid = nameCb.getName(); + char pwchars[] = passwordCb.getPassword(); + byte pwbytes[]; + if (pwchars != null) + { + pwbytes = (new String(pwchars)).getBytes("UTF8"); + passwordCb.clearPassword(); + } + else + { + pwbytes = null; + } + return (new Object[] { userid, pwbytes }); + } + catch (IOException e) + { + throw new SaslException("Cannot get password", e); + } + catch (UnsupportedCallbackException e) + { + throw new SaslException("Cannot get userid/password", e); + } + } +} diff --git a/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/sasl/SaslProvider.java b/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/sasl/SaslProvider.java new file mode 100644 index 0000000000..1eb44e35df --- /dev/null +++ b/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/sasl/SaslProvider.java @@ -0,0 +1,35 @@ +/* + * + * 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.management.common.sasl; + +import java.security.Provider; + +public class SaslProvider extends Provider +{ + private static final long serialVersionUID = -6978096016899676466L; + + public SaslProvider() + { + super("SaslClientFactory", 1.0, "SASL PLAIN CLIENT MECHANISM"); + put("SaslClientFactory.PLAIN", "ClientSaslFactory"); + } + +} diff --git a/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/sasl/UserPasswordCallbackHandler.java b/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/sasl/UserPasswordCallbackHandler.java new file mode 100644 index 0000000000..a1634f86d9 --- /dev/null +++ b/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/sasl/UserPasswordCallbackHandler.java @@ -0,0 +1,73 @@ +/* + * 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.management.common.sasl; + +import java.io.*; +import javax.security.auth.callback.*; + +public class UserPasswordCallbackHandler implements CallbackHandler +{ + private String user; + private char[] pwchars; + + public UserPasswordCallbackHandler(String user, String password) + { + this.user = user; + this.pwchars = password.toCharArray(); + } + + public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException + { + for (int i = 0; i < callbacks.length; i++) + { + if (callbacks[i] instanceof NameCallback) + { + NameCallback ncb = (NameCallback) callbacks[i]; + ncb.setName(user); + } + else if (callbacks[i] instanceof PasswordCallback) + { + PasswordCallback pcb = (PasswordCallback) callbacks[i]; + pcb.setPassword(pwchars); + } + else + { + throw new UnsupportedCallbackException(callbacks[i]); + } + } + } + + private void clearPassword() + { + if (pwchars != null) + { + for (int i = 0 ; i < pwchars.length ; i++) + { + pwchars[i] = 0; + } + pwchars = null; + } + } + + protected void finalize() + { + clearPassword(); + } +} diff --git a/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/sasl/UsernameHashedPasswordCallbackHandler.java b/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/sasl/UsernameHashedPasswordCallbackHandler.java new file mode 100644 index 0000000000..09aba1f3e1 --- /dev/null +++ b/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/sasl/UsernameHashedPasswordCallbackHandler.java @@ -0,0 +1,108 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.common.sasl; + +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + +import javax.security.auth.callback.Callback; +import javax.security.auth.callback.CallbackHandler; +import javax.security.auth.callback.NameCallback; +import javax.security.auth.callback.PasswordCallback; +import javax.security.auth.callback.UnsupportedCallbackException; + + +public class UsernameHashedPasswordCallbackHandler implements CallbackHandler +{ + private String user; + private char[] pwchars; + + public UsernameHashedPasswordCallbackHandler(String user, String password) throws Exception + { + this.user = user; + this.pwchars = getHash(password); + } + + public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException + { + for (int i = 0; i < callbacks.length; i++) + { + if (callbacks[i] instanceof NameCallback) + { + NameCallback ncb = (NameCallback) callbacks[i]; + ncb.setName(user); + } + else if (callbacks[i] instanceof PasswordCallback) + { + PasswordCallback pcb = (PasswordCallback) callbacks[i]; + pcb.setPassword(pwchars); + } + else + { + throw new UnsupportedCallbackException(callbacks[i]); + } + } + } + + + private void clearPassword() + { + if (pwchars != null) + { + for (int i = 0 ; i < pwchars.length ; i++) + { + pwchars[i] = 0; + } + pwchars = null; + } + } + + protected void finalize() + { + clearPassword(); + } + + public static char[] getHash(String text) throws NoSuchAlgorithmException, UnsupportedEncodingException + { + byte[] data = text.getBytes("utf-8"); + + MessageDigest md = MessageDigest.getInstance("MD5"); + + for (byte b : data) + { + md.update(b); + } + + byte[] digest = md.digest(); + + char[] hash = new char[digest.length ]; + + int index = 0; + for (byte b : digest) + { + hash[index++] = (char) b; + } + + return hash; + } +} |