diff options
author | Alex Rudyy <orudyy@apache.org> | 2013-03-14 15:17:20 +0000 |
---|---|---|
committer | Alex Rudyy <orudyy@apache.org> | 2013-03-14 15:17:20 +0000 |
commit | 098f65fa6eca15ee673392681bcaabcbb049bd04 (patch) | |
tree | a066a62bfe57187b6039b43c2f5f0b22695aae5b | |
parent | a6758e9bb48c9ba985975f9af1e0db5105d7aaf8 (diff) | |
download | qpid-python-098f65fa6eca15ee673392681bcaabcbb049bd04.tar.gz |
QPID-4593: Remove initial store type command line argument, simplify configuration store interface, split json configuration store into memory and json stores
git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@1456473 13f79535-47bb-0310-9956-ffa450edef68
19 files changed, 953 insertions, 939 deletions
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/Broker.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/Broker.java index 5615e1e11b..2043b2cd67 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/Broker.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/Broker.java @@ -119,8 +119,7 @@ public class Broker configureLogging(logConfigFile, options.getLogWatchFrequency()); BrokerConfigurationStoreCreator storeCreator = new BrokerConfigurationStoreCreator(); - ConfigurationEntryStore store = storeCreator.createStore(storeLocation, storeType, - options.getInitialConfigurationStoreLocation(), options.getInitialConfigurationStoreLocation()); + ConfigurationEntryStore store = storeCreator.createStore(storeLocation, storeType, options.getInitialConfigurationLocation()); if (options.isManagementMode()) { diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/BrokerOptions.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/BrokerOptions.java index ec2894da55..23975ca6d5 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/BrokerOptions.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/BrokerOptions.java @@ -23,12 +23,16 @@ package org.apache.qpid.server; import java.io.File; import org.apache.qpid.server.configuration.BrokerProperties; +import org.apache.qpid.server.configuration.ConfigurationEntryStore; +import org.apache.qpid.server.configuration.store.JsonConfigurationEntryStore; public class BrokerOptions { public static final String DEFAULT_STORE_TYPE = "json"; public static final String DEFAULT_CONFIG_NAME_PREFIX = "config"; public static final String DEFAULT_LOG_CONFIG_FILE = "etc/log4j.xml"; + public static final String DEFAULT_INITIAL_CONFIG_LOCATION = + BrokerOptions.class.getClassLoader().getResource("initial-store.json").toExternalForm(); private String _logConfigFile; private Integer _logWatchFrequency = 0; @@ -36,8 +40,7 @@ public class BrokerOptions private String _configurationStoreLocation; private String _configurationStoreType; - private String _initialConfigurationStoreLocation; - private String _initialConfigurationStoreType; + private String _initialConfigurationLocation; private boolean _managementMode; private int _managementModeRmiPort; @@ -69,31 +72,6 @@ public class BrokerOptions _logWatchFrequency = logWatchFrequency; } - public void setInitialConfigurationStoreLocation(String initialConfigurationStore) - { - _initialConfigurationStoreLocation = initialConfigurationStore; - } - - public void setInitialConfigurationStoreType(String initialConfigurationStoreType) - { - _initialConfigurationStoreType = initialConfigurationStoreType; - } - - public String getInitialConfigurationStoreLocation() - { - return _initialConfigurationStoreLocation; - } - - public String getInitialConfigurationStoreType() - { - if(_initialConfigurationStoreType == null) - { - return DEFAULT_STORE_TYPE; - } - - return _initialConfigurationStoreType; - } - public boolean isManagementMode() { return _managementMode; @@ -222,4 +200,32 @@ public class BrokerOptions { _workingDir = workingDir; } + + /** + * Get the broker initial JSON configuration location. + * + * Defaults to an internal configuration file within the broker jar, which is loaded with the {@link JsonConfigurationEntryStore}. + * + * @return the previously set configuration location, or the default location if none was set. + */ + public String getInitialConfigurationLocation() + { + if(_initialConfigurationLocation == null) + { + return DEFAULT_INITIAL_CONFIG_LOCATION; + } + + return _initialConfigurationLocation; + } + + /** + * Set the absolute path or URL to use for the initial JSON configuration, which is loaded with the + * {@link JsonConfigurationEntryStore} in order to initialise any new {@link ConfigurationEntryStore} for the broker. + * + * Passing null clears any previously set value and returns to the default. + */ + public void setInitialConfigurationLocation(String initialConfigurationLocation) + { + _initialConfigurationLocation = initialConfigurationLocation; + } } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/Main.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/Main.java index 4927956c6c..ddda137bcc 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/Main.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/Main.java @@ -48,11 +48,8 @@ public class Main private static final Option OPTION_CONFIGURATION_STORE_TYPE = OptionBuilder.withArgName("type").hasArg() .withDescription("use given store type").withLongOpt("store-type").create("st"); - private static final Option OPTION_INITIAL_CONFIGURATION_STORE_PATH = OptionBuilder.withArgName("path").hasArg() - .withDescription("pass the location of initial store to use to create a user store").withLongOpt("initial-store-path").create("isp"); - - private static final Option OPTION_INITIAL_CONFIGURATION_STORE_TYPE = OptionBuilder.withArgName("type").hasArg() - .withDescription("the type of initial store").withLongOpt("initial-store-type").create("ist"); + private static final Option OPTION_INITIAL_CONFIGURATION_PATH = OptionBuilder.withArgName("path").hasArg() + .withDescription("pass the location of initial JSON config to use when creating a new configuration store").withLongOpt("initial-config-path").create("icp"); private static final Option OPTION_LOG_CONFIG_FILE = OptionBuilder.withArgName("file").hasArg() @@ -84,8 +81,7 @@ public class Main OPTIONS.addOption(OPTION_CONFIGURATION_STORE_TYPE); OPTIONS.addOption(OPTION_LOG_CONFIG_FILE); OPTIONS.addOption(OPTION_LOG_WATCH); - OPTIONS.addOption(OPTION_INITIAL_CONFIGURATION_STORE_PATH); - OPTIONS.addOption(OPTION_INITIAL_CONFIGURATION_STORE_TYPE); + OPTIONS.addOption(OPTION_INITIAL_CONFIGURATION_PATH); OPTIONS.addOption(OPTION_MANAGEMENT_MODE); OPTIONS.addOption(OPTION_RMI_PORT); OPTIONS.addOption(OPTION_CONNECTOR_PORT); @@ -194,15 +190,10 @@ public class Main options.setLogConfigFile(logConfig); } - String initialConfigurationStore = _commandLine.getOptionValue(OPTION_INITIAL_CONFIGURATION_STORE_PATH.getOpt()); - if (initialConfigurationStore != null) - { - options.setInitialConfigurationStoreLocation(initialConfigurationStore); - } - String initailConfigurationStoreType = _commandLine.getOptionValue(OPTION_INITIAL_CONFIGURATION_STORE_TYPE.getOpt()); - if (initailConfigurationStoreType != null) + String initialConfigLocation = _commandLine.getOptionValue(OPTION_INITIAL_CONFIGURATION_PATH.getOpt()); + if (initialConfigLocation != null) { - options.setInitialConfigurationStoreType(initailConfigurationStoreType); + options.setInitialConfigurationLocation(initialConfigLocation); } boolean managmentMode = _commandLine.hasOption(OPTION_MANAGEMENT_MODE.getOpt()); diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/BrokerConfigurationStoreCreator.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/BrokerConfigurationStoreCreator.java index 31e08ab88a..2bb63a803b 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/BrokerConfigurationStoreCreator.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/BrokerConfigurationStoreCreator.java @@ -23,7 +23,8 @@ package org.apache.qpid.server.configuration; import java.util.HashMap; import java.util.Map; -import org.apache.qpid.server.configuration.store.JsonConfigurationEntryStore; +import org.apache.qpid.server.configuration.store.MemoryConfigurationEntryStore; +import org.apache.qpid.server.plugin.ConfigurationStoreFactory; import org.apache.qpid.server.plugin.QpidServiceLoader; /** @@ -31,12 +32,6 @@ import org.apache.qpid.server.plugin.QpidServiceLoader; */ public class BrokerConfigurationStoreCreator { - /** - * URL to resource containing broker default configuration - */ - public static final String DEFAULT_INITIAL_STORE_LOCATION = BrokerConfigurationStoreCreator.class.getClassLoader() - .getResource("initial-store.json").toExternalForm(); - private Map<String, ConfigurationStoreFactory> _factories = new HashMap<String, ConfigurationStoreFactory>(); public BrokerConfigurationStoreCreator() @@ -58,45 +53,22 @@ public class BrokerConfigurationStoreCreator } /** - * Create broker configuration store for a given store location, store type, initial store location and initial store type + * Create broker configuration store for a given store location, store type, initial json config location * * @param storeLocation store location * @param storeType store type - * @param initialStoreLocation initial store location - * @param initialStoreType initial store type - * @return store instance opened at given store location + * @param initialConfigLocation initial store location * @throws IllegalConfigurationException if store type is unknown */ - public ConfigurationEntryStore createStore(String storeLocation, String storeType, String initialStoreLocation, - String initialStoreType) - { - ConfigurationEntryStore store = createStore(storeType); - if (initialStoreLocation == null) - { - initialStoreLocation = DEFAULT_INITIAL_STORE_LOCATION; - initialStoreType = JsonConfigurationEntryStore.STORE_TYPE; - } - if (storeType.equals(initialStoreType)) - { - store.open(storeLocation, initialStoreLocation); - } - else - { - ConfigurationEntryStore initialStore = createStore(initialStoreType); - initialStore.open(initialStoreLocation); - store.open(storeLocation, initialStore); - } - return store; - } - - private ConfigurationEntryStore createStore(String storeType) + public ConfigurationEntryStore createStore(String storeLocation, String storeType, String initialConfigLocation) { + ConfigurationEntryStore initialStore = new MemoryConfigurationEntryStore(initialConfigLocation, null); ConfigurationStoreFactory factory = _factories.get(storeType.toLowerCase()); if (factory == null) { throw new IllegalConfigurationException("Unknown store type: " + storeType); } - return factory.createStore(); + return factory.createStore(storeLocation, initialStore); } } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfigurationEntryStore.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfigurationEntryStore.java index 8238d147bd..d514bf25ce 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfigurationEntryStore.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfigurationEntryStore.java @@ -24,38 +24,6 @@ import java.util.UUID; public interface ConfigurationEntryStore { - /** - * Opens the store from a given location. - * <p> - * If location does not exists than a new empty store is created with a single root entry - * - * @param storeLocation store location - * @throws IllegalConfigurationException if store cannot be opened in the given location - */ - void open(String storeLocation); - - /** - * Opens the store from a given location. - * <p> - * If location does not exists than a new store is created either empty or from the initial store location if it is provided - * - * @param storeLocation store location - * @param initialStoreLocation initial store location - * @throws IllegalConfigurationException if store cannot be opened in the given location or initial store location does not - * exists or corrupted. - */ - void open(String storeLocation, String initialStoreLocation); - - /** - * Opens the store from a given location. - * <p> - * If location does not exists than a new store is created either empty or from the initial store if it is provided - * - * @param storeLocation store location - * @param initialStore initial store - * @throws IllegalConfigurationException if store cannot be opened in the given location - */ - void open(String storeLocation, ConfigurationEntryStore initialStore); /** * Returns stored root configuration entry @@ -95,4 +63,11 @@ public interface ConfigurationEntryStore * @throws IllegalConfigurationException if store cannot be copied into given location */ public void copyTo(String copyLocation); + + /** + * Return the store location for the opened store or null if store has not been opened. + * + * @return store location for the opened store or null if store has not been opened + */ + public String getStoreLocation(); } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/store/JsonConfigurationEntryStore.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/store/JsonConfigurationEntryStore.java index e11b63001a..2ee072e5ff 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/store/JsonConfigurationEntryStore.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/store/JsonConfigurationEntryStore.java @@ -1,324 +1,103 @@ package org.apache.qpid.server.configuration.store; -import static org.apache.qpid.server.configuration.ConfigurationEntry.ATTRIBUTE_NAME; - import java.io.File; import java.io.IOException; import java.io.InputStream; -import java.net.MalformedURLException; import java.net.URL; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; import java.util.Map; -import java.util.Set; -import java.util.TreeMap; -import java.util.TreeSet; import java.util.UUID; 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.Broker; -import org.apache.qpid.server.model.ConfiguredObject; -import org.apache.qpid.server.model.Model; -import org.apache.qpid.server.model.UUIDGenerator; import org.apache.qpid.util.FileUtils; -import org.apache.qpid.util.Strings; -import org.codehaus.jackson.JsonGenerationException; -import org.codehaus.jackson.JsonNode; -import org.codehaus.jackson.JsonParser; -import org.codehaus.jackson.JsonProcessingException; -import org.codehaus.jackson.map.JsonMappingException; -import org.codehaus.jackson.map.ObjectMapper; -import org.codehaus.jackson.map.SerializationConfig; -import org.codehaus.jackson.node.ArrayNode; -public class JsonConfigurationEntryStore implements ConfigurationEntryStore +public class JsonConfigurationEntryStore extends MemoryConfigurationEntryStore { public static final String STORE_TYPE = "json"; - public static final String IN_MEMORY = ":memory:"; - - private static final String DEFAULT_BROKER_NAME = "Broker"; - private static final String ID = "id"; - private static final String TYPE = "@type"; - private ObjectMapper _objectMapper; - private Map<UUID, ConfigurationEntry> _entries; private File _storeFile; - private UUID _rootId; - private Map<String, Class<? extends ConfiguredObject>> _relationshipClasses; - - public JsonConfigurationEntryStore() - { - _objectMapper = new ObjectMapper(); - _objectMapper.configure(SerializationConfig.Feature.INDENT_OUTPUT, true); - _objectMapper.configure(JsonParser.Feature.ALLOW_COMMENTS, true); - _entries = new HashMap<UUID, ConfigurationEntry>(); - _relationshipClasses = buildRelationshipClassMap(); - } - - @Override - public void open(String storeLocation) - { - if (_rootId != null) - { - throw new IllegalConfigurationException("The store has been opened alread"); - } - if (!IN_MEMORY.equals(storeLocation)) - { - _storeFile = new File(storeLocation); - } - createOrLoadStore(); - } - @Override - public void open(String storeLocation, String initialStoreLocation) + public JsonConfigurationEntryStore(String storeLocation, ConfigurationEntryStore initialStore) { - if (_rootId != null) - { - throw new IllegalConfigurationException("The store has been opened already"); - } - if (!IN_MEMORY.equals(storeLocation)) - { - _storeFile = new File(storeLocation); - if ((!_storeFile.exists() || _storeFile.length() == 0) && initialStoreLocation != null) - { - copyInitialStoreFile(initialStoreLocation); - } - createOrLoadStore(); - } - else - { - if (initialStoreLocation == null) - { - createRootEntryIfNotExists(); - } - else - { - load(toURL(initialStoreLocation)); - } - } - } - - @Override - public void open(String storeLocation, ConfigurationEntryStore initialStore) - { - if (_rootId != null) - { - throw new IllegalConfigurationException("The store has been opened already"); - } - boolean copyStore = false; - if (IN_MEMORY.equals(storeLocation)) - { - copyStore = initialStore != null; - } - else - { - _storeFile = new File(storeLocation); - if ((!_storeFile.exists() || _storeFile.length() == 0) && initialStore != null) - { - createStoreFileIfNotExist(_storeFile); - copyStore = true; - } - } - if (copyStore) - { - ConfigurationEntry rootEntry = initialStore.getRootEntry(); - _rootId = rootEntry.getId(); - copyEntry(rootEntry.getId(), initialStore); - saveAsTree(); - } - else + super(); + _storeFile = new File(storeLocation); + if ((!_storeFile.exists() || _storeFile.length() == 0)) { - createOrLoadStore(); + initialiseStore(_storeFile, initialStore); } + load(fileToURL(_storeFile)); } @Override public synchronized UUID[] remove(UUID... entryIds) { - List<UUID> removedIds = new ArrayList<UUID>(); - boolean anyRemoved = false; - for (UUID uuid : entryIds) + UUID[] removedIds = super.remove(entryIds); + if (removedIds.length > 0) { - if (_rootId.equals(uuid)) - { - throw new IllegalConfigurationException("Cannot remove root entry"); - } - } - for (UUID uuid : entryIds) - { - if (removeInternal(uuid)) - { - anyRemoved = true; - - // remove references to the entry from parent entries - for (ConfigurationEntry entry : _entries.values()) - { - if (entry.hasChild(uuid)) - { - Set<UUID> children = new HashSet<UUID>(entry.getChildrenIds()); - children.remove(uuid); - ConfigurationEntry referal = new ConfigurationEntry(entry.getId(), entry.getType(), - entry.getAttributes(), children, this); - _entries.put(entry.getId(), referal); - } - } - removedIds.add(uuid); - } + saveAsTree(_storeFile); } - if (anyRemoved) - { - saveAsTree(); - } - return removedIds.toArray(new UUID[removedIds.size()]); + return removedIds; } @Override public synchronized void save(ConfigurationEntry... entries) { - boolean anySaved = false; - for (ConfigurationEntry entry : entries) + if (replaceEntries(entries)) { - ConfigurationEntry oldEntry = _entries.put(entry.getId(), entry); - if (!entry.equals(oldEntry)) - { - anySaved = true; - } - } - if (anySaved) - { - saveAsTree(); + saveAsTree(_storeFile); } } @Override - public ConfigurationEntry getRootEntry() + public String getStoreLocation() { - return getEntry(_rootId); - } - - @Override - public synchronized ConfigurationEntry getEntry(UUID id) - { - return _entries.get(id); - } - - @Override - public void copyTo(String copyLocation) - { - if (_rootId == null) - { - throw new IllegalConfigurationException("The store has not been opened"); - } - File file = new File(copyLocation); - if (!file.exists()) - { - createStoreFileIfNotExist(file); - } - saveAsTree(_rootId, _entries, _objectMapper, file); + return _storeFile.getAbsolutePath(); } @Override public String toString() { - return "JsonConfigurationEntryStore [_storeFile=" + _storeFile + ", _rootId=" + _rootId + "]"; + return "JsonConfigurationEntryStore [_storeFile=" + _storeFile + ", _rootId=" + getRootEntry().getId() + "]"; } - private Map<String, Class<? extends ConfiguredObject>> buildRelationshipClassMap() - { - Map<String, Class<? extends ConfiguredObject>> relationships = new HashMap<String, Class<? extends ConfiguredObject>>(); - Collection<Class<? extends ConfiguredObject>> children = Model.getInstance().getChildTypes(Broker.class); - for (Class<? extends ConfiguredObject> childClass : children) + private void initialiseStore(File storeFile, ConfigurationEntryStore initialStore) + { + createFileIfNotExist(storeFile); + if (initialStore == null) { - String name = childClass.getSimpleName().toLowerCase(); - String relationshipName = name + (name.endsWith("s") ? "es" : "s"); - relationships.put(relationshipName, childClass); + throw new IllegalConfigurationException("Cannot create new store without an initial store"); } - return relationships; - } - - private void createOrLoadStore() - { - if (_storeFile != null) + else { - if (!_storeFile.exists() || _storeFile.length() == 0) + if (initialStore instanceof MemoryConfigurationEntryStore && initialStore.getStoreLocation() != null) { - createStoreFileIfNotExist(_storeFile); + copyInitialStoreFile(initialStore.getStoreLocation(), storeFile); } else { - load(fileToURL(_storeFile)); + ConfigurationEntry rootEntry = initialStore.getRootEntry(); + Map<UUID, ConfigurationEntry> entries = new HashMap<UUID, ConfigurationEntry>(); + copyEntry(rootEntry.getId(), initialStore, entries); + saveAsTree(rootEntry.getId(), entries, getObjectMapper(), storeFile); } } - - createRootEntryIfNotExists(); - } - - private void createRootEntryIfNotExists() - { - if (_rootId == null) - { - // create a root entry for an empty store - ConfigurationEntry brokerEntry = new ConfigurationEntry(UUIDGenerator.generateRandomUUID(), - Broker.class.getSimpleName(), Collections.<String, Object> emptyMap(), Collections.<UUID> emptySet(), this); - _rootId = brokerEntry.getId(); - _entries.put(_rootId, brokerEntry); - } } - private void load(URL url) + private void copyInitialStoreFile(String initialStoreLocation, File storeFile) { - InputStream is = null; - try - { - is = url.openStream(); - JsonNode node = loadJsonNodes(is, _objectMapper); - ConfigurationEntry brokerEntry = toEntry(node, Broker.class, _entries); - _rootId = brokerEntry.getId(); - } - catch (IOException e) - { - throw new IllegalConfigurationException("Cannot load store from: " + url, e); - } - finally - { - if (is != null) - { - if (is != null) - { - try - { - is.close(); - } - catch (IOException e) - { - throw new IllegalConfigurationException("Cannot close input stream for: " + url, e); - } - } - } - } - } - - private void copyInitialStoreFile(String initialStoreLocation) - { - createStoreFileIfNotExist(_storeFile); URL initialStoreURL = toURL(initialStoreLocation); InputStream in = null; try { in = initialStoreURL.openStream(); - FileUtils.copy(in, _storeFile); + FileUtils.copy(in, storeFile); } catch (IOException e) { - throw new IllegalConfigurationException("Cannot create store file " + _storeFile + " by copying initial store from " + initialStoreLocation , e); + throw new IllegalConfigurationException("Cannot create store file " + storeFile + " by copying initial store from " + initialStoreLocation , e); } finally { @@ -336,376 +115,4 @@ public class JsonConfigurationEntryStore implements ConfigurationEntryStore } } - private URL fileToURL(File storeFile) - { - URL storeURL = null; - try - { - storeURL = storeFile.toURI().toURL(); - } - catch (MalformedURLException e) - { - throw new IllegalConfigurationException("Cannot create URL for file " + storeFile, e); - } - return storeURL; - } - - private boolean removeInternal(UUID entryId) - { - ConfigurationEntry oldEntry = _entries.remove(entryId); - if (oldEntry != null) - { - Set<UUID> children = oldEntry.getChildrenIds(); - if (children != null && !children.isEmpty()) - { - for (UUID childId : children) - { - removeInternal(childId); - } - } - return true; - } - return false; - } - - private void saveAsTree() - { - if (_storeFile != null) - { - saveAsTree(_rootId, _entries, _objectMapper, _storeFile); - } - } - - private void saveAsTree(UUID rootId, Map<UUID, ConfigurationEntry> entries, ObjectMapper mapper, File file) - { - Map<String, Object> tree = toTree(rootId, entries); - try - { - mapper.writeValue(file, tree); - } - catch (JsonGenerationException e) - { - throw new IllegalConfigurationException("Cannot generate json!", e); - } - catch (JsonMappingException e) - { - throw new IllegalConfigurationException("Cannot map objects for json serialization!", e); - } - catch (IOException e) - { - throw new IllegalConfigurationException("Cannot save configuration into " + file + "!", e); - } - } - - private Map<String, Object> toTree(UUID rootId, Map<UUID, ConfigurationEntry> entries) - { - ConfigurationEntry entry = entries.get(rootId); - if (entry == null || !entry.getId().equals(rootId)) - { - throw new IllegalConfigurationException("Cannot find entry with id " + rootId + "!"); - } - Map<String, Object> tree = new TreeMap<String, Object>(); - Map<String, Object> attributes = entry.getAttributes(); - if (attributes != null) - { - tree.putAll(attributes); - } - tree.put(ID, entry.getId()); - tree.put(TYPE, entry.getType()); - Set<UUID> childrenIds = entry.getChildrenIds(); - if (childrenIds != null && !childrenIds.isEmpty()) - { - for (UUID relationship : childrenIds) - { - ConfigurationEntry child = entries.get(relationship); - if (child != null) - { - String relationshipName = child.getType().toLowerCase() + "s"; - - @SuppressWarnings("unchecked") - Collection<Map<String, Object>> children = (Collection<Map<String, Object>>) tree.get(relationshipName); - if (children == null) - { - children = new ArrayList<Map<String, Object>>(); - tree.put(relationshipName, children); - } - Map<String, Object> childAsMap = toTree(relationship, entries); - children.add(childAsMap); - } - } - } - return tree; - } - - private JsonNode loadJsonNodes(InputStream is, ObjectMapper mapper) - { - JsonNode root = null; - try - { - root = mapper.readTree(is); - } - catch (JsonProcessingException e) - { - throw new IllegalConfigurationException("Cannot parse json", e); - } - catch (IOException e) - { - throw new IllegalConfigurationException("Cannot read json", e); - } - return root; - } - - private ConfigurationEntry toEntry(JsonNode parent, Class<? extends ConfiguredObject> expectedConfiguredObjectClass, Map<UUID, ConfigurationEntry> entries) - { - Map<String, Object> attributes = null; - Set<UUID> childrenIds = new TreeSet<UUID>(); - Iterator<String> fieldNames = parent.getFieldNames(); - String type = null; - String idAsString = null; - while (fieldNames.hasNext()) - { - String fieldName = fieldNames.next(); - JsonNode fieldNode = parent.get(fieldName); - if (fieldName.equals(ID)) - { - idAsString = fieldNode.asText(); - } - else if (fieldName.equals(TYPE)) - { - type = fieldNode.asText(); - } - else if (fieldNode.isArray()) - { - // array containing either broker children or attribute values - Iterator<JsonNode> elements = fieldNode.getElements(); - List<Object> fieldValues = null; - while (elements.hasNext()) - { - JsonNode element = elements.next(); - if (element.isObject()) - { - Class<? extends ConfiguredObject> expectedChildConfiguredObjectClass = _relationshipClasses.get(fieldName); - // assuming it is a child node - ConfigurationEntry entry = toEntry(element, expectedChildConfiguredObjectClass, entries); - childrenIds.add(entry.getId()); - } - else - { - if (fieldValues == null) - { - fieldValues = new ArrayList<Object>(); - } - fieldValues.add(toObject(element)); - } - } - if (fieldValues != null) - { - Object[] array = fieldValues.toArray(new Object[fieldValues.size()]); - attributes.put(fieldName, array); - } - } - else if (fieldNode.isObject()) - { - // ignore, in-line objects are not supported yet - } - else - { - // primitive attribute - Object value = toObject(fieldNode); - if (attributes == null) - { - attributes = new HashMap<String, Object>(); - } - attributes.put(fieldName, value); - } - } - - if (type == null) - { - if (expectedConfiguredObjectClass == null) - { - throw new IllegalConfigurationException("Type attribute is not provided for configuration entry " + parent); - } - else - { - type = expectedConfiguredObjectClass.getSimpleName(); - } - } - String name = null; - if (attributes != null) - { - name = (String) attributes.get(ATTRIBUTE_NAME); - } - if ((name == null || "".equals(name))) - { - if (expectedConfiguredObjectClass == Broker.class) - { - name = DEFAULT_BROKER_NAME; - } - else - { - throw new IllegalConfigurationException("Name attribute is not provided for configuration entry " + parent); - } - } - UUID id = null; - if (idAsString == null) - { - if (expectedConfiguredObjectClass == Broker.class) - { - id = UUIDGenerator.generateRandomUUID(); - } - else - { - id = UUIDGenerator.generateBrokerChildUUID(type, name); - } - } - else - { - try - { - id = UUID.fromString(idAsString); - } - catch (Exception e) - { - throw new IllegalConfigurationException( - "ID attribute value does not conform to UUID format for configuration entry " + parent); - } - } - ConfigurationEntry entry = new ConfigurationEntry(id, type, attributes, childrenIds, this); - if (entries.containsKey(id)) - { - throw new IllegalConfigurationException("Duplicate id is found: " + id - + "! The following configuration entries have the same id: " + entries.get(id) + ", " + entry); - } - entries.put(id, entry); - return entry; - } - - private Object toObject(JsonNode node) - { - if (node.isValueNode()) - { - if (node.isBoolean()) - { - return node.asBoolean(); - } - else if (node.isDouble()) - { - return node.asDouble(); - } - else if (node.isInt()) - { - return node.asInt(); - } - else if (node.isLong()) - { - return node.asLong(); - } - else if (node.isNull()) - { - return null; - } - else - { - return Strings.expand(node.asText()); - } - } - else if (node.isArray()) - { - return toArray(node); - } - else if (node.isObject()) - { - return toMap(node); - } - else - { - throw new IllegalConfigurationException("Unexpected node: " + node); - } - } - - private Map<String, Object> toMap(JsonNode node) - { - Map<String, Object> object = new TreeMap<String, Object>(); - Iterator<String> fieldNames = node.getFieldNames(); - while (fieldNames.hasNext()) - { - String name = fieldNames.next(); - Object value = toObject(node.get(name)); - object.put(name, value); - } - return object; - } - - private Object toArray(JsonNode node) - { - ArrayNode arrayNode = (ArrayNode) node; - Object[] array = new Object[arrayNode.size()]; - Iterator<JsonNode> elements = arrayNode.getElements(); - for (int i = 0; i < array.length; i++) - { - array[i] = toObject(elements.next()); - } - return array; - } - - /* - * Initial store location can be URL or absolute path - */ - private URL toURL(String location) - { - URL url = null; - try - { - url = new URL(location); - } - catch (MalformedURLException e) - { - File locationFile = new File(location); - url = fileToURL(locationFile); - } - return url; - } - - private void createStoreFileIfNotExist(File file) - { - File parent = file.getParentFile(); - if (!parent.exists()) - { - if (!parent.mkdirs()) - { - throw new IllegalConfigurationException("Cannot create folders " + parent); - } - } - try - { - file.createNewFile(); - } - catch (IOException e) - { - throw new IllegalConfigurationException("Cannot create file " + file, e); - } - } - - private void copyEntry(UUID entryId, ConfigurationEntryStore initialStore) - { - ConfigurationEntry entry = initialStore.getEntry(entryId); - if (entry != null) - { - if (_entries.containsKey(entryId)) - { - throw new IllegalConfigurationException("Duplicate id is found: " + entryId - + "! The following configuration entries have the same id: " + _entries.get(entryId) + ", " + entry); - } - _entries.put(entryId, entry); - Set<UUID> children = entry.getChildrenIds(); - if (children != null) - { - for (UUID uuid : children) - { - copyEntry(uuid, initialStore); - } - } - } - } } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/store/ManagementModeStoreHandler.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/store/ManagementModeStoreHandler.java index e7c474bf55..59247df25a 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/store/ManagementModeStoreHandler.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/store/ManagementModeStoreHandler.java @@ -42,24 +42,6 @@ public class ManagementModeStoreHandler implements ConfigurationEntryStore } @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); @@ -161,6 +143,12 @@ public class ManagementModeStoreHandler implements ConfigurationEntryStore } } + @Override + public String getStoreLocation() + { + return _store.getStoreLocation(); + } + private Map<UUID, ConfigurationEntry> createPortsFromCommadLineOptions(BrokerOptions options) { int managementModeRmiPort = options.getManagementModeRmiPort(); diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/store/MemoryConfigurationEntryStore.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/store/MemoryConfigurationEntryStore.java new file mode 100644 index 0000000000..48ca01c312 --- /dev/null +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/store/MemoryConfigurationEntryStore.java @@ -0,0 +1,668 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.configuration.store; + +import static org.apache.qpid.server.configuration.ConfigurationEntry.ATTRIBUTE_NAME; + +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeMap; +import java.util.TreeSet; +import java.util.UUID; + +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.Broker; +import org.apache.qpid.server.model.ConfiguredObject; +import org.apache.qpid.server.model.Model; +import org.apache.qpid.server.model.UUIDGenerator; +import org.apache.qpid.util.Strings; +import org.codehaus.jackson.JsonGenerationException; +import org.codehaus.jackson.JsonNode; +import org.codehaus.jackson.JsonParser; +import org.codehaus.jackson.JsonProcessingException; +import org.codehaus.jackson.map.JsonMappingException; +import org.codehaus.jackson.map.ObjectMapper; +import org.codehaus.jackson.map.SerializationConfig; +import org.codehaus.jackson.node.ArrayNode; + +public class MemoryConfigurationEntryStore implements ConfigurationEntryStore +{ + public static final String STORE_TYPE = "memory"; + + private static final String DEFAULT_BROKER_NAME = "Broker"; + private static final String ID = "id"; + private static final String TYPE = "@type"; + + private final ObjectMapper _objectMapper; + private final Map<UUID, ConfigurationEntry> _entries; + private final Map<String, Class<? extends ConfiguredObject>> _relationshipClasses; + + private String _storeLocation; + private UUID _rootId; + + protected MemoryConfigurationEntryStore() + { + _objectMapper = new ObjectMapper(); + _objectMapper.configure(SerializationConfig.Feature.INDENT_OUTPUT, true); + _objectMapper.configure(JsonParser.Feature.ALLOW_COMMENTS, true); + _entries = new HashMap<UUID, ConfigurationEntry>(); + _relationshipClasses = buildRelationshipClassMap(); + } + + MemoryConfigurationEntryStore(String json) + { + this(); + if (json == null || "".equals(json)) + { + createRootEntry(); + } + else + { + loadFromJson(json); + } + } + + public MemoryConfigurationEntryStore(String initialStoreLocation, ConfigurationEntryStore initialStore) + { + this(); + if (initialStore == null && (initialStoreLocation == null || "".equals(initialStoreLocation) )) + { + throw new IllegalConfigurationException("Cannot instantiate the memory broker store as neither initial store nor initial store location is provided"); + } + + if (initialStore != null) + { + if (initialStore instanceof MemoryConfigurationEntryStore) + { + _storeLocation = initialStore.getStoreLocation(); + } + _rootId = initialStore.getRootEntry().getId(); + copyEntry(_rootId, initialStore, _entries); + } + else + { + _storeLocation = initialStoreLocation; + load(toURL(_storeLocation)); + } + } + + @Override + public synchronized UUID[] remove(UUID... entryIds) + { + List<UUID> removedIds = new ArrayList<UUID>(); + for (UUID uuid : entryIds) + { + if (_rootId.equals(uuid)) + { + throw new IllegalConfigurationException("Cannot remove root entry"); + } + } + for (UUID uuid : entryIds) + { + if (removeInternal(uuid)) + { + // remove references to the entry from parent entries + for (ConfigurationEntry entry : _entries.values()) + { + if (entry.hasChild(uuid)) + { + Set<UUID> children = new HashSet<UUID>(entry.getChildrenIds()); + children.remove(uuid); + ConfigurationEntry referal = new ConfigurationEntry(entry.getId(), entry.getType(), + entry.getAttributes(), children, this); + _entries.put(entry.getId(), referal); + } + } + removedIds.add(uuid); + } + } + + return removedIds.toArray(new UUID[removedIds.size()]); + } + + @Override + public synchronized void save(ConfigurationEntry... entries) + { + replaceEntries(entries); + } + + @Override + public ConfigurationEntry getRootEntry() + { + return getEntry(_rootId); + } + + @Override + public synchronized ConfigurationEntry getEntry(UUID id) + { + return _entries.get(id); + } + + @Override + public void copyTo(String copyLocation) + { + File file = new File(copyLocation); + if (!file.exists()) + { + createFileIfNotExist(file); + } + saveAsTree(file); + } + + @Override + public String getStoreLocation() + { + return _storeLocation; + } + + @Override + public String toString() + { + return "MemoryConfigurationEntryStore [_rootId=" + _rootId + "]"; + } + + protected boolean replaceEntries(ConfigurationEntry... entries) + { + boolean anySaved = false; + for (ConfigurationEntry entry : entries) + { + ConfigurationEntry oldEntry = _entries.put(entry.getId(), entry); + if (!entry.equals(oldEntry)) + { + anySaved = true; + } + } + return anySaved; + } + + protected ObjectMapper getObjectMapper() + { + return _objectMapper; + } + + protected void saveAsTree(File file) + { + saveAsTree(_rootId, _entries, _objectMapper, file); + } + + protected void saveAsTree(UUID rootId, Map<UUID, ConfigurationEntry> entries, ObjectMapper mapper, File file) + { + Map<String, Object> tree = toTree(rootId, entries); + try + { + mapper.writeValue(file, tree); + } + catch (JsonGenerationException e) + { + throw new IllegalConfigurationException("Cannot generate json!", e); + } + catch (JsonMappingException e) + { + throw new IllegalConfigurationException("Cannot map objects for json serialization!", e); + } + catch (IOException e) + { + throw new IllegalConfigurationException("Cannot save configuration into " + file + "!", e); + } + } + + protected void load(URL url) + { + InputStream is = null; + try + { + is = url.openStream(); + JsonNode node = loadJsonNodes(is, _objectMapper); + ConfigurationEntry brokerEntry = toEntry(node, Broker.class, _entries); + _rootId = brokerEntry.getId(); + } + catch (IOException e) + { + throw new IllegalConfigurationException("Cannot load store from: " + url, e); + } + finally + { + if (is != null) + { + if (is != null) + { + try + { + is.close(); + } + catch (IOException e) + { + throw new IllegalConfigurationException("Cannot close input stream for: " + url, e); + } + } + } + } + } + + protected URL toURL(String location) + { + URL url = null; + try + { + url = new URL(location); + } + catch (MalformedURLException e) + { + File locationFile = new File(location); + url = fileToURL(locationFile); + } + return url; + } + + protected void createFileIfNotExist(File file) + { + File parent = file.getParentFile(); + if (!parent.exists()) + { + if (!parent.mkdirs()) + { + throw new IllegalConfigurationException("Cannot create folders " + parent); + } + } + try + { + file.createNewFile(); + } + catch (IOException e) + { + throw new IllegalConfigurationException("Cannot create file " + file, e); + } + } + + protected void copyEntry(UUID entryId, ConfigurationEntryStore initialStore, Map<UUID,ConfigurationEntry> entries) + { + ConfigurationEntry entry = initialStore.getEntry(entryId); + if (entry != null) + { + if (entries.containsKey(entryId)) + { + throw new IllegalConfigurationException("Duplicate id is found: " + entryId + + "! The following configuration entries have the same id: " + entries.get(entryId) + ", " + entry); + } + entries.put(entryId, entry); + Set<UUID> children = entry.getChildrenIds(); + if (children != null) + { + for (UUID uuid : children) + { + copyEntry(uuid, initialStore, entries); + } + } + } + } + + protected URL fileToURL(File storeFile) + { + URL storeURL = null; + try + { + storeURL = storeFile.toURI().toURL(); + } + catch (MalformedURLException e) + { + throw new IllegalConfigurationException("Cannot create URL for file " + storeFile, e); + } + return storeURL; + } + + private void loadFromJson(String json) + { + ByteArrayInputStream bais = null; + try + { + byte[] bytes = json.getBytes("UTF-8"); + bais = new ByteArrayInputStream(bytes); + JsonNode node = loadJsonNodes(bais, _objectMapper); + ConfigurationEntry brokerEntry = toEntry(node, Broker.class, _entries); + _rootId = brokerEntry.getId(); + } + catch(Exception e) + { + throw new IllegalConfigurationException("Cannot create store from json:" + json); + } + finally + { + if (bais != null) + { + try + { + bais.close(); + } + catch (IOException e) + { + // ByteArrayInputStream#close() is an empty method + } + } + } + } + + private void createRootEntry() + { + ConfigurationEntry brokerEntry = new ConfigurationEntry(UUIDGenerator.generateRandomUUID(), + Broker.class.getSimpleName(), Collections.<String, Object> emptyMap(), Collections.<UUID> emptySet(), this); + _rootId = brokerEntry.getId(); + _entries.put(_rootId, brokerEntry); + } + + private Map<String, Object> toTree(UUID rootId, Map<UUID, ConfigurationEntry> entries) + { + ConfigurationEntry entry = entries.get(rootId); + if (entry == null || !entry.getId().equals(rootId)) + { + throw new IllegalConfigurationException("Cannot find entry with id " + rootId + "!"); + } + Map<String, Object> tree = new TreeMap<String, Object>(); + Map<String, Object> attributes = entry.getAttributes(); + if (attributes != null) + { + tree.putAll(attributes); + } + tree.put(ID, entry.getId()); + Set<UUID> childrenIds = entry.getChildrenIds(); + if (childrenIds != null && !childrenIds.isEmpty()) + { + for (UUID relationship : childrenIds) + { + ConfigurationEntry child = entries.get(relationship); + if (child != null) + { + String relationshipName = child.getType().toLowerCase() + "s"; + + @SuppressWarnings("unchecked") + Collection<Map<String, Object>> children = (Collection<Map<String, Object>>) tree.get(relationshipName); + if (children == null) + { + children = new ArrayList<Map<String, Object>>(); + tree.put(relationshipName, children); + } + Map<String, Object> childAsMap = toTree(relationship, entries); + children.add(childAsMap); + } + } + } + return tree; + } + + private Map<String, Class<? extends ConfiguredObject>> buildRelationshipClassMap() + { + Map<String, Class<? extends ConfiguredObject>> relationships = new HashMap<String, Class<? extends ConfiguredObject>>(); + + Collection<Class<? extends ConfiguredObject>> children = Model.getInstance().getChildTypes(Broker.class); + for (Class<? extends ConfiguredObject> childClass : children) + { + String name = childClass.getSimpleName().toLowerCase(); + String relationshipName = name + (name.endsWith("s") ? "es" : "s"); + relationships.put(relationshipName, childClass); + } + return relationships; + } + + private boolean removeInternal(UUID entryId) + { + ConfigurationEntry oldEntry = _entries.remove(entryId); + if (oldEntry != null) + { + Set<UUID> children = oldEntry.getChildrenIds(); + if (children != null && !children.isEmpty()) + { + for (UUID childId : children) + { + removeInternal(childId); + } + } + return true; + } + return false; + } + + private JsonNode loadJsonNodes(InputStream is, ObjectMapper mapper) + { + JsonNode root = null; + try + { + root = mapper.readTree(is); + } + catch (JsonProcessingException e) + { + throw new IllegalConfigurationException("Cannot parse json", e); + } + catch (IOException e) + { + throw new IllegalConfigurationException("Cannot read json", e); + } + return root; + } + + private ConfigurationEntry toEntry(JsonNode parent, Class<? extends ConfiguredObject> expectedConfiguredObjectClass, Map<UUID, ConfigurationEntry> entries) + { + Map<String, Object> attributes = null; + Set<UUID> childrenIds = new TreeSet<UUID>(); + Iterator<String> fieldNames = parent.getFieldNames(); + String type = null; + String idAsString = null; + while (fieldNames.hasNext()) + { + String fieldName = fieldNames.next(); + JsonNode fieldNode = parent.get(fieldName); + if (fieldName.equals(ID)) + { + idAsString = fieldNode.asText(); + } + else if (fieldName.equals(TYPE)) + { + type = fieldNode.asText(); + } + else if (fieldNode.isArray()) + { + // array containing either broker children or attribute values + Iterator<JsonNode> elements = fieldNode.getElements(); + List<Object> fieldValues = null; + while (elements.hasNext()) + { + JsonNode element = elements.next(); + if (element.isObject()) + { + Class<? extends ConfiguredObject> expectedChildConfiguredObjectClass = _relationshipClasses.get(fieldName); + // assuming it is a child node + ConfigurationEntry entry = toEntry(element, expectedChildConfiguredObjectClass, entries); + childrenIds.add(entry.getId()); + } + else + { + if (fieldValues == null) + { + fieldValues = new ArrayList<Object>(); + } + fieldValues.add(toObject(element)); + } + } + if (fieldValues != null) + { + Object[] array = fieldValues.toArray(new Object[fieldValues.size()]); + attributes.put(fieldName, array); + } + } + else if (fieldNode.isObject()) + { + // ignore, in-line objects are not supported yet + } + else + { + // primitive attribute + Object value = toObject(fieldNode); + if (attributes == null) + { + attributes = new HashMap<String, Object>(); + } + attributes.put(fieldName, value); + } + } + + if (type == null) + { + if (expectedConfiguredObjectClass == null) + { + throw new IllegalConfigurationException("Type attribute is not provided for configuration entry " + parent); + } + else + { + type = expectedConfiguredObjectClass.getSimpleName(); + } + } + String name = null; + if (attributes != null) + { + name = (String) attributes.get(ATTRIBUTE_NAME); + } + if ((name == null || "".equals(name))) + { + if (expectedConfiguredObjectClass == Broker.class) + { + name = DEFAULT_BROKER_NAME; + } + else + { + throw new IllegalConfigurationException("Name attribute is not provided for configuration entry " + parent); + } + } + UUID id = null; + if (idAsString == null) + { + if (expectedConfiguredObjectClass == Broker.class) + { + id = UUIDGenerator.generateRandomUUID(); + } + else + { + id = UUIDGenerator.generateBrokerChildUUID(type, name); + } + } + else + { + try + { + id = UUID.fromString(idAsString); + } + catch (Exception e) + { + throw new IllegalConfigurationException( + "ID attribute value does not conform to UUID format for configuration entry " + parent); + } + } + ConfigurationEntry entry = new ConfigurationEntry(id, type, attributes, childrenIds, this); + if (entries.containsKey(id)) + { + throw new IllegalConfigurationException("Duplicate id is found: " + id + + "! The following configuration entries have the same id: " + entries.get(id) + ", " + entry); + } + entries.put(id, entry); + return entry; + } + + private Object toObject(JsonNode node) + { + if (node.isValueNode()) + { + if (node.isBoolean()) + { + return node.asBoolean(); + } + else if (node.isDouble()) + { + return node.asDouble(); + } + else if (node.isInt()) + { + return node.asInt(); + } + else if (node.isLong()) + { + return node.asLong(); + } + else if (node.isNull()) + { + return null; + } + else + { + return Strings.expand(node.asText()); + } + } + else if (node.isArray()) + { + return toArray(node); + } + else if (node.isObject()) + { + return toMap(node); + } + else + { + throw new IllegalConfigurationException("Unexpected node: " + node); + } + } + + private Map<String, Object> toMap(JsonNode node) + { + Map<String, Object> object = new TreeMap<String, Object>(); + Iterator<String> fieldNames = node.getFieldNames(); + while (fieldNames.hasNext()) + { + String name = fieldNames.next(); + Object value = toObject(node.get(name)); + object.put(name, value); + } + return object; + } + + private Object toArray(JsonNode node) + { + ArrayNode arrayNode = (ArrayNode) node; + Object[] array = new Object[arrayNode.size()]; + Iterator<JsonNode> elements = arrayNode.getElements(); + for (int i = 0; i < array.length; i++) + { + array[i] = toObject(elements.next()); + } + return array; + } + +} diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/store/factory/JsonConfigurationStoreFactory.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/store/factory/JsonConfigurationStoreFactory.java index e37e58b840..1a0b514b4c 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/store/factory/JsonConfigurationStoreFactory.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/store/factory/JsonConfigurationStoreFactory.java @@ -21,15 +21,15 @@ package org.apache.qpid.server.configuration.store.factory; import org.apache.qpid.server.configuration.ConfigurationEntryStore; -import org.apache.qpid.server.configuration.ConfigurationStoreFactory; import org.apache.qpid.server.configuration.store.JsonConfigurationEntryStore; +import org.apache.qpid.server.plugin.ConfigurationStoreFactory; public class JsonConfigurationStoreFactory implements ConfigurationStoreFactory { @Override - public ConfigurationEntryStore createStore() + public ConfigurationEntryStore createStore(String storeLocation, ConfigurationEntryStore initialStore) { - return new JsonConfigurationEntryStore(); + return new JsonConfigurationEntryStore(storeLocation, initialStore); } @Override diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/store/factory/MemoryConfigurationStoreFactory.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/store/factory/MemoryConfigurationStoreFactory.java new file mode 100644 index 0000000000..fcd6c73170 --- /dev/null +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/store/factory/MemoryConfigurationStoreFactory.java @@ -0,0 +1,41 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.configuration.store.factory; + +import org.apache.qpid.server.configuration.ConfigurationEntryStore; +import org.apache.qpid.server.configuration.store.MemoryConfigurationEntryStore; +import org.apache.qpid.server.plugin.ConfigurationStoreFactory; + +public class MemoryConfigurationStoreFactory implements ConfigurationStoreFactory +{ + @Override + public ConfigurationEntryStore createStore(String storeLocation, ConfigurationEntryStore initialStore) + { + return new MemoryConfigurationEntryStore(null, initialStore); + } + + @Override + public String getStoreType() + { + return MemoryConfigurationEntryStore.STORE_TYPE; + } + +} diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfigurationStoreFactory.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/plugin/ConfigurationStoreFactory.java index dced38d260..a625579ece 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfigurationStoreFactory.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/plugin/ConfigurationStoreFactory.java @@ -18,7 +18,10 @@ * under the License. * */ -package org.apache.qpid.server.configuration; +package org.apache.qpid.server.plugin; + +import org.apache.qpid.server.configuration.ConfigurationEntryStore; +import org.apache.qpid.server.configuration.IllegalConfigurationException; public interface ConfigurationStoreFactory @@ -29,7 +32,13 @@ public interface ConfigurationStoreFactory public String getStoreType(); /** - * Creates the store instance. + * Creates and opens the store from a given location using initial store if provided. + * <p> + * If location does not exists than a new store is created either empty or from the initial store if it is provided + * + * @param storeLocation store location + * @param initialStore initial store + * @throws IllegalConfigurationException if store cannot be opened in the given location */ - public ConfigurationEntryStore createStore(); + public ConfigurationEntryStore createStore(String storeLocation, ConfigurationEntryStore initialStore); } diff --git a/qpid/java/broker/src/main/resources/META-INF/services/org.apache.qpid.server.configuration.ConfigurationStoreFactory b/qpid/java/broker/src/main/resources/META-INF/services/org.apache.qpid.server.plugin.ConfigurationStoreFactory index 5f75a8c4c9..cd314abcae 100644 --- a/qpid/java/broker/src/main/resources/META-INF/services/org.apache.qpid.server.configuration.ConfigurationStoreFactory +++ b/qpid/java/broker/src/main/resources/META-INF/services/org.apache.qpid.server.plugin.ConfigurationStoreFactory @@ -17,3 +17,4 @@ # under the License. # org.apache.qpid.server.configuration.store.factory.JsonConfigurationStoreFactory +org.apache.qpid.server.configuration.store.factory.MemoryConfigurationStoreFactory diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/BrokerOptionsTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/BrokerOptionsTest.java index 9105f5b2e7..7a7df66c57 100644 --- a/qpid/java/broker/src/test/java/org/apache/qpid/server/BrokerOptionsTest.java +++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/BrokerOptionsTest.java @@ -106,28 +106,16 @@ public class BrokerOptionsTest extends QpidTestCase assertEquals(myFreq, _options.getLogWatchFrequency()); } - - public void testDefaultInitialConfigurationStoreType() - { - assertEquals("json", _options.getInitialConfigurationStoreType()); - } - - public void testOverriddenInitialConfigurationStoreType() - { - _options.setInitialConfigurationStoreType("dby"); - assertEquals("dby", _options.getInitialConfigurationStoreType()); - } - - public void testDefaultInitialConfigurationStoreLocation() + public void testDefaultInitialConfigurationLocation() { - assertNull(_options.getInitialConfigurationStoreLocation()); + assertEquals(BrokerOptions.DEFAULT_INITIAL_CONFIG_LOCATION, _options.getInitialConfigurationLocation()); } - public void testOverriddenInitialConfigurationStoreLocation() + public void testOverriddenInitialConfigurationLocation() { - final String testConfigFile = "etc/mytestconfig.xml"; - _options.setInitialConfigurationStoreLocation(testConfigFile); - assertEquals(testConfigFile, _options.getInitialConfigurationStoreLocation()); + final String testConfigFile = "etc/mytestconfig.json"; + _options.setInitialConfigurationLocation(testConfigFile); + assertEquals(testConfigFile, _options.getInitialConfigurationLocation()); } public void testDefaultManagementMode() diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/MainTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/MainTest.java index 6ca9a55d7b..46c63c9e34 100644 --- a/qpid/java/broker/src/test/java/org/apache/qpid/server/MainTest.java +++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/MainTest.java @@ -46,8 +46,7 @@ public class MainTest extends QpidTestCase assertEquals(expectedStorePath, options.getConfigurationStoreLocation()); assertEquals(null, options.getLogConfigFile()); assertEquals(0, options.getLogWatchFrequency()); - assertEquals("json", options.getInitialConfigurationStoreType()); - assertEquals(null, options.getInitialConfigurationStoreLocation()); + assertEquals(BrokerOptions.DEFAULT_INITIAL_CONFIG_LOCATION, options.getInitialConfigurationLocation()); assertFalse(options.isManagementMode()); assertEquals(0, options.getManagementModeConnectorPort()); @@ -103,23 +102,13 @@ public class MainTest extends QpidTestCase assertTrue("Parsed command line didnt pick up help option", main.getCommandLine().hasOption("h")); } - public void testInitailConfigurationStoreLocation() + public void testInitailConfigurationLocation() { - BrokerOptions options = startDummyMain("-isp abcd/config.xml"); - assertEquals("abcd/config.xml", options.getInitialConfigurationStoreLocation()); - - options = startDummyMain("-initial-store-path abcd/config.xml"); - assertEquals("abcd/config.xml", options.getInitialConfigurationStoreLocation()); - } - - public void testInitialConfigurationStoreType() - { - BrokerOptions options = startDummyMain("-ist dby"); - assertEquals("dby", options.getInitialConfigurationStoreType()); - - options = startDummyMain("-initial-store-type bdb"); - assertEquals("bdb", options.getInitialConfigurationStoreType()); + BrokerOptions options = startDummyMain("-icp abcd/initial-config.json"); + assertEquals("abcd/initial-config.json", options.getInitialConfigurationLocation()); + options = startDummyMain("-initial-config-path abcd/initial-config.json"); + assertEquals("abcd/initial-config.json", options.getInitialConfigurationLocation()); } public void testManagementMode() diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/BrokerConfigurationStoreCreatorTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/BrokerConfigurationStoreCreatorTest.java index afb7559d9d..d61117868f 100644 --- a/qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/BrokerConfigurationStoreCreatorTest.java +++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/BrokerConfigurationStoreCreatorTest.java @@ -27,6 +27,7 @@ import java.util.Map; import java.util.Set; import java.util.UUID; +import org.apache.qpid.server.BrokerOptions; import org.apache.qpid.server.configuration.store.JsonConfigurationEntryStore; import org.apache.qpid.server.model.Broker; import org.apache.qpid.test.utils.QpidTestCase; @@ -49,6 +50,7 @@ public class BrokerConfigurationStoreCreatorTest extends QpidTestCase { // set the properties in order to resolve the defaults store settings setTestSystemProperty("QPID_HOME", TMP_FOLDER); + setTestSystemProperty("QPID_WORK", TMP_FOLDER + File.separator + "work"); } _storeCreator = new BrokerConfigurationStoreCreator(); _userStoreLocation = new File(TMP_FOLDER, "_store_" + System.currentTimeMillis() + "_" + getTestName()); @@ -71,12 +73,11 @@ public class BrokerConfigurationStoreCreatorTest extends QpidTestCase public void testCreateJsonStore() { - ConfigurationEntryStore store = _storeCreator.createStore(_userStoreLocation.getAbsolutePath(), "json", null, null); + ConfigurationEntryStore store = _storeCreator.createStore(_userStoreLocation.getAbsolutePath(), "json", BrokerOptions.DEFAULT_INITIAL_CONFIG_LOCATION); assertNotNull("Store was not created", store); assertTrue("File should exists", _userStoreLocation.exists()); assertTrue("File size should be greater than 0", _userStoreLocation.length() > 0); - JsonConfigurationEntryStore jsonStore = new JsonConfigurationEntryStore(); - jsonStore.open(_userStoreLocation.getAbsolutePath()); + JsonConfigurationEntryStore jsonStore = new JsonConfigurationEntryStore(_userStoreLocation.getAbsolutePath(), null); Set<UUID> childrenIds = jsonStore.getRootEntry().getChildrenIds(); assertFalse("Unexpected children: " + childrenIds, childrenIds.isEmpty()); } @@ -98,12 +99,11 @@ public class BrokerConfigurationStoreCreatorTest extends QpidTestCase File _storeFile = TestFileUtils.createTempFile(this, ".json", brokerJson); - ConfigurationEntryStore store = _storeCreator.createStore(_userStoreLocation.getAbsolutePath(), "json", _storeFile.getAbsolutePath(), "json"); + ConfigurationEntryStore store = _storeCreator.createStore(_userStoreLocation.getAbsolutePath(), "json", _storeFile.getAbsolutePath()); assertNotNull("Store was not created", store); assertTrue("File should exists", _userStoreLocation.exists()); assertTrue("File size should be greater than 0", _userStoreLocation.length() > 0); - JsonConfigurationEntryStore jsonStore = new JsonConfigurationEntryStore(); - jsonStore.open(_userStoreLocation.getAbsolutePath()); + JsonConfigurationEntryStore jsonStore = new JsonConfigurationEntryStore(_userStoreLocation.getAbsolutePath(), null); ConfigurationEntry entry = jsonStore.getRootEntry(); assertEquals("Unexpected root id", brokerId, entry.getId()); Map<String, Object> attributes = entry.getAttributes(); @@ -118,7 +118,7 @@ public class BrokerConfigurationStoreCreatorTest extends QpidTestCase { try { - _storeCreator.createStore(_userStoreLocation.getAbsolutePath(), "derby", null, null); + _storeCreator.createStore(_userStoreLocation.getAbsolutePath(), "derby", null); fail("Store is not yet supported"); } catch(IllegalConfigurationException e) diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/store/JsonConfigurationEntryStoreTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/store/JsonConfigurationEntryStoreTest.java index 7c9f4889f8..92e304ab86 100644 --- a/qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/store/JsonConfigurationEntryStoreTest.java +++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/store/JsonConfigurationEntryStoreTest.java @@ -10,6 +10,7 @@ import java.util.UUID; 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.Broker; import org.apache.qpid.test.utils.TestFileUtils; import org.codehaus.jackson.JsonGenerationException; @@ -41,8 +42,7 @@ public class JsonConfigurationEntryStoreTest extends ConfigurationEntryStoreTest protected ConfigurationEntryStore createStore(UUID brokerId, Map<String, Object> brokerAttributes) throws Exception { _storeFile = createStoreFile(brokerId, brokerAttributes); - JsonConfigurationEntryStore store = new JsonConfigurationEntryStore(); - store.open(_storeFile.getAbsolutePath()); + JsonConfigurationEntryStore store = new JsonConfigurationEntryStore(_storeFile.getAbsolutePath(), null); return store; } @@ -82,84 +82,33 @@ public class JsonConfigurationEntryStoreTest extends ConfigurationEntryStoreTest attributes, brokerConfigEntry.getChildrenIds(), store); store.save(updatedBrokerEntry); - JsonConfigurationEntryStore store2 = new JsonConfigurationEntryStore(); - store2.open(_storeFile.getAbsolutePath()); + JsonConfigurationEntryStore store2 = new JsonConfigurationEntryStore(_storeFile.getAbsolutePath(), null); assertEquals("Unresolved ACL value", aclLocation, store2.getRootEntry().getAttributes().get(Broker.ACL_FILE)); } - public void testOpenEmpty() + public void testCreateEmptyStore() { File file = TestFileUtils.createTempFile(this, ".json"); - JsonConfigurationEntryStore store = new JsonConfigurationEntryStore(); - store.open(file.getAbsolutePath()); - ConfigurationEntry root = store.getRootEntry(); - assertNotNull("Root entry is not found", root); - store.copyTo(file.getAbsolutePath()); - - JsonConfigurationEntryStore store2 = new JsonConfigurationEntryStore(); - store2.open(file.getAbsolutePath()); - ConfigurationEntry root2 = store.getRootEntry(); - assertEquals("Unexpected root entry", root.getId(), root2.getId()); + try + { + new JsonConfigurationEntryStore(file.getAbsolutePath(), null); + fail("Cannot create a new store without initial store"); + } + catch(IllegalConfigurationException e) + { + // pass + } } - public void testOpenNotEmpty() throws Exception + public void testCreateFromExistingLocation() throws Exception { UUID brokerId = UUID.randomUUID(); Map<String, Object> brokerAttributes = new HashMap<String, Object>(); brokerAttributes.put(Broker.NAME, getTestName()); File file = createStoreFile(brokerId, brokerAttributes); - JsonConfigurationEntryStore store = new JsonConfigurationEntryStore(); - store.open(file.getAbsolutePath()); - ConfigurationEntry root = store.getRootEntry(); - assertNotNull("Root entry is not found", root); - assertEquals("Unexpected root entry", brokerId, root.getId()); - Map<String, Object> attributes = root.getAttributes(); - assertNotNull("Attributes not found", attributes); - assertEquals("Unexpected number of attriburtes", 1, attributes.size()); - assertEquals("Unexpected name attribute", getTestName(), attributes.get(Broker.NAME)); - } - - public void testOpenInMemoryEmpty() - { - JsonConfigurationEntryStore store = new JsonConfigurationEntryStore(); - store.open(JsonConfigurationEntryStore.IN_MEMORY); - - ConfigurationEntry root = store.getRootEntry(); - assertNotNull("Root entry is not found", root); - } - - public void testOpenWithInitialStoreLocation() throws Exception - { - UUID brokerId = UUID.randomUUID(); - Map<String, Object> brokerAttributes = new HashMap<String, Object>(); - brokerAttributes.put(Broker.NAME, getTestName()); - File initialStoreFile = createStoreFile(brokerId, brokerAttributes); - - File storeFile = TestFileUtils.createTempFile(this, ".json"); - JsonConfigurationEntryStore store = new JsonConfigurationEntryStore(); - store.open(storeFile.getAbsolutePath(), initialStoreFile.getAbsolutePath()); - - ConfigurationEntry root = store.getRootEntry(); - assertNotNull("Root entry is not found", root); - assertEquals("Unexpected root entry", brokerId, root.getId()); - Map<String, Object> attributes = root.getAttributes(); - assertNotNull("Attributes not found", attributes); - assertEquals("Unexpected number of attriburtes", 1, attributes.size()); - assertEquals("Unexpected name attribute", getTestName(), attributes.get(Broker.NAME)); - } - - public void testOpenInMemoryWithInitialStoreLocation() throws Exception - { - UUID brokerId = UUID.randomUUID(); - Map<String, Object> brokerAttributes = new HashMap<String, Object>(); - brokerAttributes.put(Broker.NAME, getTestName()); - File initialStoreFile = createStoreFile(brokerId, brokerAttributes); - - JsonConfigurationEntryStore store = new JsonConfigurationEntryStore(); - store.open(JsonConfigurationEntryStore.IN_MEMORY, initialStoreFile.getAbsolutePath()); - + JsonConfigurationEntryStore store = new JsonConfigurationEntryStore(file.getAbsolutePath(), null); ConfigurationEntry root = store.getRootEntry(); assertNotNull("Root entry is not found", root); assertEquals("Unexpected root entry", brokerId, root.getId()); @@ -169,19 +118,17 @@ public class JsonConfigurationEntryStoreTest extends ConfigurationEntryStoreTest assertEquals("Unexpected name attribute", getTestName(), attributes.get(Broker.NAME)); } - public void testOpenWithInitialStore() throws Exception + public void testCreateFromInitialStore() throws Exception { UUID brokerId = UUID.randomUUID(); Map<String, Object> brokerAttributes = new HashMap<String, Object>(); brokerAttributes.put(Broker.NAME, getTestName()); File initialStoreFile = createStoreFile(brokerId, brokerAttributes); - JsonConfigurationEntryStore initialStore = new JsonConfigurationEntryStore(); - initialStore.open(initialStoreFile.getAbsolutePath()); + JsonConfigurationEntryStore initialStore = new JsonConfigurationEntryStore(initialStoreFile.getAbsolutePath(), null); File storeFile = TestFileUtils.createTempFile(this, ".json"); - JsonConfigurationEntryStore store = new JsonConfigurationEntryStore(); - store.open(storeFile.getAbsolutePath(), initialStore); + JsonConfigurationEntryStore store = new JsonConfigurationEntryStore(storeFile.getAbsolutePath(), initialStore); ConfigurationEntry root = store.getRootEntry(); assertNotNull("Root entry is not found", root); @@ -192,25 +139,4 @@ public class JsonConfigurationEntryStoreTest extends ConfigurationEntryStoreTest assertEquals("Unexpected name attribute", getTestName(), attributes.get(Broker.NAME)); } - public void testOpenInMemoryWithInitialStore() throws Exception - { - UUID brokerId = UUID.randomUUID(); - Map<String, Object> brokerAttributes = new HashMap<String, Object>(); - brokerAttributes.put(Broker.NAME, getTestName()); - File initialStoreFile = createStoreFile(brokerId, brokerAttributes); - - JsonConfigurationEntryStore initialStore = new JsonConfigurationEntryStore(); - initialStore.open(initialStoreFile.getAbsolutePath()); - - JsonConfigurationEntryStore store = new JsonConfigurationEntryStore(); - store.open(JsonConfigurationEntryStore.IN_MEMORY, initialStore); - - ConfigurationEntry root = store.getRootEntry(); - assertNotNull("Root entry is not found", root); - assertEquals("Unexpected root entry", brokerId, root.getId()); - Map<String, Object> attributes = root.getAttributes(); - assertNotNull("Attributes not found", attributes); - assertEquals("Unexpected number of attriburtes", 1, attributes.size()); - assertEquals("Unexpected name attribute", getTestName(), attributes.get(Broker.NAME)); - } } diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/store/ManagementModeStoreHandlerTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/store/ManagementModeStoreHandlerTest.java index a67daac610..52e021240e 100644 --- a/qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/store/ManagementModeStoreHandlerTest.java +++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/store/ManagementModeStoreHandlerTest.java @@ -5,7 +5,6 @@ import static org.mockito.Mockito.when; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.any; -import java.io.File; import java.util.Arrays; import java.util.Collection; import java.util.Collections; @@ -15,7 +14,6 @@ import java.util.Map; import java.util.UUID; import org.apache.qpid.server.BrokerOptions; -import org.apache.qpid.server.configuration.BrokerConfigurationStoreCreator; import org.apache.qpid.server.configuration.ConfigurationEntry; import org.apache.qpid.server.configuration.ConfigurationEntryStore; import org.apache.qpid.server.configuration.IllegalConfigurationException; @@ -54,46 +52,6 @@ public class ManagementModeStoreHandlerTest extends QpidTestCase _handler = new ManagementModeStoreHandler(_store, _options); } - public void testOpenString() - { - try - { - _handler.open(TMP_FOLDER + File.separator + getTestName()); - fail("Exception should be thrown on attempt to call open method on a handler"); - } - catch (IllegalStateException e) - { - // pass - } - } - - public void testOpenStringString() - { - try - { - _handler.open(TMP_FOLDER + File.separator + getTestName(), - BrokerConfigurationStoreCreator.DEFAULT_INITIAL_STORE_LOCATION); - fail("Exception should be thrown on attempt to call open method on a handler"); - } - catch (IllegalStateException e) - { - // pass - } - } - - public void testOpenStringConfigurationEntryStore() - { - try - { - _handler.open(TMP_FOLDER + File.separator + getTestName(), _store); - fail("Exception should be thrown on attempt to call open method on a handler"); - } - catch (IllegalStateException e) - { - // pass - } - } - public void testGetRootEntryWithEmptyOptions() { ConfigurationEntry root = _handler.getRootEntry(); diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/store/MemoryConfigurationEntryStoreTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/store/MemoryConfigurationEntryStoreTest.java new file mode 100644 index 0000000000..65ced69915 --- /dev/null +++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/store/MemoryConfigurationEntryStoreTest.java @@ -0,0 +1,97 @@ +package org.apache.qpid.server.configuration.store; + +import java.io.File; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +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.Broker; +import org.codehaus.jackson.map.ObjectMapper; + +public class MemoryConfigurationEntryStoreTest extends ConfigurationEntryStoreTestCase +{ + + @Override + protected ConfigurationEntryStore createStore(UUID brokerId, Map<String, Object> brokerAttributes) throws Exception + { + Map<String, Object> broker = new HashMap<String, Object>(); + broker.put(Broker.ID, brokerId); + broker.putAll(brokerAttributes); + ObjectMapper mapper = new ObjectMapper(); + + return new MemoryConfigurationEntryStore(mapper.writeValueAsString(broker)); + } + + @Override + protected void addConfiguration(UUID id, String type, Map<String, Object> attributes) + { + ConfigurationEntryStore store = getStore(); + store.save(new ConfigurationEntry(id, type, attributes, Collections.<UUID> emptySet(), store)); + } + + public void testCreateWithNullLocationAndNullInitialStore() + { + try + { + new MemoryConfigurationEntryStore(null, null); + fail("Cannot create a memory store without either initial store or path to an initial store file"); + } + catch(IllegalConfigurationException e) + { + // pass + } + } + + public void testCreateWithNullJson() + { + MemoryConfigurationEntryStore store = new MemoryConfigurationEntryStore(null); + + ConfigurationEntry root = store.getRootEntry(); + assertNotNull("Root entry is not found", root); + } + + public void testOpenInMemoryWithInitialStore() throws Exception + { + UUID brokerId = UUID.randomUUID(); + Map<String, Object> brokerAttributes = new HashMap<String, Object>(); + brokerAttributes.put(Broker.NAME, getTestName()); + MemoryConfigurationEntryStore initialStoreFile = (MemoryConfigurationEntryStore)createStore(brokerId, brokerAttributes); + MemoryConfigurationEntryStore store = new MemoryConfigurationEntryStore(null, initialStoreFile); + + ConfigurationEntry root = store.getRootEntry(); + assertNotNull("Root entry is not found", root); + assertEquals("Unexpected root entry", brokerId, root.getId()); + Map<String, Object> attributes = root.getAttributes(); + assertNotNull("Attributes not found", attributes); + assertEquals("Unexpected number of attriburtes", 1, attributes.size()); + assertEquals("Unexpected name attribute", getTestName(), attributes.get(Broker.NAME)); + } + + + public void testOpenWithDefaultInitialStore() throws Exception + { + // check whether QPID_HOME JVM system property is set + if (QPID_HOME == null) + { + // set the properties in order to resolve the defaults store settings + setTestSystemProperty("QPID_HOME", TMP_FOLDER); + setTestSystemProperty("QPID_WORK", TMP_FOLDER + File.separator + "work"); + } + MemoryConfigurationEntryStore initialStore = new MemoryConfigurationEntryStore(BrokerOptions.DEFAULT_INITIAL_CONFIG_LOCATION, null); + ConfigurationEntry initialStoreRoot = initialStore.getRootEntry(); + assertNotNull("Initial store root entry is not found", initialStoreRoot); + + MemoryConfigurationEntryStore store = new MemoryConfigurationEntryStore(null, initialStore); + + ConfigurationEntry root = store.getRootEntry(); + assertNotNull("Root entry is not found", root); + + assertEquals("Unexpected broker attributes", initialStoreRoot.getAttributes(), root.getAttributes()); + assertEquals("Unexpected broker children", initialStoreRoot.getChildrenIds(), root.getChildrenIds()); + } +} diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/test/utils/TestBrokerConfiguration.java b/qpid/java/systests/src/main/java/org/apache/qpid/test/utils/TestBrokerConfiguration.java index 80f8010678..db10bfb7e7 100644 --- a/qpid/java/systests/src/main/java/org/apache/qpid/test/utils/TestBrokerConfiguration.java +++ b/qpid/java/systests/src/main/java/org/apache/qpid/test/utils/TestBrokerConfiguration.java @@ -29,7 +29,7 @@ import java.util.Set; import java.util.UUID; import org.apache.qpid.server.configuration.ConfigurationEntry; -import org.apache.qpid.server.configuration.store.JsonConfigurationEntryStore; +import org.apache.qpid.server.configuration.store.MemoryConfigurationEntryStore; import org.apache.qpid.server.model.AuthenticationProvider; import org.apache.qpid.server.model.Plugin; import org.apache.qpid.server.model.Port; @@ -53,14 +53,13 @@ public class TestBrokerConfiguration public static final String MANAGEMENT_JMX_PLUGIN_TYPE = "MANAGEMENT-JMX"; public static final String ENTRY_NAME_ANONYMOUS_PROVIDER = "anonymous"; - private JsonConfigurationEntryStore _store; + private MemoryConfigurationEntryStore _store; private boolean _saved; public TestBrokerConfiguration(String storeType, String intialStoreLocation) { // TODO: add support for DERBY store - _store = new JsonConfigurationEntryStore(); - _store.open(JsonConfigurationEntryStore.IN_MEMORY, intialStoreLocation); + _store = new MemoryConfigurationEntryStore(intialStoreLocation, null); } public boolean setBrokerAttribute(String name, Object value) |