diff options
Diffstat (limited to 'java')
29 files changed, 638 insertions, 348 deletions
diff --git a/java/bdbstore/jmx/src/main/java/org/apache/qpid/server/store/berkeleydb/jmx/BDBHAMessageStoreManagerMBeanProvider.java b/java/bdbstore/jmx/src/main/java/org/apache/qpid/server/store/berkeleydb/jmx/BDBHAMessageStoreManagerMBeanProvider.java index fb61df68b7..45e0c39274 100644 --- a/java/bdbstore/jmx/src/main/java/org/apache/qpid/server/store/berkeleydb/jmx/BDBHAMessageStoreManagerMBeanProvider.java +++ b/java/bdbstore/jmx/src/main/java/org/apache/qpid/server/store/berkeleydb/jmx/BDBHAMessageStoreManagerMBeanProvider.java @@ -31,8 +31,7 @@ import org.apache.qpid.server.store.berkeleydb.replication.ReplicatedEnvironment import org.apache.qpid.server.virtualhostnode.berkeleydb.BDBHAVirtualHostNode; /** - * This provide will create a {@link BDBHAMessageStoreManagerMBean} if the child is a virtual - * host and of type {@link ReplicatedEnvironmentFacade#TYPE}. + * This provide will create a {@link BDBHAMessageStoreManagerMBean} if the child is a BDBHAVirtualHostNode. * */ public class BDBHAMessageStoreManagerMBeanProvider implements MBeanProvider diff --git a/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/BDBConfigurationStore.java b/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/BDBConfigurationStore.java index be1c7c140e..37792cdd43 100644 --- a/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/BDBConfigurationStore.java +++ b/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/BDBConfigurationStore.java @@ -131,7 +131,7 @@ public class BDBConfigurationStore implements MessageStoreProvider, DurableConfi if (_environmentFacade == null) { - _environmentFacade = _environmentFacadeFactory.createEnvironmentFacade(storeSettings); + _environmentFacade = _environmentFacadeFactory.createEnvironmentFacade(parent, storeSettings); _storeLocation = _environmentFacade.getStoreLocation(); } else @@ -617,8 +617,7 @@ public class BDBConfigurationStore implements MessageStoreProvider, DurableConfi if (_environmentFacade == null) { - _environmentFacade = _environmentFacadeFactory.createEnvironmentFacade(messageStoreSettings - ); + _environmentFacade = _environmentFacadeFactory.createEnvironmentFacade(parent, messageStoreSettings); _storeLocation = _environmentFacade.getStoreLocation(); } } diff --git a/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/EnvironmentFacadeFactory.java b/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/EnvironmentFacadeFactory.java index e13ad0e452..3a4ace2238 100644 --- a/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/EnvironmentFacadeFactory.java +++ b/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/EnvironmentFacadeFactory.java @@ -22,11 +22,11 @@ package org.apache.qpid.server.store.berkeleydb; import java.util.Map; +import org.apache.qpid.server.model.ConfiguredObject; + public interface EnvironmentFacadeFactory { - public static final String ENVIRONMENT_CONFIGURATION = "environmentConfiguration"; - - EnvironmentFacade createEnvironmentFacade(Map<String, Object> storeSettings); + EnvironmentFacade createEnvironmentFacade(final ConfiguredObject<?> parent, + Map<String, Object> storeSettings); - String getType(); } diff --git a/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/StandardEnvironmentConfiguration.java b/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/StandardEnvironmentConfiguration.java new file mode 100644 index 0000000000..02ee53a53a --- /dev/null +++ b/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/StandardEnvironmentConfiguration.java @@ -0,0 +1,29 @@ +/* + * 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.store.berkeleydb; + +import java.util.Map; + +public interface StandardEnvironmentConfiguration +{ + String getName(); + String getStorePath(); + Map<String, String> getParameters(); +} diff --git a/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/StandardEnvironmentFacade.java b/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/StandardEnvironmentFacade.java index f2690a5aa1..6a377babdf 100644 --- a/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/StandardEnvironmentFacade.java +++ b/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/StandardEnvironmentFacade.java @@ -21,6 +21,7 @@ package org.apache.qpid.server.store.berkeleydb; import java.io.File; +import java.util.HashMap; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @@ -42,7 +43,6 @@ import com.sleepycat.je.Transaction; public class StandardEnvironmentFacade implements EnvironmentFacade { private static final Logger LOGGER = Logger.getLogger(StandardEnvironmentFacade.class); - public static final String TYPE = "BDB"; private final String _storePath; private final ConcurrentHashMap<String, Database> _cachedDatabases = new ConcurrentHashMap<>(); @@ -51,17 +51,16 @@ public class StandardEnvironmentFacade implements EnvironmentFacade private Environment _environment; private final Committer _committer; - public StandardEnvironmentFacade(String storePath, - Map<String, String> attributes) + public StandardEnvironmentFacade(StandardEnvironmentConfiguration configuration) { - _storePath = storePath; + _storePath = configuration.getStorePath(); if (LOGGER.isInfoEnabled()) { LOGGER.info("Creating environment at environment path " + _storePath); } - File environmentPath = new File(storePath); + File environmentPath = new File(_storePath); if (!environmentPath.exists()) { if (!environmentPath.mkdirs()) @@ -71,14 +70,24 @@ public class StandardEnvironmentFacade implements EnvironmentFacade } } - String name = (String)attributes.get(ConfiguredObject.NAME); + String name = configuration.getName(); EnvironmentConfig envConfig = new EnvironmentConfig(); envConfig.setAllowCreate(true); envConfig.setTransactional(true); - for (Map.Entry<String, String> configItem : attributes.entrySet()) + Map<String, String> params = new HashMap<>(EnvironmentFacade.ENVCONFIG_DEFAULTS); + params.putAll(configuration.getParameters()); + + for (Map.Entry<String, String> configItem : params.entrySet()) { - LOGGER.debug("Setting EnvironmentConfig key " + configItem.getKey() + " to '" + configItem.getValue() + "'"); + if (LOGGER.isDebugEnabled()) + { + LOGGER.debug("Setting EnvironmentConfig key " + + configItem.getKey() + + " to '" + + configItem.getValue() + + "'"); + } envConfig.setConfigParam(configItem.getKey(), configItem.getValue()); } diff --git a/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/StandardEnvironmentFacadeFactory.java b/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/StandardEnvironmentFacadeFactory.java index 49db913d6c..9c760d12e3 100644 --- a/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/StandardEnvironmentFacadeFactory.java +++ b/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/StandardEnvironmentFacadeFactory.java @@ -20,9 +20,14 @@ */ package org.apache.qpid.server.store.berkeleydb; +import java.util.Collections; import java.util.HashMap; import java.util.Map; +import com.sleepycat.je.config.ConfigParam; +import com.sleepycat.je.config.EnvironmentParams; + +import org.apache.qpid.server.model.ConfiguredObject; import org.apache.qpid.server.store.MessageStore; public class StandardEnvironmentFacadeFactory implements EnvironmentFacadeFactory @@ -30,24 +35,49 @@ public class StandardEnvironmentFacadeFactory implements EnvironmentFacadeFactor @SuppressWarnings("unchecked") @Override - public EnvironmentFacade createEnvironmentFacade(Map<String, Object> messageStoreSettings) + public EnvironmentFacade createEnvironmentFacade(final ConfiguredObject<?> parent, + final Map<String, Object> messageStoreSettings) { - Map<String, String> envConfigMap = new HashMap<String, String>(); - envConfigMap.putAll(EnvironmentFacade.ENVCONFIG_DEFAULTS); + final String storeLocation = (String) messageStoreSettings.get(MessageStore.STORE_PATH); - Object environmentConfigurationAttributes = messageStoreSettings.get(ENVIRONMENT_CONFIGURATION); - if (environmentConfigurationAttributes instanceof Map) + StandardEnvironmentConfiguration sec = new StandardEnvironmentConfiguration() { - envConfigMap.putAll((Map<String, String>) environmentConfigurationAttributes); - } - String storeLocation = (String) messageStoreSettings.get(MessageStore.STORE_PATH); - return new StandardEnvironmentFacade(storeLocation, envConfigMap); + @Override + public String getName() + { + return parent.getName(); + } + + @Override + public String getStorePath() + { + return storeLocation; + } + + @Override + public Map<String, String> getParameters() + { + return buildEnvironmentConfiguration(parent); + } + }; + + return new StandardEnvironmentFacade(sec); } - @Override - public String getType() + private Map<String, String> buildEnvironmentConfiguration(ConfiguredObject<?> parent) { - return StandardEnvironmentFacade.TYPE; - } + final Map<String, String> context = parent.getContext(); + Map<String, String> envConfigMap = new HashMap<>(); + for (ConfigParam cp : EnvironmentParams.SUPPORTED_PARAMS.values()) + { + final String parameterName = cp.getName(); + if (context.containsKey(parameterName) && !cp.isForReplication()) + { + String contextValue = context.get(parameterName); + envConfigMap.put(parameterName, contextValue); + } + } + return Collections.unmodifiableMap(envConfigMap); + } } diff --git a/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/replication/ReplicatedEnvironmentConfiguration.java b/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/replication/ReplicatedEnvironmentConfiguration.java index 1fc37db902..90fb086dc5 100644 --- a/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/replication/ReplicatedEnvironmentConfiguration.java +++ b/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/replication/ReplicatedEnvironmentConfiguration.java @@ -23,16 +23,15 @@ package org.apache.qpid.server.store.berkeleydb.replication; import java.util.Map; -public interface ReplicatedEnvironmentConfiguration +import org.apache.qpid.server.store.berkeleydb.StandardEnvironmentConfiguration; + +public interface ReplicatedEnvironmentConfiguration extends StandardEnvironmentConfiguration { - String getName(); String getGroupName(); String getHostPort(); String getHelperHostPort(); boolean isDesignatedPrimary(); int getPriority(); int getQuorumOverride(); - String getStorePath(); - Map<String, String> getParameters(); Map<String, String> getReplicationParameters(); } diff --git a/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/replication/ReplicatedEnvironmentFacade.java b/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/replication/ReplicatedEnvironmentFacade.java index 2d411724a6..f8c08dec04 100644 --- a/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/replication/ReplicatedEnvironmentFacade.java +++ b/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/replication/ReplicatedEnvironmentFacade.java @@ -906,8 +906,6 @@ public class ReplicatedEnvironmentFacade implements EnvironmentFacade, StateChan String groupName = _configuration.getGroupName(); String helperHostPort = _configuration.getHelperHostPort(); String hostPort = _configuration.getHostPort(); - Map<String, String> environmentParameters = _configuration.getParameters(); - Map<String, String> replicationEnvironmentParameters = _configuration.getReplicationParameters(); boolean designatedPrimary = _configuration.isDesignatedPrimary(); int priority = _configuration.getPriority(); int quorumOverride = _configuration.getQuorumOverride(); @@ -926,16 +924,8 @@ public class ReplicatedEnvironmentFacade implements EnvironmentFacade, StateChan LOGGER.info("Quorum override " + quorumOverride); } - Map<String, String> replicationEnvironmentSettings = new HashMap<String, String>(REPCONFIG_DEFAULTS); - if (replicationEnvironmentParameters != null && !replicationEnvironmentParameters.isEmpty()) - { - replicationEnvironmentSettings.putAll(replicationEnvironmentParameters); - } - Map<String, String> environmentSettings = new HashMap<String, String>(EnvironmentFacade.ENVCONFIG_DEFAULTS); - if (environmentParameters != null && !environmentParameters.isEmpty()) - { - environmentSettings.putAll(environmentParameters); - } + Map<String, String> replicationEnvironmentParameters = new HashMap<>(ReplicatedEnvironmentFacade.REPCONFIG_DEFAULTS); + replicationEnvironmentParameters.putAll(_configuration.getReplicationParameters()); ReplicationConfig replicationConfig = new ReplicationConfig(groupName, _configuration.getName(), hostPort); replicationConfig.setHelperHosts(helperHostPort); @@ -943,7 +933,7 @@ public class ReplicatedEnvironmentFacade implements EnvironmentFacade, StateChan replicationConfig.setNodePriority(priority); replicationConfig.setElectableGroupSizeOverride(quorumOverride); - for (Map.Entry<String, String> configItem : replicationEnvironmentSettings.entrySet()) + for (Map.Entry<String, String> configItem : replicationEnvironmentParameters.entrySet()) { if (LOGGER.isInfoEnabled()) { @@ -952,13 +942,16 @@ public class ReplicatedEnvironmentFacade implements EnvironmentFacade, StateChan replicationConfig.setConfigParam(configItem.getKey(), configItem.getValue()); } + Map<String, String> environmentParameters = new HashMap<>(EnvironmentFacade.ENVCONFIG_DEFAULTS); + environmentParameters.putAll(_configuration.getParameters()); + EnvironmentConfig envConfig = new EnvironmentConfig(); envConfig.setAllowCreate(true); envConfig.setTransactional(true); envConfig.setExceptionListener(new LoggingAsyncExceptionListener()); envConfig.setDurability(_defaultDurability); - for (Map.Entry<String, String> configItem : environmentSettings.entrySet()) + for (Map.Entry<String, String> configItem : environmentParameters.entrySet()) { if (LOGGER.isInfoEnabled()) { diff --git a/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/replication/ReplicatedEnvironmentFacadeFactory.java b/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/replication/ReplicatedEnvironmentFacadeFactory.java index c08318a657..6bab0db62b 100644 --- a/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/replication/ReplicatedEnvironmentFacadeFactory.java +++ b/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/replication/ReplicatedEnvironmentFacadeFactory.java @@ -20,8 +20,14 @@ */ package org.apache.qpid.server.store.berkeleydb.replication; +import java.util.Collections; +import java.util.HashMap; import java.util.Map; +import com.sleepycat.je.config.ConfigParam; +import com.sleepycat.je.config.EnvironmentParams; + +import org.apache.qpid.server.model.ConfiguredObject; import org.apache.qpid.server.store.berkeleydb.EnvironmentFacade; import org.apache.qpid.server.store.berkeleydb.EnvironmentFacadeFactory; import org.apache.qpid.server.virtualhostnode.berkeleydb.BDBHAVirtualHostNode; @@ -29,7 +35,7 @@ import org.apache.qpid.server.virtualhostnode.berkeleydb.BDBHAVirtualHostNode; public class ReplicatedEnvironmentFacadeFactory implements EnvironmentFacadeFactory { @Override - public EnvironmentFacade createEnvironmentFacade(final Map<String, Object> messageStoreSettings) + public EnvironmentFacade createEnvironmentFacade(final ConfiguredObject<?> parent, final Map<String, Object> messageStoreSettings) { ReplicatedEnvironmentConfiguration configuration = new ReplicatedEnvironmentConfiguration() { @@ -45,18 +51,16 @@ public class ReplicatedEnvironmentFacadeFactory implements EnvironmentFacadeFact return (String) messageStoreSettings.get(BDBHAVirtualHostNode.STORE_PATH); } - @SuppressWarnings("unchecked") @Override public Map<String, String> getParameters() { - return (Map<String, String>) messageStoreSettings.get(BDBHAVirtualHostNode.ENVIRONMENT_CONFIGURATION); + return buildEnvironmentConfigParameters(parent); } - @SuppressWarnings("unchecked") @Override public Map<String, String> getReplicationParameters() { - return (Map<String, String>) messageStoreSettings.get(BDBHAVirtualHostNode.REPLICATED_ENVIRONMENT_CONFIGURATION); + return buildReplicationConfigParameters(parent); } @Override @@ -99,10 +103,31 @@ public class ReplicatedEnvironmentFacadeFactory implements EnvironmentFacadeFact } - @Override - public String getType() + private Map<String, String> buildEnvironmentConfigParameters(ConfiguredObject<?> parent) { - return ReplicatedEnvironmentFacade.TYPE; + return buildConfig(parent, false); } + private Map<String, String> buildReplicationConfigParameters(ConfiguredObject<?> parent) + { + + return buildConfig(parent, true); + } + + private Map<String, String> buildConfig(ConfiguredObject<?> parent, boolean selectReplicationParaemeters) + { + Map<String, String> targetMap = new HashMap<>(); + for (ConfigParam entry : EnvironmentParams.SUPPORTED_PARAMS.values()) + { + final String name = entry.getName(); + if (entry.isForReplication() == selectReplicationParaemeters && parent.getContext().containsKey(name)) + { + String contextValue = parent.getContext().get(name); + targetMap.put(name, contextValue); + } + } + return Collections.unmodifiableMap(targetMap); + } + + } diff --git a/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNodeImpl.java b/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNodeImpl.java index 2eeedd63a1..90737a9385 100644 --- a/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNodeImpl.java +++ b/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNodeImpl.java @@ -65,10 +65,12 @@ import org.apache.qpid.server.store.berkeleydb.replication.ReplicationGroupListe import org.apache.qpid.server.util.ServerScopedRuntimeException; import org.apache.qpid.server.virtualhostnode.AbstractVirtualHostNode; -@ManagedObject( category = false, type = "BDB_HA" ) +@ManagedObject( category = false, type = BDBHAVirtualHostNodeImpl.VIRTUAL_HOST_NODE_TYPE ) public class BDBHAVirtualHostNodeImpl extends AbstractVirtualHostNode<BDBHAVirtualHostNodeImpl> implements BDBHAVirtualHostNode<BDBHAVirtualHostNodeImpl> { + public static final String VIRTUAL_HOST_NODE_TYPE = "BDB_HA"; + /** * Length of time we synchronously await the a JE mutation to complete. It is not considered an error if we exceed this timeout, although a * a warning will be logged. @@ -82,9 +84,6 @@ public class BDBHAVirtualHostNodeImpl extends AbstractVirtualHostNode<BDBHAVirtu private final AtomicReference<ReplicatedEnvironment.State> _lastReplicatedEnvironmentState = new AtomicReference<>(ReplicatedEnvironment.State.UNKNOWN); @ManagedAttributeField - private Map<String, String> _environmentConfiguration; - - @ManagedAttributeField private String _storePath; @ManagedAttributeField @@ -138,12 +137,6 @@ public class BDBHAVirtualHostNodeImpl extends AbstractVirtualHostNode<BDBHAVirtu } @Override - public Map<String, String> getEnvironmentConfiguration() - { - return _environmentConfiguration; - } - - @Override public String getStorePath() { return _storePath; diff --git a/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBVirtualHostNode.java b/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBVirtualHostNode.java index 91b2d7ae63..65a2fc1d30 100644 --- a/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBVirtualHostNode.java +++ b/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBVirtualHostNode.java @@ -27,8 +27,4 @@ import org.apache.qpid.server.virtualhostnode.FileBasedVirtualHostNode; public interface BDBVirtualHostNode<X extends BDBVirtualHostNode<X>> extends FileBasedVirtualHostNode<X> { - public static final String ENVIRONMENT_CONFIGURATION = "environmentConfiguration"; - - @ManagedAttribute(mandatory=false) - Map<String, String> getEnvironmentConfiguration(); } diff --git a/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBVirtualHostNodeImpl.java b/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBVirtualHostNodeImpl.java index 61c01c7003..d37c626b57 100644 --- a/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBVirtualHostNodeImpl.java +++ b/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBVirtualHostNodeImpl.java @@ -38,9 +38,6 @@ public class BDBVirtualHostNodeImpl extends AbstractStandardVirtualHostNode<BDBV @ManagedAttributeField private String _storePath; - @ManagedAttributeField - private Map<String, String> _environmentConfiguration; - @ManagedObjectFactoryConstructor public BDBVirtualHostNodeImpl(Map<String, Object> attributes, Broker<?> parent) { @@ -54,11 +51,6 @@ public class BDBVirtualHostNodeImpl extends AbstractStandardVirtualHostNode<BDBV } @Override - public Map<String, String> getEnvironmentConfiguration() - { - return _environmentConfiguration; - } - @Override public String getStorePath() { return _storePath; diff --git a/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/BDBHAVirtualHostNodeTest.java b/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/BDBHAVirtualHostNodeTest.java index a2ef422046..f9bdaeda93 100644 --- a/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/BDBHAVirtualHostNodeTest.java +++ b/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/BDBHAVirtualHostNodeTest.java @@ -56,6 +56,7 @@ import org.apache.qpid.server.virtualhost.berkeleydb.BDBHAVirtualHostImpl; import org.apache.qpid.server.virtualhostnode.berkeleydb.BDBHARemoteReplicationNode; import org.apache.qpid.server.virtualhostnode.berkeleydb.BDBHARemoteReplicationNodeImpl; import org.apache.qpid.server.virtualhostnode.berkeleydb.BDBHAVirtualHostNode; +import org.apache.qpid.server.virtualhostnode.berkeleydb.BDBHAVirtualHostNodeImpl; import org.apache.qpid.test.utils.QpidTestCase; import org.apache.qpid.util.FileUtils; @@ -132,14 +133,14 @@ public class BDBHAVirtualHostNodeTest extends QpidTestCase UUID id = UUID.randomUUID(); Map<String, Object> attributes = new HashMap<String, Object>(); - attributes.put(BDBHAVirtualHostNode.TYPE, "BDB_HA"); + attributes.put(BDBHAVirtualHostNode.TYPE, BDBHAVirtualHostNodeImpl.VIRTUAL_HOST_NODE_TYPE); attributes.put(BDBHAVirtualHostNode.ID, id); attributes.put(BDBHAVirtualHostNode.NAME, nodeName); attributes.put(BDBHAVirtualHostNode.GROUP_NAME, groupName); attributes.put(BDBHAVirtualHostNode.ADDRESS, nodeHostPort); attributes.put(BDBHAVirtualHostNode.HELPER_ADDRESS, helperHostPort); attributes.put(BDBHAVirtualHostNode.STORE_PATH, _bdbStorePath); - attributes.put(BDBHAVirtualHostNode.REPLICATED_ENVIRONMENT_CONFIGURATION, + attributes.put(BDBHAVirtualHostNode.CONTEXT, Collections.singletonMap(ReplicationConfig.REP_STREAM_TIMEOUT, repStreamTimeout)); BDBHAVirtualHostNode<?> node = createHaVHN(attributes); diff --git a/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/BDBMessageStoreQuotaEventsTest.java b/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/BDBMessageStoreQuotaEventsTest.java index 2afdaa4dd5..f445171005 100644 --- a/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/BDBMessageStoreQuotaEventsTest.java +++ b/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/BDBMessageStoreQuotaEventsTest.java @@ -66,12 +66,16 @@ public class BDBMessageStoreQuotaEventsTest extends MessageStoreQuotaEventsTestB messageStoreSettings.put(MessageStore.STORE_PATH, storeLocation); messageStoreSettings.put(MessageStore.OVERFULL_SIZE, OVERFULL_SIZE); messageStoreSettings.put(MessageStore.UNDERFULL_SIZE, UNDERFULL_SIZE); - Map<String,String> envMap = Collections.singletonMap("je.log.fileMax", MAX_BDB_LOG_SIZE); - messageStoreSettings.put(EnvironmentFacadeFactory.ENVIRONMENT_CONFIGURATION, envMap); return messageStoreSettings; } @Override + protected Map<String, String> createContextSettings() + { + return Collections.singletonMap("je.log.fileMax", MAX_BDB_LOG_SIZE); + } + + @Override protected MessageStore createStore() throws Exception { MessageStore store = (new BDBConfigurationStore()).getMessageStore(); diff --git a/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/StandardEnvironmentFacadeTest.java b/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/StandardEnvironmentFacadeTest.java index 5772498ebc..9521f7d85d 100644 --- a/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/StandardEnvironmentFacadeTest.java +++ b/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/StandardEnvironmentFacadeTest.java @@ -20,8 +20,12 @@ */ package org.apache.qpid.server.store.berkeleydb; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + import java.io.File; import java.util.Collections; +import java.util.Map; import org.apache.qpid.test.utils.QpidTestCase; import org.apache.qpid.util.FileUtils; @@ -29,6 +33,7 @@ import org.apache.qpid.util.FileUtils; import com.sleepycat.je.Database; import com.sleepycat.je.DatabaseConfig; import com.sleepycat.je.Environment; +import com.sleepycat.je.EnvironmentConfig; public class StandardEnvironmentFacadeTest extends QpidTestCase { @@ -62,7 +67,7 @@ public class StandardEnvironmentFacadeTest extends QpidTestCase public void testEnvironmentFacade() throws Exception { - EnvironmentFacade ef = getEnvironmentFacade(); + EnvironmentFacade ef = createEnvironmentFacade(); assertNotNull("Environment should not be null", ef); Environment e = ef.getEnvironment(); assertTrue("Environment is not valid", e.isValid()); @@ -70,18 +75,32 @@ public class StandardEnvironmentFacadeTest extends QpidTestCase public void testClose() throws Exception { - EnvironmentFacade ef = getEnvironmentFacade(); + EnvironmentFacade ef = createEnvironmentFacade(); ef.close(); Environment e = ef.getEnvironment(); assertNull("Environment should be null after facade close", e); } + public void testOverrideJeParameter() throws Exception + { + String statCollectVarName = EnvironmentConfig.STATS_COLLECT; + + EnvironmentFacade ef = createEnvironmentFacade(); + assertEquals("false", ef.getEnvironment().getMutableConfig().getConfigParam(statCollectVarName)); + ef.close(); + + ef = createEnvironmentFacade(Collections.singletonMap(statCollectVarName, "true")); + assertEquals("true", ef.getEnvironment().getMutableConfig().getConfigParam(statCollectVarName)); + ef.close(); + } + + public void testOpenDatabaseReusesCachedHandle() throws Exception { DatabaseConfig createIfAbsentDbConfig = DatabaseConfig.DEFAULT.setAllowCreate(true); - EnvironmentFacade ef = getEnvironmentFacade(); + EnvironmentFacade ef = createEnvironmentFacade(); Database handle1 = ef.openDatabase("myDatabase", createIfAbsentDbConfig); assertNotNull(handle1); @@ -94,18 +113,21 @@ public class StandardEnvironmentFacadeTest extends QpidTestCase assertNotSame("Expecting a new handle after database closure", handle1, handle3); } - EnvironmentFacade getEnvironmentFacade() throws Exception + EnvironmentFacade createEnvironmentFacade() { - if (_environmentFacade == null) - { - _environmentFacade = createEnvironmentFacade(); - } + _environmentFacade = createEnvironmentFacade(Collections.<String, String>emptyMap()); return _environmentFacade; + } - EnvironmentFacade createEnvironmentFacade() + EnvironmentFacade createEnvironmentFacade(Map<String, String> map) { - return new StandardEnvironmentFacade(_storePath.getAbsolutePath(), Collections.<String, String>emptyMap()); + StandardEnvironmentConfiguration sec = mock(StandardEnvironmentConfiguration.class); + when(sec.getName()).thenReturn(getTestName()); + when(sec.getParameters()).thenReturn(map); + when(sec.getStorePath()).thenReturn(_storePath.getAbsolutePath()); + + return new StandardEnvironmentFacade(sec); } } diff --git a/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/replication/ReplicatedEnvironmentFacadeTest.java b/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/replication/ReplicatedEnvironmentFacadeTest.java index 67364ada35..ec5098f369 100644 --- a/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/replication/ReplicatedEnvironmentFacadeTest.java +++ b/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/replication/ReplicatedEnvironmentFacadeTest.java @@ -252,7 +252,7 @@ public class ReplicatedEnvironmentFacadeTest extends QpidTestCase }; TestStateChangeListener stateChangeListener = new TestStateChangeListener(State.MASTER); - ReplicatedEnvironmentFacade replicatedEnvironmentFacade = addNode(State.MASTER, stateChangeListener, listener); + ReplicatedEnvironmentFacade replicatedEnvironmentFacade = addNode(stateChangeListener, listener); assertTrue("Master was not started", stateChangeListener.awaitForStateChange(LISTENER_TIMEOUT, TimeUnit.SECONDS)); assertEquals("Unexpected number of nodes at start of test", 1, replicatedEnvironmentFacade.getNumberOfElectableGroupMembers()); @@ -296,7 +296,7 @@ public class ReplicatedEnvironmentFacadeTest extends QpidTestCase }; TestStateChangeListener stateChangeListener = new TestStateChangeListener(State.MASTER); - ReplicatedEnvironmentFacade replicatedEnvironmentFacade = addNode(State.MASTER, stateChangeListener, listener); + ReplicatedEnvironmentFacade replicatedEnvironmentFacade = addNode(stateChangeListener, listener); assertTrue("Master was not started", stateChangeListener.awaitForStateChange(LISTENER_TIMEOUT, TimeUnit.SECONDS)); String node2Name = TEST_NODE_NAME + "_2"; @@ -346,7 +346,7 @@ public class ReplicatedEnvironmentFacadeTest extends QpidTestCase }; TestStateChangeListener stateChangeListener = new TestStateChangeListener(State.MASTER); - ReplicatedEnvironmentFacade replicatedEnvironmentFacade = addNode(State.MASTER, stateChangeListener, listener); + ReplicatedEnvironmentFacade replicatedEnvironmentFacade = addNode(stateChangeListener, listener); assertTrue("Master was not started", stateChangeListener.awaitForStateChange(LISTENER_TIMEOUT, TimeUnit.SECONDS)); String node2NodeHostPort = "localhost" + ":" + getNextAvailable(TEST_NODE_PORT + 1); @@ -357,10 +357,10 @@ public class ReplicatedEnvironmentFacadeTest extends QpidTestCase assertTrue("Node add not fired within timeout", nodeAddedLatch.await(LISTENER_TIMEOUT, TimeUnit.SECONDS)); ReplicationNode remoteNode = (ReplicationNode)nodeRef.get(); - assertEquals("Unexpcted node name", node2Name, remoteNode.getName()); + assertEquals("Unexpected node name", node2Name, remoteNode.getName()); assertTrue("Node state not fired within timeout", stateLatch.await(LISTENER_TIMEOUT, TimeUnit.SECONDS)); - assertEquals("Unexpcted node state", State.REPLICA, stateRef.get().getNodeState()); + assertEquals("Unexpected node state", State.REPLICA, stateRef.get().getNodeState()); } public void testRemoveNodeFromGroup() throws Exception @@ -419,7 +419,7 @@ public class ReplicatedEnvironmentFacadeTest extends QpidTestCase }; TestStateChangeListener stateChangeListener = new TestStateChangeListener(State.MASTER); - final ReplicatedEnvironmentFacade masterEnvironment = addNode(State.MASTER, stateChangeListener, listener); + final ReplicatedEnvironmentFacade masterEnvironment = addNode(stateChangeListener, listener); assertTrue("Master was not started", stateChangeListener.awaitForStateChange(LISTENER_TIMEOUT, TimeUnit.SECONDS)); masterEnvironment.setDesignatedPrimary(true); @@ -434,7 +434,7 @@ public class ReplicatedEnvironmentFacadeTest extends QpidTestCase ReplicationNode node = addedNodeRef.get(); assertEquals("Unexpected node name", replicaName, node.getName()); - assertTrue("Node state was not heared", stateLatch.await(WAIT_STATE_CHANGE_TIMEOUT, TimeUnit.SECONDS)); + assertTrue("Node state was not heard", stateLatch.await(WAIT_STATE_CHANGE_TIMEOUT, TimeUnit.SECONDS)); assertEquals("Unexpected node role", State.REPLICA, stateRef.get().getNodeState()); assertEquals("Unexpected node name", replicaName, stateRef.get().getNodeName()); @@ -478,7 +478,7 @@ public class ReplicatedEnvironmentFacadeTest extends QpidTestCase } }; - addNode(State.MASTER, stateChangeListener, new NoopReplicationGroupListener()); + addNode(stateChangeListener, new NoopReplicationGroupListener()); assertTrue("Master was not started", masterLatch.await(LISTENER_TIMEOUT, TimeUnit.SECONDS)); int replica1Port = getNextAvailable(TEST_NODE_PORT + 1); @@ -520,7 +520,7 @@ public class ReplicatedEnvironmentFacadeTest extends QpidTestCase } } }; - ReplicatedEnvironmentFacade firstNode = addNode(State.MASTER, stateChangeListener, new NoopReplicationGroupListener()); + ReplicatedEnvironmentFacade firstNode = addNode(stateChangeListener, new NoopReplicationGroupListener()); assertTrue("Environment did not become a master", firstNodeMasterStateLatch.await(10, TimeUnit.SECONDS)); int replica1Port = getNextAvailable(TEST_NODE_PORT + 1); @@ -548,7 +548,8 @@ public class ReplicatedEnvironmentFacadeTest extends QpidTestCase } } }; - ReplicatedEnvironmentFacade thirdNode = addNode(TEST_NODE_NAME + "_2", node2NodeHostPort, TEST_DESIGNATED_PRIMARY, State.REPLICA, testStateChangeListener, new NoopReplicationGroupListener()); + ReplicatedEnvironmentFacade thirdNode = addNode(TEST_NODE_NAME + "_2", node2NodeHostPort, TEST_DESIGNATED_PRIMARY, + testStateChangeListener, new NoopReplicationGroupListener()); assertTrue("Environment did not become a replica", replicaStateLatch.await(10, TimeUnit.SECONDS)); assertEquals(3, thirdNode.getNumberOfElectableGroupMembers()); @@ -578,7 +579,7 @@ public class ReplicatedEnvironmentFacadeTest extends QpidTestCase } } }; - ReplicatedEnvironmentFacade firstNode = addNode(State.MASTER, stateChangeListener, new NoopReplicationGroupListener()); + ReplicatedEnvironmentFacade firstNode = addNode(stateChangeListener, new NoopReplicationGroupListener()); assertTrue("Environment did not become a master", firstNodeMasterStateLatch.await(10, TimeUnit.SECONDS)); int replica1Port = getNextAvailable(TEST_NODE_PORT + 1); @@ -607,7 +608,8 @@ public class ReplicatedEnvironmentFacadeTest extends QpidTestCase } }; String thirdNodeName = TEST_NODE_NAME + "_2"; - ReplicatedEnvironmentFacade thirdNode = addNode(thirdNodeName, node2NodeHostPort, TEST_DESIGNATED_PRIMARY, State.REPLICA, testStateChangeListener, new NoopReplicationGroupListener()); + ReplicatedEnvironmentFacade thirdNode = addNode(thirdNodeName, node2NodeHostPort, TEST_DESIGNATED_PRIMARY, + testStateChangeListener, new NoopReplicationGroupListener()); assertTrue("Environment did not become a replica", replicaStateLatch.await(10, TimeUnit.SECONDS)); assertEquals(3, thirdNode.getNumberOfElectableGroupMembers()); @@ -665,7 +667,7 @@ public class ReplicatedEnvironmentFacadeTest extends QpidTestCase private ReplicatedEnvironmentFacade createMaster(ReplicationGroupListener replicationGroupListener) throws Exception { TestStateChangeListener stateChangeListener = new TestStateChangeListener(State.MASTER); - ReplicatedEnvironmentFacade env = addNode(State.MASTER, stateChangeListener, replicationGroupListener); + ReplicatedEnvironmentFacade env = addNode(stateChangeListener, replicationGroupListener); assertTrue("Environment was not created", stateChangeListener.awaitForStateChange(LISTENER_TIMEOUT, TimeUnit.SECONDS)); return env; } @@ -680,14 +682,15 @@ public class ReplicatedEnvironmentFacadeTest extends QpidTestCase TestStateChangeListener testStateChangeListener, ReplicationGroupListener replicationGroupListener) throws InterruptedException { - ReplicatedEnvironmentFacade replicaEnvironmentFacade = addNode(nodeName, nodeHostPort, TEST_DESIGNATED_PRIMARY, State.REPLICA, testStateChangeListener, replicationGroupListener); + ReplicatedEnvironmentFacade replicaEnvironmentFacade = addNode(nodeName, nodeHostPort, TEST_DESIGNATED_PRIMARY, + testStateChangeListener, replicationGroupListener); boolean awaitForStateChange = testStateChangeListener.awaitForStateChange(LISTENER_TIMEOUT, TimeUnit.SECONDS); assertTrue("Replica " + nodeName + " did not go into desired state; current actual state is " + testStateChangeListener.getCurrentActualState(), awaitForStateChange); return replicaEnvironmentFacade; } private ReplicatedEnvironmentFacade addNode(String nodeName, String nodeHostPort, boolean designatedPrimary, - State desiredState, StateChangeListener stateChangeListener, ReplicationGroupListener replicationGroupListener) + StateChangeListener stateChangeListener, ReplicationGroupListener replicationGroupListener) { ReplicatedEnvironmentConfiguration config = createReplicatedEnvironmentConfiguration(nodeName, nodeHostPort, designatedPrimary); ReplicatedEnvironmentFacade ref = new ReplicatedEnvironmentFacade(config); @@ -697,9 +700,11 @@ public class ReplicatedEnvironmentFacadeTest extends QpidTestCase return ref; } - private ReplicatedEnvironmentFacade addNode(State desiredState, StateChangeListener stateChangeListener, ReplicationGroupListener replicationGroupListener) + private ReplicatedEnvironmentFacade addNode(StateChangeListener stateChangeListener, + ReplicationGroupListener replicationGroupListener) { - return addNode(TEST_NODE_NAME, TEST_NODE_HOST_PORT, TEST_DESIGNATED_PRIMARY, desiredState, stateChangeListener, replicationGroupListener); + return addNode(TEST_NODE_NAME, TEST_NODE_HOST_PORT, TEST_DESIGNATED_PRIMARY, + stateChangeListener, replicationGroupListener); } private ReplicatedEnvironmentConfiguration createReplicatedEnvironmentConfiguration(String nodeName, String nodeHostPort, boolean designatedPrimary) diff --git a/java/bdbstore/systests/src/main/java/org/apache/qpid/server/store/berkeleydb/HATestClusterCreator.java b/java/bdbstore/systests/src/main/java/org/apache/qpid/server/store/berkeleydb/HATestClusterCreator.java index 48e15561d0..1ac4c681ff 100644 --- a/java/bdbstore/systests/src/main/java/org/apache/qpid/server/store/berkeleydb/HATestClusterCreator.java +++ b/java/bdbstore/systests/src/main/java/org/apache/qpid/server/store/berkeleydb/HATestClusterCreator.java @@ -50,6 +50,7 @@ import org.apache.qpid.server.model.Port; import org.apache.qpid.server.model.VirtualHostNode; import org.apache.qpid.server.virtualhostnode.berkeleydb.BDBHARemoteReplicationNode; import org.apache.qpid.server.virtualhostnode.berkeleydb.BDBHAVirtualHostNode; +import org.apache.qpid.server.virtualhostnode.berkeleydb.BDBHAVirtualHostNodeImpl; import org.apache.qpid.systest.rest.RestTestHelper; import org.apache.qpid.test.utils.QpidBrokerTestCase; import org.apache.qpid.test.utils.TestBrokerConfiguration; @@ -118,12 +119,12 @@ public class HATestClusterCreator virtualHostNodeAttributes.put(BDBHAVirtualHostNode.NAME, nodeName); virtualHostNodeAttributes.put(BDBHAVirtualHostNode.ADDRESS, getNodeHostPortForNodeAt(bdbPort)); virtualHostNodeAttributes.put(BDBHAVirtualHostNode.HELPER_ADDRESS, getHelperHostPort()); - virtualHostNodeAttributes.put(BDBHAVirtualHostNode.TYPE, "BDB_HA"); + virtualHostNodeAttributes.put(BDBHAVirtualHostNode.TYPE, BDBHAVirtualHostNodeImpl.VIRTUAL_HOST_NODE_TYPE); - Map<String, String> repSettings = new HashMap<String, String>(); + Map<String, String> repSettings = new HashMap<>(); repSettings.put(ReplicationConfig.INSUFFICIENT_REPLICAS_TIMEOUT, "2 s"); repSettings.put(ReplicationConfig.ELECTIONS_PRIMARY_RETRIES, "0"); - virtualHostNodeAttributes.put(BDBHAVirtualHostNode.REPLICATED_ENVIRONMENT_CONFIGURATION, repSettings); + virtualHostNodeAttributes.put(BDBHAVirtualHostNode.CONTEXT, repSettings); TestBrokerConfiguration brokerConfiguration = _testcase.getBrokerConfiguration(brokerPort); brokerConfiguration.addJmxManagementConfiguration(); diff --git a/java/broker-core/src/main/java/org/apache/qpid/server/model/AbstractConfiguredObject.java b/java/broker-core/src/main/java/org/apache/qpid/server/model/AbstractConfiguredObject.java index f94f669dfc..f568422d99 100644 --- a/java/broker-core/src/main/java/org/apache/qpid/server/model/AbstractConfiguredObject.java +++ b/java/broker-core/src/main/java/org/apache/qpid/server/model/AbstractConfiguredObject.java @@ -713,7 +713,7 @@ public abstract class AbstractConfiguredObject<X extends ConfiguredObject<X>> im public Map<String,String> getContext() { - return _context == null ? null : Collections.unmodifiableMap(_context); + return _context == null ? Collections.<String,String>emptyMap() : Collections.unmodifiableMap(_context); } public State getDesiredState() diff --git a/java/broker-core/src/main/java/org/apache/qpid/server/store/BrokerStoreUpgraderAndRecoverer.java b/java/broker-core/src/main/java/org/apache/qpid/server/store/BrokerStoreUpgraderAndRecoverer.java index 7fff9151d9..6cc56d0e4d 100644 --- a/java/broker-core/src/main/java/org/apache/qpid/server/store/BrokerStoreUpgraderAndRecoverer.java +++ b/java/broker-core/src/main/java/org/apache/qpid/server/store/BrokerStoreUpgraderAndRecoverer.java @@ -21,6 +21,7 @@ package org.apache.qpid.server.store; import java.util.Arrays; import java.util.Collection; +import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -233,7 +234,7 @@ public class BrokerStoreUpgraderAndRecoverer addAttributeTransformer("storePath", copyAttribute()). addAttributeTransformer("storeUnderfullSize", copyAttribute()). addAttributeTransformer("storeOverfullSize", copyAttribute()). - addAttributeTransformer("bdbEnvironmentConfig", mutateAttributeName("environmentConfiguration"))); + addAttributeTransformer("bdbEnvironmentConfig", mutateAttributeName("context"))); put("JDBC", new AttributesTransformer(). addAttributeTransformer("id", copyAttribute()). addAttributeTransformer("name", copyAttribute()). @@ -242,13 +243,13 @@ public class BrokerStoreUpgraderAndRecoverer addAttributeTransformer("storePath", mutateAttributeName("connectionURL")). addAttributeTransformer("connectionURL", mutateAttributeName("connectionUrl")). addAttributeTransformer("connectionPool", mutateAttributeName("connectionPoolType")). - addAttributeTransformer("jdbcBigIntType", mutateAttributeName("bigIntType")). - addAttributeTransformer("jdbcBytesForBlob", mutateAttributeName("bytesForBlob")). - addAttributeTransformer("jdbcBlobType", mutateAttributeName("blobType")). - addAttributeTransformer("jdbcVarbinaryType", mutateAttributeName("varbinaryType")). - addAttributeTransformer("partitionCount", copyAttribute()). - addAttributeTransformer("maxConnectionsPerPartition", copyAttribute()). - addAttributeTransformer("minConnectionsPerPartition", copyAttribute())); + addAttributeTransformer("jdbcBigIntType", addContextVar("qpid.jdbcstore.bigIntType")). + addAttributeTransformer("jdbcBytesForBlob", addContextVar("qpid.jdbcstore.useBytesForBlob")). + addAttributeTransformer("jdbcBlobType", addContextVar("qpid.jdbcstore.blobType")). + addAttributeTransformer("jdbcVarbinaryType", addContextVar("qpid.jdbcstore.varBinaryType")). + addAttributeTransformer("partitionCount", addContextVar("qpid.jdbcstore.bonecp.partitionCount")). + addAttributeTransformer("maxConnectionsPerPartition", addContextVar("qpid.jdbcstore.bonecp.maxConnectionsPerPartition")). + addAttributeTransformer("minConnectionsPerPartition", addContextVar("qpid.jdbcstore.bonecp.minConnectionsPerPartition"))); put("BDB_HA", new AttributesTransformer(). addAttributeTransformer("id", copyAttribute()). addAttributeTransformer("createdTime", copyAttribute()). @@ -261,8 +262,8 @@ public class BrokerStoreUpgraderAndRecoverer addAttributeTransformer("haHelperAddress", mutateAttributeName("helperAddress")). addAttributeTransformer("haNodeAddress", mutateAttributeName("address")). addAttributeTransformer("haDesignatedPrimary", mutateAttributeName("designatedPrimary")). - addAttributeTransformer("haReplicationConfig", mutateAttributeName("replicatedEnvironmentConfiguration")). - addAttributeTransformer("bdbEnvironmentConfig", mutateAttributeName("environmentConfiguration"))); + addAttributeTransformer("haReplicationConfig", mutateAttributeName("context")). + addAttributeTransformer("bdbEnvironmentConfig", mutateAttributeName("context"))); }}; public ConfiguredObjectRecord upgrade(ConfiguredObjectRecord vhost) @@ -300,7 +301,6 @@ public class BrokerStoreUpgraderAndRecoverer Map<String, Object> nodeAttributes = nodeAttributeTransformer.upgrade(attributes); nodeAttributes.put("type", type); - nodeAttributes.put("messageStoreProvider", true); return new ConfiguredObjectRecordImpl(vhost.getId(), "VirtualHostNode", nodeAttributes, vhost.getParents()); } @@ -329,7 +329,7 @@ public class BrokerStoreUpgraderAndRecoverer public Map<String, Object> upgrade(Map<String, Object> attributes) { - Map<String, Object> settings = new HashMap<String, Object>(); + Map<String, Object> settings = new HashMap<>(); for (Map.Entry<String, List<AttributeTransformer>> entry : _transformers.entrySet()) { String attributeName = entry.getKey(); @@ -349,7 +349,17 @@ public class BrokerStoreUpgraderAndRecoverer } if (newEntry != null) { - settings.put(newEntry.getKey(), newEntry.getValue()); + if (settings.get(newEntry.getKey()) instanceof Map && newEntry.getValue() instanceof Map) + { + final Map newMap = (Map)newEntry.getValue(); + final Map mergedMap = new HashMap((Map) settings.get(newEntry.getKey())); + mergedMap.putAll(newMap); + settings.put(newEntry.getKey(), mergedMap); + } + else + { + settings.put(newEntry.getKey(), newEntry.getValue()); + } } } } @@ -367,6 +377,11 @@ public class BrokerStoreUpgraderAndRecoverer return new MutateAttributeName(newName); } + private static AttributeTransformer addContextVar(String newName) + { + return new AddContextVar(newName); + } + private static interface AttributeTransformer { MutableEntry transform(MutableEntry entry); @@ -386,6 +401,23 @@ public class BrokerStoreUpgraderAndRecoverer return entry; } } + + private static class AddContextVar implements AttributeTransformer + { + private final String _newName; + + public AddContextVar(String newName) + { + _newName = newName; + } + + @Override + public MutableEntry transform(MutableEntry entry) + { + return new MutableEntry("context", Collections.singletonMap(_newName, entry.getValue())); + } + } + private static class MutateAttributeName implements AttributeTransformer { private final String _newName; diff --git a/java/broker-core/src/test/java/org/apache/qpid/server/store/BrokerStoreUpgraderAndRecovererTest.java b/java/broker-core/src/test/java/org/apache/qpid/server/store/BrokerStoreUpgraderAndRecovererTest.java index 7d37363c81..2c9583490a 100644 --- a/java/broker-core/src/test/java/org/apache/qpid/server/store/BrokerStoreUpgraderAndRecovererTest.java +++ b/java/broker-core/src/test/java/org/apache/qpid/server/store/BrokerStoreUpgraderAndRecovererTest.java @@ -20,6 +20,7 @@ */ package org.apache.qpid.server.store; +import static org.mockito.Matchers.contains; import static org.mockito.Mockito.mock; import java.util.Collections; @@ -77,6 +78,11 @@ public class BrokerStoreUpgraderAndRecovererTest extends QpidTestCase hostAttributes.put("partitionCount", 2); hostAttributes.put("storeType", "jdbc"); hostAttributes.put("type", "STANDARD"); + hostAttributes.put("jdbcBigIntType", "mybigint"); + hostAttributes.put("jdbcBlobType", "myblob"); + hostAttributes.put("jdbcVarbinaryType", "myvarbinary"); + hostAttributes.put("jdbcBytesForBlob", true); + ConfiguredObjectRecord virtualHostRecord = new ConfiguredObjectRecordImpl(UUID.randomUUID(), "VirtualHost", hostAttributes, Collections.<String,ConfiguredObjectRecord>singletonMap("Broker", _brokerRecord)); @@ -92,12 +98,20 @@ public class BrokerStoreUpgraderAndRecovererTest extends QpidTestCase expectedAttributes.put("connectionUrl", "jdbc:derby://localhost:1527/tmp/vh/test;create=true"); expectedAttributes.put("createdBy", "webadmin"); expectedAttributes.put("createdTime", 1401385905260l); - expectedAttributes.put("maxConnectionsPerPartition", 7); - expectedAttributes.put("minConnectionsPerPartition", 6); - expectedAttributes.put("partitionCount", 2); expectedAttributes.put("name", "test"); expectedAttributes.put("type", "JDBC"); - expectedAttributes.put("messageStoreProvider", true); + + final Map<String, Object> context = new HashMap<>(); + context.put("qpid.jdbcstore.bigIntType", "mybigint"); + context.put("qpid.jdbcstore.varBinaryType", "myvarbinary"); + context.put("qpid.jdbcstore.blobType", "myblob"); + context.put("qpid.jdbcstore.useBytesForBlob", true); + + context.put("qpid.jdbcstore.bonecp.maxConnectionsPerPartition", 7); + context.put("qpid.jdbcstore.bonecp.minConnectionsPerPartition", 6); + context.put("qpid.jdbcstore.bonecp.partitionCount", 2); + expectedAttributes.put("context", context); + assertEquals("Unexpected attributes", expectedAttributes, upgradedVirtualHostNodeRecord.getAttributes()); } @@ -127,7 +141,6 @@ public class BrokerStoreUpgraderAndRecovererTest extends QpidTestCase expectedAttributes.put("createdTime", 1401385905260l); expectedAttributes.put("name", "test"); expectedAttributes.put("type", "DERBY"); - expectedAttributes.put("messageStoreProvider", true); assertEquals("Unexpected attributes", expectedAttributes, upgradedVirtualHostNodeRecord.getAttributes()); } @@ -141,6 +154,8 @@ public class BrokerStoreUpgraderAndRecovererTest extends QpidTestCase hostAttributes.put("createdBy", "webadmin"); hostAttributes.put("createdTime", 1401385905260l); hostAttributes.put("type", "STANDARD"); + hostAttributes.put("bdbEnvironmentConfig", Collections.singletonMap("je.stats.collect", "false")); + ConfiguredObjectRecord virtualHostRecord = new ConfiguredObjectRecordImpl(UUID.randomUUID(), "VirtualHost", hostAttributes, Collections.<String,ConfiguredObjectRecord>singletonMap("Broker", _brokerRecord)); @@ -157,7 +172,7 @@ public class BrokerStoreUpgraderAndRecovererTest extends QpidTestCase expectedAttributes.put("createdTime", 1401385905260l); expectedAttributes.put("name", "test"); expectedAttributes.put("type", "BDB"); - expectedAttributes.put("messageStoreProvider", true); + expectedAttributes.put("context", Collections.singletonMap("je.stats.collect", "false")); assertEquals("Unexpected attributes", expectedAttributes, upgradedVirtualHostNodeRecord.getAttributes()); } @@ -176,6 +191,9 @@ public class BrokerStoreUpgraderAndRecovererTest extends QpidTestCase hostAttributes.put("haHelperAddress", "localhost:7000"); hostAttributes.put("haNodeAddress", "localhost:7000"); hostAttributes.put("haNodeName", "n1"); + hostAttributes.put("haReplicationConfig", Collections.singletonMap("je.stats.collect", "false")); + hostAttributes.put("bdbEnvironmentConfig", Collections.singletonMap("je.rep.feederTimeout", "1 m")); + ConfiguredObjectRecord virtualHostRecord = new ConfiguredObjectRecordImpl(UUID.randomUUID(), "VirtualHost", hostAttributes, Collections.<String,ConfiguredObjectRecord>singletonMap("Broker", _brokerRecord)); @@ -186,6 +204,10 @@ public class BrokerStoreUpgraderAndRecovererTest extends QpidTestCase ConfiguredObjectRecord upgradedVirtualHostNodeRecord = findRecordById(virtualHostRecord.getId(), records); assertEquals("Unexpected type", "VirtualHostNode", upgradedVirtualHostNodeRecord.getType()); + Map<String,Object> expectedContext = new HashMap<>(); + expectedContext.put("je.stats.collect", "false"); + expectedContext.put("je.rep.feederTimeout", "1 m"); + Map<String,Object> expectedAttributes = new HashMap<>(); expectedAttributes.put("createdBy", "webadmin"); expectedAttributes.put("createdTime", 1401385905260l); @@ -196,7 +218,8 @@ public class BrokerStoreUpgraderAndRecovererTest extends QpidTestCase expectedAttributes.put("address", "localhost:7000"); expectedAttributes.put("helperAddress", "localhost:7000"); expectedAttributes.put("name", "n1"); - expectedAttributes.put("messageStoreProvider", true); + expectedAttributes.put("context", expectedContext); + assertEquals("Unexpected attributes", expectedAttributes, upgradedVirtualHostNodeRecord.getAttributes()); } @@ -224,7 +247,6 @@ public class BrokerStoreUpgraderAndRecovererTest extends QpidTestCase expectedAttributes.put("createdTime", 1401385905260l); expectedAttributes.put("name", "test"); expectedAttributes.put("type", "Memory"); - expectedAttributes.put("messageStoreProvider", true); assertEquals("Unexpected attributes", expectedAttributes, upgradedVirtualHostNodeRecord.getAttributes()); } diff --git a/java/broker-core/src/test/java/org/apache/qpid/server/store/MessageStoreQuotaEventsTestBase.java b/java/broker-core/src/test/java/org/apache/qpid/server/store/MessageStoreQuotaEventsTestBase.java index 89fef15e7e..baab5dd6d3 100644 --- a/java/broker-core/src/test/java/org/apache/qpid/server/store/MessageStoreQuotaEventsTestBase.java +++ b/java/broker-core/src/test/java/org/apache/qpid/server/store/MessageStoreQuotaEventsTestBase.java @@ -50,6 +50,7 @@ public abstract class MessageStoreQuotaEventsTestBase extends QpidTestCase imple protected abstract MessageStore createStore() throws Exception; protected abstract Map<String, Object> createStoreSettings(String storeLocation); + protected abstract Map<String, String> createContextSettings(); protected abstract int getNumberOfMessagesToFillStore(); @Override @@ -67,6 +68,8 @@ public abstract class MessageStoreQuotaEventsTestBase extends QpidTestCase imple ConfiguredObject<?> parent = mock(ConfiguredObject.class); when(parent.getName()).thenReturn("test"); + when(parent.getContext()).thenReturn(createContextSettings()); + _store.openMessageStore(parent, storeSettings); _transactionResource = UUID.randomUUID(); diff --git a/java/broker-plugins/derby-store/src/test/java/org/apache/qpid/server/store/derby/DerbyMessageStoreQuotaEventsTest.java b/java/broker-plugins/derby-store/src/test/java/org/apache/qpid/server/store/derby/DerbyMessageStoreQuotaEventsTest.java index ba7ae26292..348d81fadd 100644 --- a/java/broker-plugins/derby-store/src/test/java/org/apache/qpid/server/store/derby/DerbyMessageStoreQuotaEventsTest.java +++ b/java/broker-plugins/derby-store/src/test/java/org/apache/qpid/server/store/derby/DerbyMessageStoreQuotaEventsTest.java @@ -20,6 +20,7 @@ */ package org.apache.qpid.server.store.derby; +import java.util.Collections; import java.util.HashMap; import java.util.Map; @@ -65,4 +66,10 @@ public class DerbyMessageStoreQuotaEventsTest extends MessageStoreQuotaEventsTes return messageStoreSettings; } + @Override + protected Map<String, String> createContextSettings() + { + return Collections.emptyMap(); + } + } diff --git a/java/broker-plugins/jdbc-provider-bone/src/main/java/org/apache/qpid/server/store/jdbc/bonecp/BoneCPConnectionProvider.java b/java/broker-plugins/jdbc-provider-bone/src/main/java/org/apache/qpid/server/store/jdbc/bonecp/BoneCPConnectionProvider.java index 8bc3a10320..4dfb05ff4f 100644 --- a/java/broker-plugins/jdbc-provider-bone/src/main/java/org/apache/qpid/server/store/jdbc/bonecp/BoneCPConnectionProvider.java +++ b/java/broker-plugins/jdbc-provider-bone/src/main/java/org/apache/qpid/server/store/jdbc/bonecp/BoneCPConnectionProvider.java @@ -31,9 +31,10 @@ import java.util.Map; public class BoneCPConnectionProvider implements ConnectionProvider { - public static final String PARTITION_COUNT = "partitionCount"; - public static final String MAX_CONNECTIONS_PER_PARTITION = "maxConnectionsPerPartition"; - public static final String MIN_CONNECTIONS_PER_PARTITION = "minConnectionsPerPartition"; + public static final String PARTITION_COUNT = "qpid.jdbcstore.bonecp.partitionCount"; + public static final String MAX_CONNECTIONS_PER_PARTITION = "qpid.jdbcstore.bonecp.maxConnectionsPerPartition"; + public static final String MIN_CONNECTIONS_PER_PARTITION = "qpid.jdbcstore.bonecp.minConnectionsPerPartition"; + public static final int DEFAULT_MIN_CONNECTIONS_PER_PARTITION = 5; public static final int DEFAULT_MAX_CONNECTIONS_PER_PARTITION = 10; @@ -43,6 +44,7 @@ public class BoneCPConnectionProvider implements ConnectionProvider public BoneCPConnectionProvider(String connectionUrl, Map<String, Object> storeSettings) throws SQLException { + // TODO change interface to pass through username and password BoneCPConfig config = new BoneCPConfig(); config.setJdbcUrl(connectionUrl); config.setMinConnectionsPerPartition(MapValueConverter.getIntegerAttribute(MIN_CONNECTIONS_PER_PARTITION, storeSettings, DEFAULT_MIN_CONNECTIONS_PER_PARTITION)); diff --git a/java/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/store/jdbc/GenericJDBCConfigurationStore.java b/java/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/store/jdbc/GenericJDBCConfigurationStore.java index 6e707b5f3b..aa8c38cbb0 100644 --- a/java/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/store/jdbc/GenericJDBCConfigurationStore.java +++ b/java/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/store/jdbc/GenericJDBCConfigurationStore.java @@ -32,7 +32,6 @@ import org.apache.log4j.Logger; import org.apache.qpid.server.model.ConfiguredObject; import org.apache.qpid.server.plugin.JDBCConnectionProviderFactory; import org.apache.qpid.server.store.*; -import org.apache.qpid.server.util.MapValueConverter; /** * Implementation of a DurableConfigurationStore backed by Generic JDBC Database @@ -46,15 +45,11 @@ public class GenericJDBCConfigurationStore extends AbstractJDBCConfigurationStor public static final String CONNECTION_URL = "connectionUrl"; public static final String CONNECTION_POOL_TYPE = "connectionPoolType"; - public static final String JDBC_BIG_INT_TYPE = "bigIntType"; - public static final String JDBC_BYTES_FOR_BLOB = "bytesForBlob"; - public static final String JDBC_VARBINARY_TYPE = "varbinaryType"; - public static final String JDBC_BLOB_TYPE = "blobType"; private final AtomicBoolean _configurationStoreOpen = new AtomicBoolean(); private final MessageStore _providedMessageStore = new ProvidedMessageStore(); - protected String _connectionURL; + private String _connectionURL; private ConnectionProvider _connectionProvider; private String _blobType; @@ -74,20 +69,17 @@ public class GenericJDBCConfigurationStore extends AbstractJDBCConfigurationStor _connectionURL = String.valueOf(storeSettings.get(CONNECTION_URL)); Object poolAttribute = storeSettings.get(CONNECTION_POOL_TYPE); - JDBCDetails details = null; + JDBCDetails details = JDBCDetails.getDetailsForJdbcUrl(_connectionURL, parent.getContext()); - String[] components = _connectionURL.split(":", 3); - if(components.length >= 2) + if (!details.isKnownVendor() && getLogger().isInfoEnabled()) { - String vendor = components[1]; - details = JDBCDetails.getDetails(vendor); + getLogger().info("Do not recognize vendor from connection URL: " + _connectionURL + + " Using fallback settings " + details); } - - if(details == null) + if (details.isOverridden() && getLogger().isInfoEnabled()) { - getLogger().info("Do not recognize vendor from connection URL: " + _connectionURL); - - details = JDBCDetails.getDefaultDetails(); + getLogger().info("One or more JDBC details were overridden from context. " + + " Using settings : " + details); } String connectionPoolType = poolAttribute == null ? DefaultConnectionProviderFactory.TYPE : String.valueOf(poolAttribute); @@ -110,12 +102,10 @@ public class GenericJDBCConfigurationStore extends AbstractJDBCConfigurationStor { throw new StoreException("Failed to create connection provider for " + _connectionURL); } - _blobType = MapValueConverter.getStringAttribute(JDBC_BLOB_TYPE, storeSettings, details.getBlobType()); - _varBinaryType = MapValueConverter.getStringAttribute(JDBC_VARBINARY_TYPE, storeSettings, details.getVarBinaryType()); - _useBytesMethodsForBlob = MapValueConverter.getBooleanAttribute(JDBC_BYTES_FOR_BLOB, storeSettings, details.isUseBytesMethodsForBlob()); - _bigIntType = MapValueConverter.getStringAttribute(JDBC_BIG_INT_TYPE, - storeSettings, - details.getBigintType()); + _blobType = details.getBlobType(); + _varBinaryType = details.getVarBinaryType(); + _useBytesMethodsForBlob = details.isUseBytesMethodsForBlob(); + _bigIntType = details.getBigintType(); createOrOpenConfigurationStoreDatabase(); } diff --git a/java/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/store/jdbc/GenericJDBCMessageStore.java b/java/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/store/jdbc/GenericJDBCMessageStore.java index dad4432183..680f6b5d10 100644 --- a/java/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/store/jdbc/GenericJDBCMessageStore.java +++ b/java/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/store/jdbc/GenericJDBCMessageStore.java @@ -25,6 +25,7 @@ import java.sql.Blob; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; +import java.util.Collections; import java.util.Map; import org.apache.log4j.Logger; @@ -42,13 +43,8 @@ public class GenericJDBCMessageStore extends GenericAbstractJDBCMessageStore private static final Logger _logger = Logger.getLogger(GenericJDBCMessageStore.class); - public static final String TYPE = "JDBC"; public static final String CONNECTION_URL = "connectionUrl"; public static final String CONNECTION_POOL_TYPE = "connectionPoolType"; - public static final String JDBC_BIG_INT_TYPE = "bigIntType"; - public static final String JDBC_BYTES_FOR_BLOB = "bytesForBlob"; - public static final String JDBC_VARBINARY_TYPE = "varbinaryType"; - public static final String JDBC_BLOB_TYPE = "blobType"; protected String _connectionURL; private ConnectionProvider _connectionProvider; @@ -58,35 +54,29 @@ public class GenericJDBCMessageStore extends GenericAbstractJDBCMessageStore private String _bigIntType; private boolean _useBytesMethodsForBlob; - @Override protected void doOpen(final ConfiguredObject<?> parent, final Map<String, Object> storeSettings) throws StoreException { _connectionURL = String.valueOf(storeSettings.get(CONNECTION_URL)); - org.apache.qpid.server.store.jdbc.JDBCDetails details = null; + JDBCDetails details = JDBCDetails.getDetailsForJdbcUrl(_connectionURL, parent.getContext()); - String[] components = _connectionURL.split(":", 3); - if(components.length >= 2) + if (!details.isKnownVendor() && getLogger().isInfoEnabled()) { - String vendor = components[1]; - details = org.apache.qpid.server.store.jdbc.JDBCDetails.getDetails(vendor); + getLogger().info("Do not recognize vendor from connection URL: " + _connectionURL + + " Using fallback settings " + details); } - - if(details == null) + if (details.isOverridden() && getLogger().isInfoEnabled()) { - getLogger().info("Do not recognize vendor from connection URL: " + _connectionURL); - - details = org.apache.qpid.server.store.jdbc.JDBCDetails.getDefaultDetails(); + getLogger().info("One or more JDBC details were overridden from context. " + + " Using settings : " + details); } + _blobType = details.getBlobType(); + _varBinaryType = details.getVarBinaryType(); + _useBytesMethodsForBlob = details.isUseBytesMethodsForBlob(); + _bigIntType = details.getBigintType(); - _blobType = MapValueConverter.getStringAttribute(JDBC_BLOB_TYPE, storeSettings, details.getBlobType()); - _varBinaryType = MapValueConverter.getStringAttribute(JDBC_VARBINARY_TYPE, storeSettings, details.getVarBinaryType()); - _useBytesMethodsForBlob = MapValueConverter.getBooleanAttribute(JDBC_BYTES_FOR_BLOB, storeSettings, details.isUseBytesMethodsForBlob()); - _bigIntType = MapValueConverter.getStringAttribute(JDBC_BIG_INT_TYPE, - storeSettings, - details.getBigintType()); Object poolAttribute = storeSettings.get(CONNECTION_POOL_TYPE); String connectionPoolType = poolAttribute == null ? DefaultConnectionProviderFactory.TYPE : String.valueOf(poolAttribute); @@ -95,12 +85,13 @@ public class GenericJDBCMessageStore extends GenericAbstractJDBCMessageStore JDBCConnectionProviderFactory.FACTORIES.get(connectionPoolType); if(connectionProviderFactory == null) { - _logger.warn("Unknown connection pool type: " + connectionPoolType + ". no connection pooling will be used"); + _logger.warn("Unknown connection pool type: " + connectionPoolType + ". No connection pooling will be used"); connectionProviderFactory = new DefaultConnectionProviderFactory(); } try { + // TODO: Pass parent to the connenction provider? _connectionProvider = connectionProviderFactory.getConnectionProvider(_connectionURL, storeSettings); } catch (SQLException e) diff --git a/java/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/store/jdbc/JDBCDetails.java b/java/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/store/jdbc/JDBCDetails.java index 6cf1413b83..a74f852dfa 100644 --- a/java/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/store/jdbc/JDBCDetails.java +++ b/java/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/store/jdbc/JDBCDetails.java @@ -19,123 +19,128 @@ package org.apache.qpid.server.store.jdbc; +import java.util.Collections; import java.util.HashMap; import java.util.Map; -public class JDBCDetails +public abstract class JDBCDetails { + public static final String CONTEXT_JDBCSTORE_BIGINTTYPE = "qpid.jdbcstore.bigIntType"; + public static final String CONTEXT_JDBCSTORE_VARBINARYTYPE = "qpid.jdbcstore.varBinaryType"; + public static final String CONTEXT_JDBCSTORE_BLOBTYPE = "qpid.jdbcstore.blobType"; + public static final String CONTEXT_JDBCSTORE_USEBYTESFORBLOB = "qpid.jdbcstore.useBytesForBlob"; - private static Map<String, JDBCDetails> VENDOR_DETAILS = new HashMap<>(); + public abstract String getVendor(); - private static JDBCDetails DERBY_DETAILS = - new JDBCDetails("derby", - "blob", - "varchar(%d) for bit data", - "bigint", - false); + public abstract String getBlobType(); - private static JDBCDetails POSTGRESQL_DETAILS = - new JDBCDetails("postgresql", - "bytea", - "bytea", - "bigint", - true); + public abstract String getVarBinaryType(); - private static JDBCDetails MYSQL_DETAILS = - new JDBCDetails("mysql", - "blob", - "varbinary(%d)", - "bigint", - false); + public abstract String getBigintType(); + public abstract boolean isUseBytesMethodsForBlob(); - private static JDBCDetails SYBASE_DETAILS = - new JDBCDetails("sybase", - "image", - "varbinary(%d)", - "bigint", - false); + public abstract boolean isKnownVendor(); + public abstract boolean isOverridden(); - private static JDBCDetails ORACLE_DETAILS = - new JDBCDetails("oracle", - "blob", - "raw(%d)", - "number", - false); - - - static - { - - addDetails(DERBY_DETAILS); - addDetails(POSTGRESQL_DETAILS); - addDetails(MYSQL_DETAILS); - addDetails(SYBASE_DETAILS); - addDetails(ORACLE_DETAILS); - } - - public static JDBCDetails getDetails(String vendor) + static class KnownJDBCDetails extends JDBCDetails { - return VENDOR_DETAILS.get(vendor); - } + private static final JDBCDetails FALLBACK = new KnownJDBCDetails("fallback", "blob", "varchar(%d) for bit data", "bigint", false, + false); + private static final JDBCDetails ORACLE = new KnownJDBCDetails("oracle", "blob", "raw(%d)", "number", false, + true); + private static final JDBCDetails SYBASE = new KnownJDBCDetails("sybase", "image", "varbinary(%d)", "bigint", false, + true); + private static final JDBCDetails POSTGRES = new KnownJDBCDetails("postgresql", "bytea", "bytea", "bigint", true, + true); + private static final JDBCDetails DERBY = new KnownJDBCDetails("derby", "blob", "varchar(%d) for bit data", "bigint", false, + true); + + static + { + Map<String, JDBCDetails> map = new HashMap<>(); + + try + { + map.put(ORACLE.getVendor(), ORACLE); + map.put(SYBASE.getVendor(), SYBASE); + map.put(POSTGRES.getVendor(), POSTGRES); + map.put(DERBY.getVendor(), DERBY); + map.put(FALLBACK.getVendor(), FALLBACK); + } + finally + { + VENDOR_DETAILS = Collections.unmodifiableMap(map); + } + } - public static JDBCDetails getDefaultDetails() - { - return DERBY_DETAILS; - } + private final static Map<String, JDBCDetails> VENDOR_DETAILS; + + private final String _vendor; + private final String _blobType; + private final String _varBinaryType; + private final String _bigintType; + private final boolean _useBytesMethodsForBlob; + private final boolean _isKnownVendor; + + KnownJDBCDetails(String vendor, + String blobType, + String varBinaryType, + String bigIntType, + boolean useBytesMethodsForBlob, + boolean knownVendor) + { + _vendor = vendor; + _blobType = blobType; + _varBinaryType = varBinaryType; + _bigintType = bigIntType; + _useBytesMethodsForBlob = useBytesMethodsForBlob; + _isKnownVendor = knownVendor; + } - private static void addDetails(JDBCDetails details) - { - VENDOR_DETAILS.put(details.getVendor(), details); - } + @Override + public String getVendor() + { + return _vendor; + } - private final String _vendor; - private String _blobType; - private String _varBinaryType; - private String _bigintType; - private boolean _useBytesMethodsForBlob; - - JDBCDetails(String vendor, - String blobType, - String varBinaryType, - String bigIntType, - boolean useBytesMethodsForBlob) - { - _vendor = vendor; - setBlobType(blobType); - setVarBinaryType(varBinaryType); - setBigintType(bigIntType); - setUseBytesMethodsForBlob(useBytesMethodsForBlob); - } + @Override + public String getBlobType() + { + return _blobType; + } + @Override + public String getVarBinaryType() + { + return _varBinaryType; + } - @Override - public boolean equals(Object o) - { - if (this == o) + @Override + public boolean isUseBytesMethodsForBlob() { - return true; + return _useBytesMethodsForBlob; } - if (o == null || getClass() != o.getClass()) + + @Override + public String getBigintType() { - return false; + return _bigintType; } - JDBCDetails that = (JDBCDetails) o; + @Override + public boolean isKnownVendor() + { + return _isKnownVendor; + } - if (!getVendor().equals(that.getVendor())) + @Override + public boolean isOverridden() { return false; } - return true; - } - - @Override - public int hashCode() - { - return getVendor().hashCode(); } @Override @@ -147,51 +152,145 @@ public class JDBCDetails ", varBinaryType='" + getVarBinaryType() + '\'' + ", bigIntType='" + getBigintType() + '\'' + ", useBytesMethodsForBlob=" + isUseBytesMethodsForBlob() + + ", knownVendor=" + isKnownVendor() + + ", overridden=" + isOverridden() + '}'; } - public String getVendor() + @Override + public boolean equals(final Object o) { - return _vendor; - } + if (this == o) + { + return true; + } + if (o == null || getClass() != o.getClass()) + { + return false; + } - public String getBlobType() - { - return _blobType; - } + final JDBCDetails that = (JDBCDetails) o; - public void setBlobType(String blobType) - { - _blobType = blobType; - } + if (isKnownVendor() != that.isKnownVendor()) + { + return false; + } + if (isOverridden() != that.isOverridden()) + { + return false; + } + if (isUseBytesMethodsForBlob() != that.isUseBytesMethodsForBlob()) + { + return false; + } + if (getBigintType() != null ? !getBigintType().equals(that.getBigintType()) : that.getBigintType() != null) + { + return false; + } + if (getBlobType() != null ? !getBlobType().equals(that.getBlobType()) : that.getBlobType() != null) + { + return false; + } + if (getVarBinaryType() != null ? !getVarBinaryType().equals(that.getVarBinaryType()) : that.getVarBinaryType() != null) + { + return false; + } + if (getVendor() != null ? !getVendor().equals(that.getVendor()) : that.getVendor() != null) + { + return false; + } - public String getVarBinaryType() - { - return _varBinaryType; + return true; } - public void setVarBinaryType(String varBinaryType) + @Override + public int hashCode() { - _varBinaryType = varBinaryType; + int result = getVendor() != null ? getVendor().hashCode() : 0; + result = 31 * result + (getBlobType() != null ? getBlobType().hashCode() : 0); + result = 31 * result + (getVarBinaryType() != null ? getVarBinaryType().hashCode() : 0); + result = 31 * result + (getBigintType() != null ? getBigintType().hashCode() : 0); + result = 31 * result + (isUseBytesMethodsForBlob() ? 1 : 0); + result = 31 * result + (isKnownVendor() ? 1 : 0); + result = 31 * result + (isOverridden() ? 1 : 0); + return result; } - public boolean isUseBytesMethodsForBlob() - { - return _useBytesMethodsForBlob; - } - public void setUseBytesMethodsForBlob(boolean useBytesMethodsForBlob) + public static JDBCDetails getDetailsForJdbcUrl(String jdbcUrl, final Map<String, String> contextMap) { - _useBytesMethodsForBlob = useBytesMethodsForBlob; - } + String[] components = jdbcUrl.split(":", 3); + final JDBCDetails details; + if(components.length >= 2) + { + String vendor = components[1]; + if (KnownJDBCDetails.VENDOR_DETAILS.containsKey(vendor)) + { + details = KnownJDBCDetails.VENDOR_DETAILS.get(vendor); + } + else + { + details = KnownJDBCDetails.FALLBACK; + } + } + else + { + details = KnownJDBCDetails.FALLBACK; + } - public String getBigintType() - { - return _bigintType; - } - public void setBigintType(String bigintType) - { - _bigintType = bigintType; + return new JDBCDetails() + { + @Override + public String getVendor() + { + return details.getVendor(); + } + + @Override + public String getBlobType() + { + return contextMap.containsKey(CONTEXT_JDBCSTORE_BLOBTYPE) + ? String.valueOf(contextMap.get(CONTEXT_JDBCSTORE_BLOBTYPE)) : details.getBlobType(); + } + + @Override + public String getVarBinaryType() + { + return contextMap.containsKey(CONTEXT_JDBCSTORE_VARBINARYTYPE) + ? String.valueOf(contextMap.get(CONTEXT_JDBCSTORE_VARBINARYTYPE)) : details.getVarBinaryType(); + } + + @Override + public String getBigintType() + { + return contextMap.containsKey(CONTEXT_JDBCSTORE_BIGINTTYPE) + ? String.valueOf(contextMap.get(CONTEXT_JDBCSTORE_BIGINTTYPE)) : details.getBigintType(); + } + + @Override + public boolean isUseBytesMethodsForBlob() + { + return contextMap.containsKey(CONTEXT_JDBCSTORE_USEBYTESFORBLOB) + ? Boolean.parseBoolean(contextMap.get(CONTEXT_JDBCSTORE_USEBYTESFORBLOB)) : details.isUseBytesMethodsForBlob(); + } + + @Override + public boolean isKnownVendor() + { + return details.isKnownVendor(); + } + + @Override + public boolean isOverridden() + { + return contextMap.containsKey(CONTEXT_JDBCSTORE_USEBYTESFORBLOB) + || contextMap.containsKey(CONTEXT_JDBCSTORE_BIGINTTYPE) + || contextMap.containsKey(CONTEXT_JDBCSTORE_VARBINARYTYPE) + || contextMap.containsKey(CONTEXT_JDBCSTORE_BLOBTYPE); + } + }; + } + } diff --git a/java/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/virtualhostnode/jdbc/JDBCVirtualHostNode.java b/java/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/virtualhostnode/jdbc/JDBCVirtualHostNode.java index 302ec9c59f..f9756fec65 100644 --- a/java/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/virtualhostnode/jdbc/JDBCVirtualHostNode.java +++ b/java/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/virtualhostnode/jdbc/JDBCVirtualHostNode.java @@ -33,16 +33,4 @@ public interface JDBCVirtualHostNode<X extends JDBCVirtualHostNode<X>> extends V @ManagedAttribute(defaultValue=DefaultConnectionProviderFactory.TYPE) String getConnectionPoolType(); - @ManagedAttribute - String getBigIntType(); - - @ManagedAttribute - boolean isBytesForBlob(); - - @ManagedAttribute - String getVarBinaryType(); - - @ManagedAttribute - String getBlobType(); - } diff --git a/java/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/virtualhostnode/jdbc/JDBCVirtualHostNodeImpl.java b/java/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/virtualhostnode/jdbc/JDBCVirtualHostNodeImpl.java index ab8f4554cb..9098434b69 100644 --- a/java/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/virtualhostnode/jdbc/JDBCVirtualHostNodeImpl.java +++ b/java/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/virtualhostnode/jdbc/JDBCVirtualHostNodeImpl.java @@ -41,18 +41,6 @@ public class JDBCVirtualHostNodeImpl extends AbstractStandardVirtualHostNode<JDB @ManagedAttributeField private String _connectionPoolType; - @ManagedAttributeField - private String _bigIntType; - - @ManagedAttributeField - private boolean _bytesForBlob; - - @ManagedAttributeField - private String _varBinaryType; - - @ManagedAttributeField - private String _blobType; - @ManagedObjectFactoryConstructor public JDBCVirtualHostNodeImpl(Map<String, Object> attributes, Broker<?> parent) { @@ -77,27 +65,4 @@ public class JDBCVirtualHostNodeImpl extends AbstractStandardVirtualHostNode<JDB return _connectionPoolType; } - @Override - public String getBigIntType() - { - return _bigIntType; - } - - @Override - public boolean isBytesForBlob() - { - return _bytesForBlob; - } - - @Override - public String getVarBinaryType() - { - return _varBinaryType; - } - - @Override - public String getBlobType() - { - return _blobType; - } } diff --git a/java/broker-plugins/jdbc-store/src/test/java/org/apache/qpid/server/store/jdbc/JDBCDetailsTest.java b/java/broker-plugins/jdbc-store/src/test/java/org/apache/qpid/server/store/jdbc/JDBCDetailsTest.java new file mode 100644 index 0000000000..67e9960ca7 --- /dev/null +++ b/java/broker-plugins/jdbc-store/src/test/java/org/apache/qpid/server/store/jdbc/JDBCDetailsTest.java @@ -0,0 +1,94 @@ +/* + * 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.store.jdbc; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import junit.framework.TestCase; + +public class JDBCDetailsTest extends TestCase +{ + public void testDerby() + { + JDBCDetails derbyDetails = JDBCDetails.getDetailsForJdbcUrl("jdbc:derby:sample", + Collections.<String, String>emptyMap()); + assertEquals("derby", derbyDetails.getVendor()); + assertEquals("varchar(%d) for bit data", derbyDetails.getVarBinaryType()); + assertEquals("bigint", derbyDetails.getBigintType()); + assertEquals("blob", derbyDetails.getBlobType()); + assertFalse(derbyDetails.isUseBytesMethodsForBlob()); + + assertTrue(derbyDetails.isKnownVendor()); + assertFalse(derbyDetails.isOverridden()); + } + + public void testUnknownVendor_UsesFallbackDetails() + { + JDBCDetails details = JDBCDetails.getDetailsForJdbcUrl("jdbc:homedb:", Collections.<String, String>emptyMap()); + assertEquals("fallback", details.getVendor()); + assertEquals("varchar(%d) for bit data", details.getVarBinaryType()); + assertEquals("bigint", details.getBigintType()); + assertEquals("blob", details.getBlobType()); + assertEquals(false, details.isUseBytesMethodsForBlob()); + assertFalse(details.isOverridden()); + assertFalse(details.isKnownVendor()); + } + + public void testDerbyWithOverride() + { + + Map<String, String> contextMap = new HashMap<>(); + contextMap.put(JDBCDetails.CONTEXT_JDBCSTORE_VARBINARYTYPE, "myvarbin"); + + JDBCDetails derbyDetails = JDBCDetails.getDetailsForJdbcUrl("jdbc:derby:sample", contextMap); + assertEquals("derby", derbyDetails.getVendor()); + assertEquals("myvarbin", derbyDetails.getVarBinaryType()); + assertEquals("bigint", derbyDetails.getBigintType()); + assertEquals("blob", derbyDetails.getBlobType()); + assertFalse(derbyDetails.isUseBytesMethodsForBlob()); + + assertTrue(derbyDetails.isKnownVendor()); + assertTrue(derbyDetails.isOverridden()); + } + + + + + public void testRecognisedDriver_AllDetailsProvidedByContext() + { + Map<String, String> contextMap = new HashMap<>(); + contextMap.put(JDBCDetails.CONTEXT_JDBCSTORE_VARBINARYTYPE, "myvarbin"); + contextMap.put(JDBCDetails.CONTEXT_JDBCSTORE_BIGINTTYPE, "mybigint"); + contextMap.put(JDBCDetails.CONTEXT_JDBCSTORE_BLOBTYPE, "myblob"); + contextMap.put(JDBCDetails.CONTEXT_JDBCSTORE_USEBYTESFORBLOB, "true"); + + JDBCDetails details = JDBCDetails.getDetailsForJdbcUrl("jdbc:sybase:", contextMap); + assertEquals("sybase", details.getVendor()); + assertEquals("myvarbin", details.getVarBinaryType()); + assertEquals("mybigint", details.getBigintType()); + assertEquals("myblob", details.getBlobType()); + assertEquals(true, details.isUseBytesMethodsForBlob()); + assertTrue(details.isKnownVendor()); + assertTrue(details.isOverridden()); + } + +}
\ No newline at end of file |