diff options
Diffstat (limited to 'qpid/tools/src/java/qpid-broker-plugins-management-qmf2/src/main/java/org/apache/qpid/server/qmf2/QmfManagementPlugin.java')
-rw-r--r-- | qpid/tools/src/java/qpid-broker-plugins-management-qmf2/src/main/java/org/apache/qpid/server/qmf2/QmfManagementPlugin.java | 280 |
1 files changed, 6 insertions, 274 deletions
diff --git a/qpid/tools/src/java/qpid-broker-plugins-management-qmf2/src/main/java/org/apache/qpid/server/qmf2/QmfManagementPlugin.java b/qpid/tools/src/java/qpid-broker-plugins-management-qmf2/src/main/java/org/apache/qpid/server/qmf2/QmfManagementPlugin.java index 978ecc15d4..d8e7a73a13 100644 --- a/qpid/tools/src/java/qpid-broker-plugins-management-qmf2/src/main/java/org/apache/qpid/server/qmf2/QmfManagementPlugin.java +++ b/qpid/tools/src/java/qpid-broker-plugins-management-qmf2/src/main/java/org/apache/qpid/server/qmf2/QmfManagementPlugin.java @@ -18,287 +18,19 @@ * under the License. * */ - package org.apache.qpid.server.qmf2; -// Misc Imports -import java.lang.reflect.Type; -import java.net.InetSocketAddress; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.UUID; - -// Simple Logging Facade 4 Java -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -// Java Broker Management Imports -import org.apache.qpid.server.logging.messages.ManagementConsoleMessages; - -import org.apache.qpid.server.model.Broker; -import org.apache.qpid.server.model.Exchange; -import org.apache.qpid.server.model.LifetimePolicy; import org.apache.qpid.server.model.ManagedAttribute; +import org.apache.qpid.server.model.ManagedObject; import org.apache.qpid.server.model.Plugin; -import org.apache.qpid.server.model.State; -import org.apache.qpid.server.model.VirtualHost; -import org.apache.qpid.server.model.adapter.AbstractPluginAdapter; -import org.apache.qpid.server.plugin.PluginFactory; -import org.apache.qpid.server.util.MapValueConverter; - -/** - * This class is a Qpid Java Broker Plugin which follows the Plugin API added in Qpid 0.22 it implements - * org.apache.qpid.server.model.Plugin and extends org.apache.qpid.server.model.adapter.AbstractPluginAdapter. - * <p> - * This Plugin provides access to the Java Broker Management Objects via QMF2 thus allowing the Java Broker to - * be managed and monitored in the same way as the C++ Broker. - * <p> - * The intention is for the Java Broker QmfManagementPlugin to conform to the same Management Schema as the C++ - * Broker (e.g. as specified in the management-schema.xml) in order to provide maximum cohesion between the - * two Broker implementations, however that's not entirely possible given differences between the underlying - * Management Models. The ultimate aim is to align the Management Models of the two Qpid Brokers and migrate - * to the AMQP 1.0 Management architecture when it becomes available. - * <p> - * This Plugin attempts to map properties from the Java org.apache.qpid.server.model.* classes to equivalent - * properties and statistics in the C++ Broker's Management Schema rather than expose them "natively", this is - * in order to try and maximise alignment between the two implementations and to try to allow the Java Broker - * to be managed by the Command Line tools used with the C++ Broker such as qpid-config etc. it's also to - * enable the Java Broker to be accessed via the QMF2 REST API and GUI. - * <p> - * This class only bootstraps the ManagementPlugin, the actual business logic is run from QmfManagementAgent. - * It's worth also mentioning that this Plugin actually establishes an AMQP Connection to the Broker via JMS. - * As it's a Broker Plugin it could conceivably use the low level Broker internal transport, this would probably - * be a little more efficient, but OTOH by using the JMS based approach I can use the QMF2 Agent code - * directly and implementing a complete QMF2 Agent for the Java Broker becomes "fairly simple" only requiring - * mappings between the org.apache.qpid.server.model.* classes and their QmfAgentData equivalents. - * <p> - * This Plugin requires config to be set, if this is not done the Plugin will not bootstrap. Config may be - * set in $QPID_WORK/config.json as part of the "plugins" config e.g. - * <pre> - * "plugins" : [ { - * "id" : "26887211-842c-3c4a-ab09-b1a1f64de369", - * "name" : "qmf2Management", - * "pluginType" : "MANAGEMENT-QMF2", - * "connectionURL" : "amqp://guest:guest@/?brokerlist='tcp://0.0.0.0:5672'" - * }] - * </pre> - * @author Fraser Adams - */ -public class QmfManagementPlugin extends AbstractPluginAdapter<QmfManagementPlugin> +@ManagedObject( category = false, type = "MANAGEMENT-QMF2" ) +public interface QmfManagementPlugin<X extends QmfManagementPlugin<X>> extends Plugin<X> { - private static final Logger _log = LoggerFactory.getLogger(QmfManagementPlugin.class); - - private static final String OPERATIONAL_LOGGING_NAME = "QMF2"; - - /************* Static initialiser used to implement org.apache.qpid.server.model.Plugin *************/ - - public static final String PLUGIN_TYPE = "MANAGEMENT-QMF2"; // attributes - public static final String NAME = "name"; - public static final String CONNECTION_URL = "connectionURL"; - - // default values - public static final String DEFAULT_NAME = "qmf2Management"; - public static final String DEFAULT_CONNECTION_URL = "amqp://guest:guest@/?brokerlist='tcp://0.0.0.0:5672'"; - - @SuppressWarnings("serial") - private static final Map<String, Object> DEFAULTS = Collections.unmodifiableMap(new HashMap<String, Object>() - {{ - put(NAME, DEFAULT_NAME); - put(CONNECTION_URL, DEFAULT_CONNECTION_URL); - put(PluginFactory.PLUGIN_TYPE, PLUGIN_TYPE); - }}); - - @SuppressWarnings("serial") - private static final Map<String, Type> ATTRIBUTE_TYPES = Collections.unmodifiableMap(new HashMap<String, Type>() - {{ - put(NAME, String.class); - put(CONNECTION_URL, String.class); - put(PluginFactory.PLUGIN_TYPE, String.class); - }}); - - /************************************ End of Static initialiser *************************************/ - - private final Broker<?> _broker; // Passed in by Plugin bootstrapping. - private final String _defaultVirtualHost; // Pulled from the broker attributes. - private final String _connectionURL; // Pulled from the Plugin config. - private QmfManagementAgent _agent; - - /** - * Constructor, called at broker startup by QmfManagementFactory.createInstance(). - * @param id the UUID of the Plugin. - * @param attributes a Map containing configuration information for the Plugin. - * @param broker the root Broker Management Object from which the other Management Objects may be obtained. - */ - public QmfManagementPlugin(UUID id, Broker broker, Map<String, Object> attributes) - { - super(id, DEFAULTS, MapValueConverter.convert(attributes, ATTRIBUTE_TYPES), broker); - addParent(Broker.class, broker); - _broker = broker; - _defaultVirtualHost = (String)broker.getAttribute("defaultVirtualHost"); - _connectionURL = (String)getAttribute(CONNECTION_URL); - } - - /** - * Set the state of the Plugin, I believe that this is called from the BrokerAdapter object when it - * has its own state set to State.ACTIVE or State.STOPPED. - * When State.ACTIVE is set this calls the start() method to startup the Plugin, when State.STOPPED - * is set this calls the stop() method to shutdown the Plugin. - * @param currentState the current state of the Plugin (ignored). - * @param desiredState the desired state of the Plugin (either State.ACTIVE or State.STOPPED). - * @return true if a valid state has been set, otherwise false. - */ - @Override // From org.apache.qpid.server.model.adapter.AbstractAdapter - protected boolean setState(State currentState, State desiredState) - { - if (desiredState == State.ACTIVE) - { - start(); - return true; - } - else if (desiredState == State.STOPPED) - { - stop(); - return true; - } - else - { - _log.info("QmfManagementPlugin.setState() received invalid desiredState {}", desiredState); - return false; - } - } - - /** - * Start the Plugin. Note that we bind the QMF Connection the the default Virtual Host, this is important - * in order to allow C++ or Python QMF Consoles to control the Java Broker, as they know nothing of Virtual - * Hosts and their Connection URL formats don't have a mechanism to specify Virtual Hosts. - * <p> - * Note too that it may be necessary to create the "qmf.default.direct" and "qmf.default.topic" exchanges - * as these don't exist by default on the Java Broker, however we have to check if they already exist - * as attempting to add an Exchange that already exists will cause IllegalArgumentException. - */ - private void start() - { - // Log "QMF2 Management Startup" message. - getBroker().getEventLogger().message(ManagementConsoleMessages.STARTUP(OPERATIONAL_LOGGING_NAME)); - - // Wrap main startup logic in a try/catch block catching Exception. The idea is that if anything goes - // wrong with QmfManagementPlugin startup it shouldn't fatally prevent the Broker from starting, though - // clearly QMF2 management will not be available. - try - { - // Iterate through the Virtual Hosts looking for the default Virtual Host. When we find the default - // we create the QMF exchanges then construct the QmfManagementAgent passing it the ConnectionURL. - boolean foundDefaultVirtualHost = false; - for (VirtualHost<?> vhost : _broker.getVirtualHosts()) - { - if (vhost.getName().equals(_defaultVirtualHost)) - { - foundDefaultVirtualHost = true; - - // Check if "qmf.default.direct" or "qmf.default.topic" already exist. It is important to - // check as attempting to add an Exchange that already exists will cause IllegalArgumentException. - boolean needDefaultDirect = true; - boolean needDefaultTopic = true; - for (Exchange exchange : vhost.getExchanges()) - { - if (exchange.getName().equals("qmf.default.direct")) - { - needDefaultDirect = false; - } - else if (exchange.getName().equals("qmf.default.topic")) - { - needDefaultTopic = false; - } - } - - // Create the QMF2 exchanges if necessary. - Map<String, Object> attributes = Collections.emptyMap(); - if (needDefaultDirect) - { - vhost.createExchange("qmf.default.direct", State.ACTIVE, true, - LifetimePolicy.PERMANENT, "direct", attributes); - } - - if (needDefaultTopic) - { - vhost.createExchange("qmf.default.topic", State.ACTIVE, true, - LifetimePolicy.PERMANENT, "topic", attributes); - } - - // Now create the *real* Agent which maps Broker Management Objects to QmdAgentData Objects. - _agent = new QmfManagementAgent(_connectionURL, _broker); - } - } - - // If we can't find a defaultVirtualHost we log that fact, the Plugin can't start in this case. - // Question. If defaultVirtualHost isn't configured or it doesn't match the name of one of the actual - // Virtual Hosts should we make the first one we find the de facto default for this Plugin?? - if (!foundDefaultVirtualHost) - { - _log.info("QmfManagementPlugin.start() could not find defaultVirtualHost"); - } - else if (_agent.isConnected()) - { - // Log QMF2 Management Ready message. - getBroker().getEventLogger().message(ManagementConsoleMessages.READY(OPERATIONAL_LOGGING_NAME)); - } - } - catch (Exception e) // Catch and log any Exception so we avoid Plugin failures stopping Broker startup. - { - _log.info("Exception {} caught in QmfManagementPlugin.start()", e.getMessage()); - } - } - - /** - * Stop the Plugin, closing the QMF Connection and logging "QMF2 Management Stopped". - */ - private void stop() - { - // When the Plugin state gets set to STOPPED we close the QMF Connection. - if (_agent != null) - { - _agent.close(); - } - - // Log "QMF2 Management Stopped" message (may not get displayed). - getBroker().getEventLogger().message(ManagementConsoleMessages.STOPPED(OPERATIONAL_LOGGING_NAME)); - } - - /** - * Accessor to retrieve the names of the available attributes. It is important to provide this overridden - * method because the Constructor uses this information when populating the underlying AbstractPlugin - * information. If we don't provide this override method getAttribute(name) will return the default values. - * @return the names of the available Plugin config attributes as a Collection. - */ - @Override // From org.apache.qpid.server.model.adapter.AbstractPluginAdapter - public Collection<String> getAttributeNames() - { - return getAttributeNames(QmfManagementPlugin.class); - } - - /** - * Accessor to retrieve the Plugin Type. - * @return the Plugin Type e.g. the String "MANAGEMENT-QMF2". - */ - @Override // From org.apache.qpid.server.model.Plugin - public String getPluginType() - { - return PLUGIN_TYPE; - } + String CONNECTION_URL = "connectionURL"; - /** - * Accessor to retrieve the connectionURL attribute. - * @return the JMS connectionURL of the Plugin. - */ - @ManagedAttribute - public String getConnectionURL() - { - return (String)getAttribute(CONNECTION_URL); - } + @ManagedAttribute( automate = true , defaultValue = "amqp://guest:guest@/?brokerlist='tcp://0.0.0.0:5672'") + String getConnectionURL(); } |