summaryrefslogtreecommitdiff
path: root/java/broker/src/main/java/org/apache/qpid/server/configuration/store/ManagementModeStoreHandler.java
diff options
context:
space:
mode:
Diffstat (limited to 'java/broker/src/main/java/org/apache/qpid/server/configuration/store/ManagementModeStoreHandler.java')
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/configuration/store/ManagementModeStoreHandler.java327
1 files changed, 327 insertions, 0 deletions
diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/store/ManagementModeStoreHandler.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/store/ManagementModeStoreHandler.java
new file mode 100644
index 0000000000..e7c474bf55
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/store/ManagementModeStoreHandler.java
@@ -0,0 +1,327 @@
+package org.apache.qpid.server.configuration.store;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+
+import org.apache.log4j.Logger;
+import org.apache.qpid.server.BrokerOptions;
+import org.apache.qpid.server.configuration.ConfigurationEntry;
+import org.apache.qpid.server.configuration.ConfigurationEntryStore;
+import org.apache.qpid.server.configuration.IllegalConfigurationException;
+import org.apache.qpid.server.model.Port;
+import org.apache.qpid.server.model.Protocol;
+import org.apache.qpid.server.model.State;
+import org.apache.qpid.server.model.VirtualHost;
+import org.apache.qpid.server.util.MapValueConverter;
+
+public class ManagementModeStoreHandler implements ConfigurationEntryStore
+{
+ private static final Logger LOGGER = Logger.getLogger(ManagementModeStoreHandler.class);
+
+ private static final String MANAGEMENT_MODE_PORT_PREFIX = "MANAGEMENT-MODE-PORT-";
+ private static final String PORT_TYPE = Port.class.getSimpleName();
+ private static final String VIRTUAL_HOST_TYPE = VirtualHost.class.getSimpleName();
+ private static final String ATTRIBUTE_STATE = VirtualHost.STATE;
+
+ private final ConfigurationEntryStore _store;
+ private final Map<UUID, ConfigurationEntry> _cliEntries;
+ private final Map<UUID, Object> _quiescedEntries;
+ private final UUID _rootId;
+
+ public ManagementModeStoreHandler(ConfigurationEntryStore store, BrokerOptions options)
+ {
+ ConfigurationEntry storeRoot = store.getRootEntry();
+ _store = store;
+ _rootId = storeRoot.getId();
+ _cliEntries = createPortsFromCommadLineOptions(options);
+ _quiescedEntries = quiesceEntries(storeRoot, options);
+ }
+
+ @Override
+ public void open(String storeLocation)
+ {
+ throw new IllegalStateException("The store should be already opened");
+ }
+
+ @Override
+ public void open(String storeLocation, String initialStoreLocation)
+ {
+ throw new IllegalStateException("The store should be already opened");
+ }
+
+ @Override
+ public void open(String storeLocation, ConfigurationEntryStore initialStore)
+ {
+ throw new IllegalStateException("The store should be already opened");
+ }
+
+ @Override
+ public ConfigurationEntry getRootEntry()
+ {
+ return getEntry(_rootId);
+ }
+
+ @Override
+ public ConfigurationEntry getEntry(UUID id)
+ {
+ synchronized (_store)
+ {
+ if (_cliEntries.containsKey(id))
+ {
+ return _cliEntries.get(id);
+ }
+
+ ConfigurationEntry entry = _store.getEntry(id);
+ if (_quiescedEntries.containsKey(id))
+ {
+ entry = createEntryWithState(entry, State.QUIESCED);
+ }
+ else if (id == _rootId)
+ {
+ entry = createRootWithCLIEntries(entry);
+ }
+ return entry;
+ }
+ }
+
+ @Override
+ public void save(ConfigurationEntry... entries)
+ {
+ synchronized (_store)
+ {
+ ConfigurationEntry[] entriesToSave = new ConfigurationEntry[entries.length];
+
+ for (int i = 0; i < entries.length; i++)
+ {
+ ConfigurationEntry entry = entries[i];
+ UUID id = entry.getId();
+ if (_cliEntries.containsKey(id))
+ {
+ throw new IllegalConfigurationException("Cannot save configuration provided as command line argument:"
+ + entry);
+ }
+ else if (_quiescedEntries.containsKey(id))
+ {
+ // save entry with the original state
+ entry = createEntryWithState(entry, _quiescedEntries.get(ATTRIBUTE_STATE));
+ }
+ else if (_rootId.equals(id))
+ {
+ // save root without command line entries
+ Set<UUID> childrenIds = new HashSet<UUID>(entry.getChildrenIds());
+ if (!_cliEntries.isEmpty())
+ {
+ childrenIds.removeAll(_cliEntries.entrySet());
+ }
+ HashMap<String, Object> attributes = new HashMap<String, Object>(entry.getAttributes());
+ entry = new ConfigurationEntry(entry.getId(), entry.getType(), attributes, childrenIds, this);
+ }
+ entriesToSave[i] = entry;
+ }
+
+ _store.save(entriesToSave);
+ }
+ }
+
+ @Override
+ public UUID[] remove(UUID... entryIds)
+ {
+ synchronized (_store)
+ {
+ for (UUID id : entryIds)
+ {
+ if (_cliEntries.containsKey(id))
+ {
+ throw new IllegalConfigurationException("Cannot change configuration for command line entry:"
+ + _cliEntries.get(id));
+ }
+ }
+ UUID[] result = _store.remove(entryIds);
+ for (UUID id : entryIds)
+ {
+ if (_quiescedEntries.containsKey(id))
+ {
+ _quiescedEntries.remove(id);
+ }
+ }
+ return result;
+ }
+ }
+
+ @Override
+ public void copyTo(String copyLocation)
+ {
+ synchronized (_store)
+ {
+ _store.copyTo(copyLocation);
+ }
+ }
+
+ private Map<UUID, ConfigurationEntry> createPortsFromCommadLineOptions(BrokerOptions options)
+ {
+ int managementModeRmiPort = options.getManagementModeRmiPort();
+ if (managementModeRmiPort < 0)
+ {
+ throw new IllegalConfigurationException("Invalid rmi port is specified: " + managementModeRmiPort);
+ }
+ int managementModeConnectorPort = options.getManagementModeConnectorPort();
+ if (managementModeConnectorPort < 0)
+ {
+ throw new IllegalConfigurationException("Invalid connector port is specified: " + managementModeConnectorPort);
+ }
+ int managementModeHttpPort = options.getManagementModeHttpPort();
+ if (managementModeHttpPort < 0)
+ {
+ throw new IllegalConfigurationException("Invalid http port is specified: " + managementModeHttpPort);
+ }
+ Map<UUID, ConfigurationEntry> cliEntries = new HashMap<UUID, ConfigurationEntry>();
+ if (managementModeRmiPort != 0)
+ {
+ ConfigurationEntry entry = createCLIPortEntry(managementModeRmiPort, Protocol.RMI);
+ cliEntries.put(entry.getId(), entry);
+ if (managementModeConnectorPort == 0)
+ {
+ ConfigurationEntry connectorEntry = createCLIPortEntry(managementModeRmiPort + 100, Protocol.JMX_RMI);
+ cliEntries.put(connectorEntry.getId(), connectorEntry);
+ }
+ }
+ if (managementModeConnectorPort != 0)
+ {
+ ConfigurationEntry entry = createCLIPortEntry(managementModeConnectorPort, Protocol.JMX_RMI);
+ cliEntries.put(entry.getId(), entry);
+ }
+ if (managementModeHttpPort != 0)
+ {
+ ConfigurationEntry entry = createCLIPortEntry(managementModeHttpPort, Protocol.HTTP);
+ cliEntries.put(entry.getId(), entry);
+ }
+ return cliEntries;
+ }
+
+ private ConfigurationEntry createCLIPortEntry(int port, Protocol protocol)
+ {
+ Map<String, Object> attributes = new HashMap<String, Object>();
+ attributes.put(Port.PORT, port);
+ attributes.put(Port.PROTOCOLS, Collections.singleton(protocol));
+ attributes.put(Port.NAME, MANAGEMENT_MODE_PORT_PREFIX + protocol.name());
+ ConfigurationEntry portEntry = new ConfigurationEntry(UUID.randomUUID(), PORT_TYPE, attributes,
+ Collections.<UUID> emptySet(), this);
+ if (LOGGER.isDebugEnabled())
+ {
+ LOGGER.debug("Add management mode port configuration " + portEntry + " for port " + port + " and protocol "
+ + protocol);
+ }
+ return portEntry;
+ }
+
+ private ConfigurationEntry createRootWithCLIEntries(ConfigurationEntry storeRoot)
+ {
+ Set<UUID> childrenIds = new HashSet<UUID>(storeRoot.getChildrenIds());
+ if (!_cliEntries.isEmpty())
+ {
+ childrenIds.addAll(_cliEntries.keySet());
+ }
+ ConfigurationEntry root = new ConfigurationEntry(storeRoot.getId(), storeRoot.getType(), new HashMap<String, Object>(
+ storeRoot.getAttributes()), childrenIds, this);
+ return root;
+ }
+
+ private Map<UUID, Object> quiesceEntries(ConfigurationEntry storeRoot, BrokerOptions options)
+ {
+ Map<UUID, Object> quiescedEntries = new HashMap<UUID, Object>();
+ Set<UUID> childrenIds;
+ int managementModeRmiPort = options.getManagementModeRmiPort();
+ int managementModeConnectorPort = options.getManagementModeConnectorPort();
+ int managementModeHttpPort = options.getManagementModeHttpPort();
+ childrenIds = storeRoot.getChildrenIds();
+ for (UUID id : childrenIds)
+ {
+ ConfigurationEntry entry = _store.getEntry(id);
+ String entryType = entry.getType();
+ Map<String, Object> attributes = entry.getAttributes();
+ boolean quiesce = false;
+ if (VIRTUAL_HOST_TYPE.equals(entryType))
+ {
+ quiesce = true;
+ }
+ else if (PORT_TYPE.equalsIgnoreCase(entryType))
+ {
+ if (attributes == null)
+ {
+ throw new IllegalConfigurationException("Port attributes are not set in " + entry);
+ }
+ Set<Protocol> protocols = getPortProtocolsAttribute(attributes);
+ if (protocols == null)
+ {
+ quiesce = true;
+ }
+ else
+ {
+ for (Protocol protocol : protocols)
+ {
+ switch (protocol)
+ {
+ case JMX_RMI:
+ quiesce = managementModeConnectorPort > 0 || managementModeRmiPort > 0;
+ break;
+ case RMI:
+ quiesce = managementModeRmiPort > 0;
+ break;
+ case HTTP:
+ case HTTPS:
+ quiesce = managementModeHttpPort > 0;
+ break;
+ default:
+ quiesce = true;
+ }
+ }
+ }
+ }
+ if (quiesce)
+ {
+ if (LOGGER.isDebugEnabled())
+ {
+ LOGGER.debug("Management mode quiescing entry " + entry);
+ }
+
+ // save original state
+ quiescedEntries.put(entry.getId(), attributes.get(ATTRIBUTE_STATE));
+ }
+ }
+ return quiescedEntries;
+ }
+
+ private Set<Protocol> getPortProtocolsAttribute(Map<String, Object> attributes)
+ {
+ Object object = attributes.get(Port.PROTOCOLS);
+ if (object == null)
+ {
+ return null;
+ }
+ return MapValueConverter.getEnumSetAttribute(Port.PROTOCOLS, attributes, Protocol.class);
+ }
+
+ private ConfigurationEntry createEntryWithState(ConfigurationEntry entry, Object state)
+ {
+ Map<String, Object> attributes = new HashMap<String, Object>(entry.getAttributes());
+ if (state == null)
+ {
+ attributes.remove(ATTRIBUTE_STATE);
+ }
+ else
+ {
+ attributes.put(ATTRIBUTE_STATE, state);
+ }
+ Set<UUID> originalChildren = entry.getChildrenIds();
+ Set<UUID> children = null;
+ if (originalChildren != null)
+ {
+ children = new HashSet<UUID>(originalChildren);
+ }
+ return new ConfigurationEntry(entry.getId(), entry.getType(), attributes, children, entry.getStore());
+ }
+}