summaryrefslogtreecommitdiff
path: root/qpid/java/broker-core
diff options
context:
space:
mode:
Diffstat (limited to 'qpid/java/broker-core')
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/BrokerOptions.java6
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/configuration/store/ManagementModeStoreHandler.java12
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/AbstractExchange.java3
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/DirectExchange.java3
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/HeadersExchange.java3
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/topic/TopicExchangeResult.java13
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/topic/TopicWordDictionary.java3
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/logging/messages/HighAvailabilityMessages.java4
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/logging/messages/HighAvailability_logmessages.properties4
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/AbstractConfiguredObject.java64
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/Broker.java3
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/BrokerModel.java2
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/ConfiguredObject.java2
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/ConfiguredObjectFactoryImpl.java4
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java29
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/AmqpPortImpl.java7
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/PortFactory.java25
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/plugin/ConfigurationSecretEncrypterFactory.java29
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/plugin/JDBCConnectionProviderFactory.java7
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/plugin/PluggableFactoryLoader.java2
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/plugin/QpidServiceLoader.java27
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/protocol/MessageConverterRegistry.java2
-rwxr-xr-xqpid/java/broker-core/src/main/java/org/apache/qpid/server/protocol/MultiVersionProtocolEngineFactory.java2
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/queue/AssignedConsumerMessageGroupManager.java9
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/queue/LastValueQueueList.java3
-rwxr-xr-xqpid/java/broker-core/src/main/java/org/apache/qpid/server/security/SecurityManager.java5
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/encryption/AESKeyFileEncrypter.java130
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/encryption/AESKeyFileEncrypterFactory.java164
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/encryption/ConfigurationSecretEncrypter.java28
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/store/AbstractMemoryStore.java3
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/store/GenericRecoverer.java1
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/store/MemoryMessageStore.java3
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/store/MessageMetaDataTypeRegistry.java4
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/virtualhost/AbstractVirtualHost.java2
-rw-r--r--qpid/java/broker-core/src/main/resources/system.properties0
-rw-r--r--qpid/java/broker-core/src/test/java/org/apache/qpid/server/queue/StandardQueueEntryListTest.java3
36 files changed, 551 insertions, 60 deletions
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/BrokerOptions.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/BrokerOptions.java
index fc3ec82041..a6fae97aaa 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/BrokerOptions.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/BrokerOptions.java
@@ -25,6 +25,7 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
import org.apache.qpid.server.configuration.BrokerProperties;
import org.apache.qpid.server.model.ConfiguredObject;
@@ -54,6 +55,7 @@ public class BrokerOptions
public static final String DEFAULT_LOG_CONFIG_FILE = "etc/log4j.xml";
public static final String DEFAULT_INITIAL_CONFIG_LOCATION =
BrokerOptions.class.getClassLoader().getResource(DEFAULT_INITIAL_CONFIG_NAME).toExternalForm();
+
public static final String MANAGEMENT_MODE_USER_NAME = "mm_admin";
private static final int MANAGEMENT_MODE_PASSWORD_LENGTH = 10;
@@ -76,6 +78,7 @@ public class BrokerOptions
private boolean _skipLoggingConfiguration;
private boolean _overwriteConfigurationStore;
private Map<String, String> _configProperties = new HashMap<String,String>();
+ private String _initialSystemProperties;
public Map<String, Object> convertToSystemAttributes()
{
@@ -304,7 +307,7 @@ public class BrokerOptions
*/
public Map<String,String> getConfigProperties()
{
- ConcurrentHashMap<String, String> properties = new ConcurrentHashMap<String,String>();
+ ConcurrentMap<String, String> properties = new ConcurrentHashMap<String,String>();
properties.putAll(_configProperties);
properties.putIfAbsent(QPID_WORK_DIR, getWorkDir());
@@ -369,4 +372,5 @@ public class BrokerOptions
return _configProperties.get(QPID_HOME_DIR);
}
+
}
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/configuration/store/ManagementModeStoreHandler.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/configuration/store/ManagementModeStoreHandler.java
index 2a39cfa642..44b76cd5c8 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/configuration/store/ManagementModeStoreHandler.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/configuration/store/ManagementModeStoreHandler.java
@@ -34,6 +34,9 @@ import org.apache.qpid.server.BrokerOptions;
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.ConfiguredObjectAttribute;
+import org.apache.qpid.server.model.ConfiguredObjectTypeRegistry;
+import org.apache.qpid.server.model.Model;
import org.apache.qpid.server.model.Port;
import org.apache.qpid.server.model.Protocol;
import org.apache.qpid.server.model.State;
@@ -44,7 +47,6 @@ import org.apache.qpid.server.store.ConfiguredObjectRecordImpl;
import org.apache.qpid.server.store.DurableConfigurationStore;
import org.apache.qpid.server.store.StoreException;
import org.apache.qpid.server.store.handler.ConfiguredObjectRecordHandler;
-import org.apache.qpid.server.util.MapValueConverter;
public class ManagementModeStoreHandler implements DurableConfigurationStore
{
@@ -455,7 +457,13 @@ public class ManagementModeStoreHandler implements DurableConfigurationStore
{
return null;
}
- return MapValueConverter.getEnumSetAttribute(Port.PROTOCOLS, attributes, Protocol.class);
+ Model model = _parent.getModel();
+ ConfiguredObjectTypeRegistry typeRegistry = model.getTypeRegistry();
+ Map<String, ConfiguredObjectAttribute<?, ?>> attributeTypes =
+ typeRegistry.getAttributeTypes(Port.class);
+ ConfiguredObjectAttribute protocolsAttribute = attributeTypes.get(Port.PROTOCOLS);
+ return (Set<Protocol>) protocolsAttribute.convert(object,_parent);
+
}
private ConfiguredObjectRecord createEntryWithState(ConfiguredObjectRecord entry, Object state)
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/AbstractExchange.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/AbstractExchange.java
index e41bb948dc..4472669f4a 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/AbstractExchange.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/AbstractExchange.java
@@ -30,6 +30,7 @@ import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
@@ -102,7 +103,7 @@ public abstract class AbstractExchange<T extends AbstractExchange<T>>
private final CopyOnWriteArrayList<ExchangeImpl.BindingListener> _listeners = new CopyOnWriteArrayList<ExchangeImpl.BindingListener>();
- private final ConcurrentHashMap<BindingIdentifier, BindingImpl> _bindingsMap = new ConcurrentHashMap<BindingIdentifier, BindingImpl>();
+ private final ConcurrentMap<BindingIdentifier, BindingImpl> _bindingsMap = new ConcurrentHashMap<BindingIdentifier, BindingImpl>();
private StateChangeListener<BindingImpl, State> _bindingListener;
private State _state = State.UNINITIALIZED;
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/DirectExchange.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/DirectExchange.java
index 4997095315..66de22ece8 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/DirectExchange.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/DirectExchange.java
@@ -28,6 +28,7 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.CopyOnWriteArraySet;
import org.apache.log4j.Logger;
@@ -133,7 +134,7 @@ public class DirectExchange extends AbstractExchange<DirectExchange>
}
}
- private final ConcurrentHashMap<String, BindingSet> _bindingsByKey =
+ private final ConcurrentMap<String, BindingSet> _bindingsByKey =
new ConcurrentHashMap<String, BindingSet>();
@ManagedObjectFactoryConstructor
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/HeadersExchange.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/HeadersExchange.java
index 83c6b9fd00..67bbc26f74 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/HeadersExchange.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/HeadersExchange.java
@@ -25,6 +25,7 @@ import java.util.LinkedHashSet;
import java.util.ListIterator;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CopyOnWriteArraySet;
@@ -74,7 +75,7 @@ public class HeadersExchange extends AbstractExchange<HeadersExchange>
private static final Logger _logger = Logger.getLogger(HeadersExchange.class);
- private final ConcurrentHashMap<String, CopyOnWriteArraySet<BindingImpl>> _bindingsByKey =
+ private final ConcurrentMap<String, CopyOnWriteArraySet<BindingImpl>> _bindingsByKey =
new ConcurrentHashMap<String, CopyOnWriteArraySet<BindingImpl>>();
private final CopyOnWriteArrayList<HeadersBinding> _bindingHeaderMatchers =
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/topic/TopicExchangeResult.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/topic/TopicExchangeResult.java
index d3a6bd9260..0db3e9b378 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/topic/TopicExchangeResult.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/topic/TopicExchangeResult.java
@@ -20,11 +20,6 @@
*/
package org.apache.qpid.server.exchange.topic;
-import org.apache.qpid.server.binding.BindingImpl;
-import org.apache.qpid.server.filter.Filterable;
-import org.apache.qpid.server.filter.MessageFilter;
-import org.apache.qpid.server.queue.AMQQueue;
-
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
@@ -32,13 +27,19 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.CopyOnWriteArrayList;
+import org.apache.qpid.server.binding.BindingImpl;
+import org.apache.qpid.server.filter.Filterable;
+import org.apache.qpid.server.filter.MessageFilter;
+import org.apache.qpid.server.queue.AMQQueue;
+
public final class TopicExchangeResult implements TopicMatcherResult
{
private final List<BindingImpl> _bindings = new CopyOnWriteArrayList<BindingImpl>();
private final Map<AMQQueue, Integer> _unfilteredQueues = new ConcurrentHashMap<AMQQueue, Integer>();
- private final ConcurrentHashMap<AMQQueue, Map<MessageFilter,Integer>> _filteredQueues = new ConcurrentHashMap<AMQQueue, Map<MessageFilter, Integer>>();
+ private final ConcurrentMap<AMQQueue, Map<MessageFilter,Integer>> _filteredQueues = new ConcurrentHashMap<AMQQueue, Map<MessageFilter, Integer>>();
private volatile ArrayList<AMQQueue> _unfilteredQueueList = new ArrayList<AMQQueue>(0);
public void addUnfilteredQueue(AMQQueue queue)
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/topic/TopicWordDictionary.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/topic/TopicWordDictionary.java
index 24c41ee7da..181f1d32b7 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/topic/TopicWordDictionary.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/topic/TopicWordDictionary.java
@@ -21,10 +21,11 @@
package org.apache.qpid.server.exchange.topic;
import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
public class TopicWordDictionary
{
- private final ConcurrentHashMap<String,TopicWord> _dictionary =
+ private final ConcurrentMap<String,TopicWord> _dictionary =
new ConcurrentHashMap<String,TopicWord>();
public TopicWordDictionary()
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/logging/messages/HighAvailabilityMessages.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/logging/messages/HighAvailabilityMessages.java
index b864a8c095..2234ce6b74 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/logging/messages/HighAvailabilityMessages.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/logging/messages/HighAvailabilityMessages.java
@@ -144,7 +144,7 @@ public class HighAvailabilityMessages
/**
* Log a HighAvailability message of the Format:
- * <pre>HA-1011 : Minimum group : {0}</pre>
+ * <pre>HA-1011 : Minimum group size : {0}</pre>
* Optional values are contained in [square brackets] and are numbered
* sequentially in the method call.
*
@@ -326,7 +326,7 @@ public class HighAvailabilityMessages
/**
* Log a HighAvailability message of the Format:
- * <pre>HA-1012 : Priority : {0}</pre>
+ * <pre>HA-1012 : Priority : {0}</pre>
* Optional values are contained in [square brackets] and are numbered
* sequentially in the method call.
*
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/logging/messages/HighAvailability_logmessages.properties b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/logging/messages/HighAvailability_logmessages.properties
index 3c5b0d260f..1a6bff5353 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/logging/messages/HighAvailability_logmessages.properties
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/logging/messages/HighAvailability_logmessages.properties
@@ -53,10 +53,10 @@ QUORUM_LOST = HA-1009 : Insufficient replicas contactable
ROLE_CHANGED = HA-1010 : Role change reported: Node : ''{0}'' ({1}) : from ''{2}'' to ''{3}''
# 0 - new value
-QUORUM_OVERRIDE_CHANGED = HA-1011 : Minimum group : {0}
+QUORUM_OVERRIDE_CHANGED = HA-1011 : Minimum group size : {0}
# 0 - new value
-PRIORITY_CHANGED = HA-1012 : Priority : {0}
+PRIORITY_CHANGED = HA-1012 : Priority : {0}
# 0 - new value
DESIGNATED_PRIMARY_CHANGED = HA-1013 : Designated primary : {0}
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/AbstractConfiguredObject.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/AbstractConfiguredObject.java
index b191db8523..18930d8817 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/AbstractConfiguredObject.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/AbstractConfiguredObject.java
@@ -64,6 +64,7 @@ import org.apache.qpid.server.configuration.updater.VoidTask;
import org.apache.qpid.server.configuration.updater.VoidTaskWithException;
import org.apache.qpid.server.security.SecurityManager;
import org.apache.qpid.server.security.auth.AuthenticatedPrincipal;
+import org.apache.qpid.server.security.encryption.ConfigurationSecretEncrypter;
import org.apache.qpid.server.store.ConfiguredObjectRecord;
import org.apache.qpid.server.util.Action;
import org.apache.qpid.server.util.ServerScopedRuntimeException;
@@ -89,6 +90,8 @@ public abstract class AbstractConfiguredObject<X extends ConfiguredObject<X>> im
SECURE_VALUES = Collections.unmodifiableMap(secureValues);
}
+ private ConfigurationSecretEncrypter _encrypter;
+
private enum DynamicState { UNINIT, OPENED, CLOSED };
private final AtomicReference<DynamicState> _dynamicState = new AtomicReference<>(DynamicState.UNINIT);
@@ -201,6 +204,16 @@ public abstract class AbstractConfiguredObject<X extends ConfiguredObject<X>> im
_automatedFields = model.getTypeRegistry().getAutomatedFields(getClass());
_stateChangeMethods = model.getTypeRegistry().getStateChangeMethods(getClass());
+
+ for(ConfiguredObject<?> parent : parents.values())
+ {
+ if(parent instanceof AbstractConfiguredObject && ((AbstractConfiguredObject)parent)._encrypter != null)
+ {
+ _encrypter = ((AbstractConfiguredObject)parent)._encrypter;
+ break;
+ }
+ }
+
Object idObj = attributes.get(ID);
UUID uuid;
@@ -541,6 +554,7 @@ public abstract class AbstractConfiguredObject<X extends ConfiguredObject<X>> im
if(skipCheck || _dynamicState.get() != DynamicState.OPENED)
{
onResolve();
+ postResolve();
applyToChildren(new Action<ConfiguredObject<?>>()
{
@Override
@@ -555,6 +569,10 @@ public abstract class AbstractConfiguredObject<X extends ConfiguredObject<X>> im
}
}
+ protected void postResolve()
+ {
+ }
+
protected final void doCreation(final boolean skipCheck)
{
if(skipCheck || _dynamicState.get() != DynamicState.OPENED)
@@ -593,6 +611,11 @@ public abstract class AbstractConfiguredObject<X extends ConfiguredObject<X>> im
{
}
+ protected void setEncrypter(final ConfigurationSecretEncrypter encrypter)
+ {
+ _encrypter = encrypter;
+ }
+
protected void onResolve()
{
Set<ConfiguredObjectAttribute<?,?>> unresolved = new HashSet<>();
@@ -1094,6 +1117,26 @@ public abstract class AbstractConfiguredObject<X extends ConfiguredObject<X>> im
{
value = ((ConfiguredObject)value).getId();
}
+ if(attr.isSecure() && _encrypter != null && value != null)
+ {
+ if(value instanceof Collection || value instanceof Map)
+ {
+ ObjectMapper mapper = new ObjectMapper();
+ try(StringWriter stringWriter = new StringWriter())
+ {
+ mapper.writeValue(stringWriter, value);
+ value = _encrypter.encrypt(stringWriter.toString());
+ }
+ catch (IOException e)
+ {
+ throw new IllegalConfigurationException("Failure when encrypting a secret value", e);
+ }
+ }
+ else
+ {
+ value = _encrypter.encrypt(value.toString());
+ }
+ }
attributes.put(attr.getName(), value);
}
}
@@ -1427,6 +1470,27 @@ public abstract class AbstractConfiguredObject<X extends ConfiguredObject<X>> im
return false;
}
+ @Override
+ public void decryptSecrets()
+ {
+ if(_encrypter != null)
+ {
+ for (Map.Entry<String, Object> entry : _attributes.entrySet())
+ {
+ ConfiguredObjectAttribute<X, ?> attr =
+ (ConfiguredObjectAttribute<X, ?>) _attributeTypes.get(entry.getKey());
+ if (attr != null
+ && attr.isSecure()
+ && entry.getValue() instanceof String)
+ {
+ String decrypt = _encrypter.decrypt((String) entry.getValue());
+ entry.setValue(decrypt);
+ }
+
+ }
+ }
+ }
+
//=========================================================================================
static String interpolate(ConfiguredObject<?> object, String value)
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/Broker.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/Broker.java
index 1a9390f210..011aaeee23 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/Broker.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/Broker.java
@@ -51,6 +51,7 @@ public interface Broker<X extends Broker<X>> extends ConfiguredObject<X>, EventL
String STORE_VERSION = "storeVersion";
String STORE_PATH = "storePath";
String MODEL_VERSION = "modelVersion";
+ String CONFIDENTIAL_CONFIGURATION_ENCRYPTION_PROVIDER = "confidentialConfigurationEncryptionProvider";
String CONNECTION_SESSION_COUNT_LIMIT = "connection.sessionCountLimit";
String CONNECTION_HEART_BEAT_DELAY = "connection.heartBeatDelay";
@@ -139,6 +140,8 @@ public interface Broker<X extends Broker<X>> extends ConfiguredObject<X>, EventL
@ManagedContextDefault(name = MESSAGE_COMPRESSION_THRESHOLD_SIZE)
int DEFAULT_MESSAGE_COMPRESSION_THRESHOLD_SIZE = 102400;
+ @ManagedAttribute
+ String getConfidentialConfigurationEncryptionProvider();
@DerivedAttribute( persist = true )
String getModelVersion();
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/BrokerModel.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/BrokerModel.java
index 2cffea5d73..02c9ccf8e1 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/BrokerModel.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/BrokerModel.java
@@ -105,7 +105,7 @@ public final class BrokerModel extends Model
addRelationship(Session.class, Publisher.class);
_objectFactory = new ConfiguredObjectFactoryImpl(this);
- _typeRegistry = new ConfiguredObjectTypeRegistry((new QpidServiceLoader<ConfiguredObjectRegistration>()).instancesOf(ConfiguredObjectRegistration.class), getSupportedCategories());
+ _typeRegistry = new ConfiguredObjectTypeRegistry((new QpidServiceLoader()).instancesOf(ConfiguredObjectRegistration.class), getSupportedCategories());
}
public final ConfiguredObjectTypeRegistry getTypeRegistry()
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/ConfiguredObject.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/ConfiguredObject.java
index ac5c75f80f..deda7768f3 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/ConfiguredObject.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/ConfiguredObject.java
@@ -253,4 +253,6 @@ public interface ConfiguredObject<X extends ConfiguredObject<X>>
Model getModel();
void delete();
+
+ void decryptSecrets();
}
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/ConfiguredObjectFactoryImpl.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/ConfiguredObjectFactoryImpl.java
index 440a790fc8..350e4fcd44 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/ConfiguredObjectFactoryImpl.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/ConfiguredObjectFactoryImpl.java
@@ -44,8 +44,8 @@ public class ConfiguredObjectFactoryImpl implements ConfiguredObjectFactory
public ConfiguredObjectFactoryImpl(Model model)
{
_model = model;
- QpidServiceLoader<ConfiguredObjectTypeFactory> serviceLoader =
- new QpidServiceLoader<ConfiguredObjectTypeFactory>();
+ QpidServiceLoader serviceLoader =
+ new QpidServiceLoader();
Iterable<ConfiguredObjectTypeFactory> allFactories =
serviceLoader.instancesOf(ConfiguredObjectTypeFactory.class);
for (ConfiguredObjectTypeFactory factory : allFactories)
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java
index af46bae1c4..afa68e23b1 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java
@@ -47,6 +47,8 @@ import org.apache.qpid.server.logging.messages.BrokerMessages;
import org.apache.qpid.server.logging.messages.VirtualHostMessages;
import org.apache.qpid.server.model.*;
import org.apache.qpid.server.model.port.AbstractPortWithAuthProvider;
+import org.apache.qpid.server.plugin.ConfigurationSecretEncrypterFactory;
+import org.apache.qpid.server.plugin.PluggableFactoryLoader;
import org.apache.qpid.server.security.SecurityManager;
import org.apache.qpid.server.security.SubjectCreator;
import org.apache.qpid.server.security.access.Operation;
@@ -94,6 +96,8 @@ public class BrokerAdapter extends AbstractConfiguredObject<BrokerAdapter> imple
private boolean _statisticsReportingResetEnabled;
@ManagedAttributeField
private boolean _messageCompressionEnabled;
+ @ManagedAttributeField
+ private String _confidentialConfigurationEncryptionProvider;
private State _state = State.UNINITIALIZED;
@@ -122,6 +126,25 @@ public class BrokerAdapter extends AbstractConfiguredObject<BrokerAdapter> imple
_dataReceived = new StatisticsCounter("bytes-received");
}
+ @Override
+ protected void postResolve()
+ {
+ super.postResolve();
+ if(_confidentialConfigurationEncryptionProvider != null)
+ {
+
+ PluggableFactoryLoader<ConfigurationSecretEncrypterFactory> factoryLoader =
+ new PluggableFactoryLoader<>(ConfigurationSecretEncrypterFactory.class);
+ ConfigurationSecretEncrypterFactory factory = factoryLoader.get(_confidentialConfigurationEncryptionProvider);
+ if(factory == null)
+ {
+ throw new IllegalConfigurationException("Unknown Configuration Secret Encryption method " + _confidentialConfigurationEncryptionProvider);
+ }
+ setEncrypter(factory.createEncrypter(this));
+ }
+
+ }
+
public void onValidate()
{
super.onValidate();
@@ -368,6 +391,12 @@ public class BrokerAdapter extends AbstractConfiguredObject<BrokerAdapter> imple
}
@Override
+ public String getConfidentialConfigurationEncryptionProvider()
+ {
+ return _confidentialConfigurationEncryptionProvider;
+ }
+
+ @Override
public String getModelVersion()
{
return BrokerModel.MODEL_VERSION;
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/AmqpPortImpl.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/AmqpPortImpl.java
index 6f6d04c335..1fbc0c8bc1 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/AmqpPortImpl.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/AmqpPortImpl.java
@@ -151,8 +151,7 @@ public class AmqpPortImpl extends AbstractPortWithAuthProvider<AmqpPortImpl> imp
TransportProvider transportProvider = null;
final HashSet<Transport> transportSet = new HashSet<Transport>(transports);
- for (TransportProviderFactory tpf : (new QpidServiceLoader<TransportProviderFactory>()).instancesOf(
- TransportProviderFactory.class))
+ for (TransportProviderFactory tpf : (new QpidServiceLoader()).instancesOf(TransportProviderFactory.class))
{
if (tpf.getSupportedTransports().contains(transports))
{
@@ -284,7 +283,7 @@ public class AmqpPortImpl extends AbstractPortWithAuthProvider<AmqpPortImpl> imp
public static Set<Protocol> getInstalledProtocols()
{
Set<Protocol> protocols = new HashSet<>();
- for(ProtocolEngineCreator installedEngine : (new QpidServiceLoader<ProtocolEngineCreator>()).instancesOf(ProtocolEngineCreator.class))
+ for(ProtocolEngineCreator installedEngine : (new QpidServiceLoader()).instancesOf(ProtocolEngineCreator.class))
{
protocols.add(installedEngine.getVersion());
}
@@ -343,7 +342,7 @@ public class AmqpPortImpl extends AbstractPortWithAuthProvider<AmqpPortImpl> imp
{
Set<Set<Transport>> combinations = new HashSet<>();
- for(TransportProviderFactory providerFactory : (new QpidServiceLoader<TransportProviderFactory>()).instancesOf(TransportProviderFactory.class))
+ for(TransportProviderFactory providerFactory : (new QpidServiceLoader()).instancesOf(TransportProviderFactory.class))
{
combinations.addAll(providerFactory.getSupportedTransports());
}
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/PortFactory.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/PortFactory.java
index 99ec4b79cb..870621f292 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/PortFactory.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/PortFactory.java
@@ -24,8 +24,12 @@ import java.util.Map;
import java.util.Set;
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.ConfiguredObjectAttribute;
import org.apache.qpid.server.model.ConfiguredObjectFactory;
+import org.apache.qpid.server.model.ConfiguredObjectTypeRegistry;
+import org.apache.qpid.server.model.Model;
import org.apache.qpid.server.model.Port;
import org.apache.qpid.server.model.Protocol;
import org.apache.qpid.server.model.Protocol.ProtocolType;
@@ -34,7 +38,6 @@ import org.apache.qpid.server.plugin.ConfiguredObjectTypeFactory;
import org.apache.qpid.server.plugin.PluggableService;
import org.apache.qpid.server.store.ConfiguredObjectRecord;
import org.apache.qpid.server.store.UnresolvedConfiguredObject;
-import org.apache.qpid.server.util.MapValueConverter;
@PluggableService
public class PortFactory<X extends Port<X>> implements ConfiguredObjectTypeFactory<X>
@@ -52,11 +55,14 @@ public class PortFactory<X extends Port<X>> implements ConfiguredObjectTypeFacto
{
}
- private ProtocolType getProtocolType(Map<String, Object> portAttributes)
+ private ProtocolType getProtocolType(Map<String, Object> portAttributes, Broker<?> broker)
{
-
- Set<Protocol> protocols = MapValueConverter.getEnumSetAttribute(Port.PROTOCOLS, portAttributes, Protocol.class);
-
+ Model model = broker.getModel();
+ ConfiguredObjectTypeRegistry typeRegistry = model.getTypeRegistry();
+ Map<String, ConfiguredObjectAttribute<?, ?>> attributeTypes =
+ typeRegistry.getAttributeTypes(Port.class);
+ ConfiguredObjectAttribute protocolsAttribute = attributeTypes.get(Port.PROTOCOLS);
+ Set<Protocol> protocols = (Set<Protocol>) protocolsAttribute.convert(portAttributes.get(Port.PROTOCOLS),broker);
ProtocolType protocolType = null;
if(protocols == null || protocols.isEmpty())
@@ -98,7 +104,7 @@ public class PortFactory<X extends Port<X>> implements ConfiguredObjectTypeFacto
final Map<String, Object> attributes,
final ConfiguredObject<?>... parents)
{
- return getPortFactory(factory, attributes).create(factory, attributes,parents);
+ return getPortFactory(factory, attributes, (Broker<?>)parents[0]).create(factory, attributes,parents);
}
@Override
@@ -106,11 +112,12 @@ public class PortFactory<X extends Port<X>> implements ConfiguredObjectTypeFacto
final ConfiguredObjectRecord record,
final ConfiguredObject<?>... parents)
{
- return getPortFactory(factory, record.getAttributes()).recover(factory, record, parents);
+ return getPortFactory(factory, record.getAttributes(), (Broker<?>)parents[0]).recover(factory, record, parents);
}
public ConfiguredObjectTypeFactory<X> getPortFactory(final ConfiguredObjectFactory factory,
- Map<String, Object> attributes)
+ Map<String, Object> attributes,
+ Broker<?> broker)
{
String type;
@@ -120,7 +127,7 @@ public class PortFactory<X extends Port<X>> implements ConfiguredObjectTypeFacto
}
else
{
- type = getProtocolType(attributes).name();
+ type = getProtocolType(attributes, broker).name();
}
return factory.getConfiguredObjectTypeFactory(Port.class.getSimpleName(), type);
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/plugin/ConfigurationSecretEncrypterFactory.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/plugin/ConfigurationSecretEncrypterFactory.java
new file mode 100644
index 0000000000..0548e6418a
--- /dev/null
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/plugin/ConfigurationSecretEncrypterFactory.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.plugin;
+
+import org.apache.qpid.server.model.ConfiguredObject;
+import org.apache.qpid.server.security.encryption.ConfigurationSecretEncrypter;
+
+public interface ConfigurationSecretEncrypterFactory extends Pluggable
+{
+ public ConfigurationSecretEncrypter createEncrypter(ConfiguredObject<?> object);
+}
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/plugin/JDBCConnectionProviderFactory.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/plugin/JDBCConnectionProviderFactory.java
index 14acd59928..6375a03cdf 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/plugin/JDBCConnectionProviderFactory.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/plugin/JDBCConnectionProviderFactory.java
@@ -21,14 +21,9 @@
package org.apache.qpid.server.plugin;
import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
import java.util.Map;
import java.util.Set;
-import org.apache.qpid.server.model.ConfiguredObject;
import org.apache.qpid.server.store.jdbc.ConnectionProvider;
public interface JDBCConnectionProviderFactory extends Pluggable
@@ -48,7 +43,7 @@ public interface JDBCConnectionProviderFactory extends Pluggable
public static JDBCConnectionProviderFactory get(String type)
{
- QpidServiceLoader<JDBCConnectionProviderFactory> qpidServiceLoader = new QpidServiceLoader<JDBCConnectionProviderFactory>();
+ QpidServiceLoader qpidServiceLoader = new QpidServiceLoader();
Iterable<JDBCConnectionProviderFactory> factories = qpidServiceLoader.atLeastOneInstanceOf(JDBCConnectionProviderFactory.class);
for(JDBCConnectionProviderFactory factory : factories)
{
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/plugin/PluggableFactoryLoader.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/plugin/PluggableFactoryLoader.java
index 40db520ff1..462f32e636 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/plugin/PluggableFactoryLoader.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/plugin/PluggableFactoryLoader.java
@@ -33,7 +33,7 @@ public class PluggableFactoryLoader<T extends Pluggable>
public PluggableFactoryLoader(Class<T> factoryClass)
{
Map<String, T> fm = new HashMap<String, T>();
- QpidServiceLoader<T> qpidServiceLoader = new QpidServiceLoader<T>();
+ QpidServiceLoader qpidServiceLoader = new QpidServiceLoader();
Iterable<T> factories = qpidServiceLoader.atLeastOneInstanceOf(factoryClass);
for (T factory : factories)
{
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/plugin/QpidServiceLoader.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/plugin/QpidServiceLoader.java
index 6920d5a879..9f94e7d09d 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/plugin/QpidServiceLoader.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/plugin/QpidServiceLoader.java
@@ -24,16 +24,17 @@ import java.util.List;
import java.util.ServiceLoader;
import org.apache.log4j.Logger;
+
import org.apache.qpid.server.util.ServerScopedRuntimeException;
/**
* Simple facade over a {@link ServiceLoader} to instantiate all configured implementations of an interface.
*/
-public class QpidServiceLoader<C extends Pluggable>
+public class QpidServiceLoader
{
private static final Logger _logger = Logger.getLogger(QpidServiceLoader.class);
- public Iterable<C> instancesOf(Class<C> clazz)
+ public <C extends Pluggable> Iterable<C> instancesOf(Class<C> clazz)
{
return instancesOf(clazz, false);
}
@@ -41,12 +42,12 @@ public class QpidServiceLoader<C extends Pluggable>
/**
* @throws RuntimeException if at least one implementation is not found.
*/
- public Iterable<C> atLeastOneInstanceOf(Class<C> clazz)
+ public <C extends Pluggable> Iterable<C> atLeastOneInstanceOf(Class<C> clazz)
{
return instancesOf(clazz, true);
}
- private Iterable<C> instancesOf(Class<C> clazz, boolean atLeastOne)
+ private <C extends Pluggable> Iterable<C> instancesOf(Class<C> clazz, boolean atLeastOne)
{
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
Iterator<C> serviceLoaderIterator = ServiceLoader.load(clazz, classLoader).iterator();
@@ -55,7 +56,11 @@ public class QpidServiceLoader<C extends Pluggable>
List<C> serviceImplementations = new ArrayList<C>();
while(serviceLoaderIterator.hasNext())
{
- serviceImplementations.add(serviceLoaderIterator.next());
+ C next = serviceLoaderIterator.next();
+ if(!isDisabled(clazz, next))
+ {
+ serviceImplementations.add(next);
+ }
}
if(atLeastOne && serviceImplementations.isEmpty())
@@ -70,4 +75,16 @@ public class QpidServiceLoader<C extends Pluggable>
return serviceImplementations;
}
+
+ private <C extends Pluggable> boolean isDisabled(Class<C> clazz, final C next)
+ {
+ return Boolean.getBoolean("qpid.plugin.disabled:"+clazz.getSimpleName().toLowerCase()+"."+next.getType())
+ || (next instanceof ConfiguredObjectTypeFactory && isDisabledConfiguredType((ConfiguredObjectTypeFactory<?>) next));
+ }
+
+ private boolean isDisabledConfiguredType(final ConfiguredObjectTypeFactory<?> typeFactory)
+ {
+ return Boolean.getBoolean("qpid.type.disabled:" + typeFactory.getCategoryClass().getSimpleName().toLowerCase()
+ + "." + typeFactory.getType());
+ }
}
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/protocol/MessageConverterRegistry.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/protocol/MessageConverterRegistry.java
index 81e5af179d..7959c7f6b4 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/protocol/MessageConverterRegistry.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/protocol/MessageConverterRegistry.java
@@ -35,7 +35,7 @@ public class MessageConverterRegistry
static
{
- for(MessageConverter<? extends ServerMessage, ? extends ServerMessage> converter : (new QpidServiceLoader<MessageConverter>()).instancesOf(MessageConverter.class))
+ for(MessageConverter<? extends ServerMessage, ? extends ServerMessage> converter : (new QpidServiceLoader()).instancesOf(MessageConverter.class))
{
Map<Class<? extends ServerMessage>, MessageConverter> map = _converters.get(converter.getInputClass());
if(map == null)
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/protocol/MultiVersionProtocolEngineFactory.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/protocol/MultiVersionProtocolEngineFactory.java
index b1c49c6fe5..ac8bdc3fa4 100755
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/protocol/MultiVersionProtocolEngineFactory.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/protocol/MultiVersionProtocolEngineFactory.java
@@ -72,7 +72,7 @@ public class MultiVersionProtocolEngineFactory implements ProtocolEngineFactory
_supported = supportedVersions;
_defaultSupportedReply = defaultSupportedReply;
final List<ProtocolEngineCreator> creators = new ArrayList<ProtocolEngineCreator>();
- for(ProtocolEngineCreator c : new QpidServiceLoader<ProtocolEngineCreator>().instancesOf(ProtocolEngineCreator.class))
+ for(ProtocolEngineCreator c : new QpidServiceLoader().instancesOf(ProtocolEngineCreator.class))
{
creators.add(c);
}
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/queue/AssignedConsumerMessageGroupManager.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/queue/AssignedConsumerMessageGroupManager.java
index 8220993e03..e1b25e5abb 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/queue/AssignedConsumerMessageGroupManager.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/queue/AssignedConsumerMessageGroupManager.java
@@ -20,11 +20,12 @@
*/
package org.apache.qpid.server.queue;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
import java.util.Iterator;
import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
public class AssignedConsumerMessageGroupManager implements MessageGroupManager
@@ -33,7 +34,7 @@ public class AssignedConsumerMessageGroupManager implements MessageGroupManager
private final String _groupId;
- private final ConcurrentHashMap<Integer, QueueConsumer<?>> _groupMap = new ConcurrentHashMap<Integer, QueueConsumer<?>>();
+ private final ConcurrentMap<Integer, QueueConsumer<?>> _groupMap = new ConcurrentHashMap<Integer, QueueConsumer<?>>();
private final int _groupMask;
public AssignedConsumerMessageGroupManager(final String groupId, final int maxGroups)
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/queue/LastValueQueueList.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/queue/LastValueQueueList.java
index 6f1edf12e5..1e250ac2c9 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/queue/LastValueQueueList.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/queue/LastValueQueueList.java
@@ -24,6 +24,7 @@ package org.apache.qpid.server.queue;
import java.util.Collections;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicReference;
import org.slf4j.Logger;
@@ -48,7 +49,7 @@ public class LastValueQueueList extends OrderedQueueEntryList
};
private final String _conflationKey;
- private final ConcurrentHashMap<Object, AtomicReference<ConflationQueueEntry>> _latestValuesMap =
+ private final ConcurrentMap<Object, AtomicReference<ConflationQueueEntry>> _latestValuesMap =
new ConcurrentHashMap<Object, AtomicReference<ConflationQueueEntry>>();
private final ConflationQueueEntry _deleteInProgress = new ConflationQueueEntry(this);
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/SecurityManager.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/SecurityManager.java
index 2f7acba91d..96bd9ee0d6 100755
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/SecurityManager.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/SecurityManager.java
@@ -35,6 +35,7 @@ import java.util.Collection;
import java.util.Collections;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
import javax.security.auth.Subject;
@@ -63,11 +64,11 @@ public class SecurityManager implements ConfigurationChangeListener
Collections.emptySet(),
Collections.emptySet());
- private final ConcurrentHashMap<String, AccessControl> _plugins = new ConcurrentHashMap<String, AccessControl>();
+ private final ConcurrentMap<String, AccessControl> _plugins = new ConcurrentHashMap<String, AccessControl>();
private final boolean _managementMode;
private final Broker<?> _broker;
- private final ConcurrentHashMap<PublishAccessCheckCacheEntry, PublishAccessCheck> _publishAccessCheckCache = new ConcurrentHashMap<SecurityManager.PublishAccessCheckCacheEntry, SecurityManager.PublishAccessCheck>();
+ private final ConcurrentMap<PublishAccessCheckCacheEntry, PublishAccessCheck> _publishAccessCheckCache = new ConcurrentHashMap<SecurityManager.PublishAccessCheckCacheEntry, SecurityManager.PublishAccessCheck>();
public SecurityManager(Broker<?> broker, boolean managementMode)
{
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/encryption/AESKeyFileEncrypter.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/encryption/AESKeyFileEncrypter.java
new file mode 100644
index 0000000000..c0c92f0389
--- /dev/null
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/encryption/AESKeyFileEncrypter.java
@@ -0,0 +1,130 @@
+/*
+ *
+ * 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.security.encryption;
+
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+
+import javax.crypto.Cipher;
+import javax.crypto.CipherInputStream;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.SecretKey;
+import javax.crypto.spec.IvParameterSpec;
+import javax.xml.bind.DatatypeConverter;
+
+import org.apache.qpid.server.configuration.IllegalConfigurationException;
+
+class AESKeyFileEncrypter implements ConfigurationSecretEncrypter
+{
+ private static final String CIPHER_NAME = "AES/CBC/PKCS5Padding";
+ private static final int AES_INITIALIZATION_VECTOR_LENGTH = 16;
+ private final SecretKey _secretKey;
+ private final SecureRandom _random = new SecureRandom();
+
+ AESKeyFileEncrypter(SecretKey secretKey)
+ {
+ _secretKey = secretKey;
+ }
+
+ @Override
+ public String encrypt(final String unencrypted)
+ {
+ byte[] unencryptedBytes = unencrypted.getBytes(StandardCharsets.UTF_8);
+ try
+ {
+ byte[] ivbytes = new byte[AES_INITIALIZATION_VECTOR_LENGTH];
+ _random.nextBytes(ivbytes);
+ Cipher cipher = Cipher.getInstance(CIPHER_NAME);
+ cipher.init(Cipher.ENCRYPT_MODE, _secretKey, new IvParameterSpec(ivbytes));
+ byte[] encryptedBytes = readFromCipherStream(unencryptedBytes, cipher);
+ byte[] output = new byte[AES_INITIALIZATION_VECTOR_LENGTH + encryptedBytes.length];
+ System.arraycopy(ivbytes, 0, output, 0, AES_INITIALIZATION_VECTOR_LENGTH);
+ System.arraycopy(encryptedBytes, 0, output, AES_INITIALIZATION_VECTOR_LENGTH, encryptedBytes.length);
+ return DatatypeConverter.printBase64Binary(output);
+ }
+ catch (IOException | InvalidAlgorithmParameterException | InvalidKeyException | NoSuchAlgorithmException | NoSuchPaddingException e)
+ {
+ throw new IllegalConfigurationException("Unable to encrypt secret", e);
+ }
+ }
+
+ @Override
+ public String decrypt(final String encrypted)
+ {
+ byte[] encryptedBytes = DatatypeConverter.parseBase64Binary(encrypted);
+ try
+ {
+ Cipher cipher = Cipher.getInstance(CIPHER_NAME);
+ cipher.init(Cipher.DECRYPT_MODE, _secretKey, new IvParameterSpec(encryptedBytes, 0,
+ AES_INITIALIZATION_VECTOR_LENGTH));
+ return new String(readFromCipherStream(encryptedBytes,
+ AES_INITIALIZATION_VECTOR_LENGTH,
+ encryptedBytes.length - AES_INITIALIZATION_VECTOR_LENGTH,
+ cipher), StandardCharsets.UTF_8);
+ }
+ catch (IOException | InvalidAlgorithmParameterException | InvalidKeyException | NoSuchAlgorithmException | NoSuchPaddingException e)
+ {
+ throw new IllegalConfigurationException("Unable to encrypt secret", e);
+ }
+ }
+
+
+ private byte[] readFromCipherStream(final byte[] unencryptedBytes, final Cipher cipher) throws IOException
+ {
+ return readFromCipherStream(unencryptedBytes, 0, unencryptedBytes.length, cipher);
+ }
+
+ private byte[] readFromCipherStream(final byte[] unencryptedBytes, int offset, int length, final Cipher cipher)
+ throws IOException
+ {
+ final byte[] encryptedBytes;
+ try (CipherInputStream cipherInputStream = new CipherInputStream(new ByteArrayInputStream(unencryptedBytes,
+ offset,
+ length), cipher))
+ {
+ byte[] buf = new byte[1024];
+ int pos = 0;
+ int read;
+ while ((read = cipherInputStream.read(buf, pos, buf.length - pos)) != -1)
+ {
+ pos += read;
+ if (pos == buf.length - 1)
+ {
+ byte[] tmp = buf;
+ buf = new byte[buf.length + 1024];
+ System.arraycopy(tmp, 0, buf, 0, tmp.length);
+ }
+ }
+ encryptedBytes = new byte[pos];
+ System.arraycopy(buf, 0, encryptedBytes, 0, pos);
+ }
+ return encryptedBytes;
+ }
+
+
+
+}
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/encryption/AESKeyFileEncrypterFactory.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/encryption/AESKeyFileEncrypterFactory.java
new file mode 100644
index 0000000000..447f19b7ce
--- /dev/null
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/encryption/AESKeyFileEncrypterFactory.java
@@ -0,0 +1,164 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.server.security.encryption;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.attribute.PosixFilePermission;
+import java.nio.file.attribute.PosixFilePermissions;
+import java.security.NoSuchAlgorithmException;
+import java.util.EnumSet;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Set;
+
+import javax.crypto.KeyGenerator;
+import javax.crypto.SecretKey;
+import javax.crypto.spec.SecretKeySpec;
+
+import org.apache.qpid.server.BrokerOptions;
+import org.apache.qpid.server.configuration.IllegalConfigurationException;
+import org.apache.qpid.server.model.ConfiguredObject;
+import org.apache.qpid.server.plugin.ConfigurationSecretEncrypterFactory;
+import org.apache.qpid.server.plugin.PluggableService;
+
+@PluggableService
+public class AESKeyFileEncrypterFactory implements ConfigurationSecretEncrypterFactory
+{
+ private static final String ENCRYPTER_KEY_FILE = "encrypter.key.file";
+
+ private static final int AES_KEY_SIZE_BITS = 256;
+ private static final int AES_KEY_SIZE_BYTES = AES_KEY_SIZE_BITS / 8;
+ private static final String AES_ALGORITHM = "AES";
+
+ public static String TYPE = "AESKeyFile";
+
+ @Override
+ public ConfigurationSecretEncrypter createEncrypter(final ConfiguredObject<?> object)
+ {
+ String fileLocation;
+ if(object.getContextKeys(false).contains(ENCRYPTER_KEY_FILE))
+ {
+ fileLocation = object.getContextValue(String.class, ENCRYPTER_KEY_FILE);
+ }
+ else
+ {
+
+ fileLocation = object.getContextValue(String.class, BrokerOptions.QPID_WORK_DIR)
+ + File.separator + ".keys" + File.separator
+ + object.getCategoryClass().getSimpleName() + "_"
+ + object.getName() + ".key";
+
+ Map<String, String> context = object.getContext();
+ Map<String, String> modifiedContext = new LinkedHashMap<>(context);
+ modifiedContext.put(ENCRYPTER_KEY_FILE, fileLocation);
+
+ object.setAttribute(ConfiguredObject.CONTEXT, context, modifiedContext);
+ }
+ File file = new File(fileLocation);
+ if(!file.exists())
+ {
+ createAndPopulateKeyFile(file);
+ }
+ if(!file.isFile())
+ {
+ throw new IllegalArgumentException("File '"+fileLocation+"' is not a regular file.");
+ }
+ try
+ {
+ Set<PosixFilePermission> permissions = Files.getPosixFilePermissions(file.toPath());
+
+ if (permissions.contains(PosixFilePermission.GROUP_READ)
+ || permissions.contains(PosixFilePermission.OTHERS_READ)
+ || permissions.contains(PosixFilePermission.GROUP_WRITE)
+ || permissions.contains(PosixFilePermission.OTHERS_WRITE))
+ {
+ throw new IllegalStateException("Key file '"
+ + fileLocation
+ + "' has incorrect permissions. Only the owner "
+ + "should be able to read or write this file.");
+ }
+ if(Files.size(file.toPath()) != AES_KEY_SIZE_BYTES)
+ {
+ throw new IllegalConfigurationException("Key file '" + fileLocation + "' contains an incorrect about of data");
+ }
+
+ try(FileInputStream inputStream = new FileInputStream(file))
+ {
+ byte[] key = new byte[AES_KEY_SIZE_BYTES];
+ int pos = 0;
+ int read;
+ while(pos < key.length && -1 != ( read = inputStream.read(key, pos, key.length - pos)))
+ {
+ pos += read;
+ }
+ if(pos != key.length)
+ {
+ throw new IllegalConfigurationException("Key file '" + fileLocation + "' contained an incorrect about of data");
+ }
+ SecretKeySpec keySpec = new SecretKeySpec(key, AES_ALGORITHM);
+ return new AESKeyFileEncrypter(keySpec);
+ }
+ }
+ catch (IOException e)
+ {
+ throw new IllegalConfigurationException("Unable to get file permissions: " + e.getMessage(), e);
+ }
+ }
+
+ private void createAndPopulateKeyFile(final File file)
+ {
+ try
+ {
+ Set<PosixFilePermission> ownerOnly = EnumSet.of(PosixFilePermission.OWNER_READ,
+ PosixFilePermission.OWNER_WRITE,
+ PosixFilePermission.OWNER_EXECUTE);
+ Files.createDirectories(file.getParentFile().toPath(), PosixFilePermissions.asFileAttribute(ownerOnly));
+
+ Files.createFile(file.toPath(), PosixFilePermissions.asFileAttribute(
+ EnumSet.of(PosixFilePermission.OWNER_READ, PosixFilePermission.OWNER_WRITE)));
+
+ KeyGenerator keyGenerator = KeyGenerator.getInstance(AES_ALGORITHM);
+ keyGenerator.init(AES_KEY_SIZE_BITS);
+ SecretKey key = keyGenerator.generateKey();
+ try(FileOutputStream os = new FileOutputStream(file))
+ {
+ os.write(key.getEncoded());
+ }
+
+ Files.setPosixFilePermissions(file.toPath(), EnumSet.of(PosixFilePermission.OWNER_READ));
+ }
+ catch (NoSuchAlgorithmException | IOException e)
+ {
+ throw new IllegalConfigurationException("Cannot create key file: " + e.getMessage(), e);
+ }
+
+ }
+
+ @Override
+ public String getType()
+ {
+ return TYPE;
+ }
+}
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/encryption/ConfigurationSecretEncrypter.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/encryption/ConfigurationSecretEncrypter.java
new file mode 100644
index 0000000000..d8c64c789c
--- /dev/null
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/encryption/ConfigurationSecretEncrypter.java
@@ -0,0 +1,28 @@
+/*
+ *
+ * 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.security.encryption;
+
+public interface ConfigurationSecretEncrypter
+{
+ String encrypt(String unencrypted);
+
+ String decrypt(String encrypted);
+}
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/store/AbstractMemoryStore.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/store/AbstractMemoryStore.java
index 4d5cb84d04..a9af138a02 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/store/AbstractMemoryStore.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/store/AbstractMemoryStore.java
@@ -24,6 +24,7 @@ import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
import org.apache.qpid.server.model.ConfiguredObject;
import org.apache.qpid.server.store.handler.ConfiguredObjectRecordHandler;
@@ -34,7 +35,7 @@ public abstract class AbstractMemoryStore implements DurableConfigurationStore,
private final Class<? extends ConfiguredObject> _rootClass;
- private final ConcurrentHashMap<UUID, ConfiguredObjectRecord> _configuredObjectRecords = new ConcurrentHashMap<UUID, ConfiguredObjectRecord>();
+ private final ConcurrentMap<UUID, ConfiguredObjectRecord> _configuredObjectRecords = new ConcurrentHashMap<UUID, ConfiguredObjectRecord>();
protected AbstractMemoryStore(final Class<? extends ConfiguredObject> rootClass)
{
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/store/GenericRecoverer.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/store/GenericRecoverer.java
index 58fa852849..9edc5fd30a 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/store/GenericRecoverer.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/store/GenericRecoverer.java
@@ -170,6 +170,7 @@ public class GenericRecoverer
{
updatesMade = true;
ConfiguredObject<?> resolved = recovered.resolve();
+ resolved.decryptSecrets();
resolvedObjects.put(resolved.getId(), resolved);
}
else
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/store/MemoryMessageStore.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/store/MemoryMessageStore.java
index f3b2cac52e..9c0a5118ff 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/store/MemoryMessageStore.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/store/MemoryMessageStore.java
@@ -26,6 +26,7 @@ import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicLong;
import org.apache.qpid.server.message.EnqueueableMessage;
@@ -41,7 +42,7 @@ public class MemoryMessageStore implements MessageStore
private final AtomicLong _messageId = new AtomicLong(1);
- private final ConcurrentHashMap<Long, StoredMemoryMessage> _messages = new ConcurrentHashMap<Long, StoredMemoryMessage>();
+ private final ConcurrentMap<Long, StoredMemoryMessage> _messages = new ConcurrentHashMap<Long, StoredMemoryMessage>();
private final Object _transactionLock = new Object();
private final Map<UUID, Set<Long>> _messageInstances = new HashMap<UUID, Set<Long>>();
private final Map<Xid, DistributedTransactionRecords> _distributedTransactions = new HashMap<Xid, DistributedTransactionRecords>();
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/store/MessageMetaDataTypeRegistry.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/store/MessageMetaDataTypeRegistry.java
index 64f3ab15ee..940abf42f4 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/store/MessageMetaDataTypeRegistry.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/store/MessageMetaDataTypeRegistry.java
@@ -32,7 +32,7 @@ public class MessageMetaDataTypeRegistry
int maxOrdinal = -1;
Iterable<MessageMetaDataType> messageMetaDataTypes =
- new QpidServiceLoader<MessageMetaDataType>().atLeastOneInstanceOf(MessageMetaDataType.class);
+ new QpidServiceLoader().atLeastOneInstanceOf(MessageMetaDataType.class);
for(MessageMetaDataType type : messageMetaDataTypes)
{
@@ -42,7 +42,7 @@ public class MessageMetaDataTypeRegistry
}
}
values = new MessageMetaDataType[maxOrdinal+1];
- for(MessageMetaDataType type : new QpidServiceLoader<MessageMetaDataType>().instancesOf(MessageMetaDataType.class))
+ for(MessageMetaDataType type : new QpidServiceLoader().instancesOf(MessageMetaDataType.class))
{
if(values[type.ordinal()] != null)
{
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/virtualhost/AbstractVirtualHost.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/virtualhost/AbstractVirtualHost.java
index b72d44debf..450fc30bf2 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/virtualhost/AbstractVirtualHost.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/virtualhost/AbstractVirtualHost.java
@@ -272,7 +272,7 @@ public abstract class AbstractVirtualHost<X extends AbstractVirtualHost<X>> exte
private void registerSystemNodes()
{
- QpidServiceLoader<SystemNodeCreator> qpidServiceLoader = new QpidServiceLoader<SystemNodeCreator>();
+ QpidServiceLoader qpidServiceLoader = new QpidServiceLoader();
Iterable<SystemNodeCreator> factories = qpidServiceLoader.instancesOf(SystemNodeCreator.class);
for(SystemNodeCreator creator : factories)
{
diff --git a/qpid/java/broker-core/src/main/resources/system.properties b/qpid/java/broker-core/src/main/resources/system.properties
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/qpid/java/broker-core/src/main/resources/system.properties
diff --git a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/queue/StandardQueueEntryListTest.java b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/queue/StandardQueueEntryListTest.java
index 95c53c8428..28d22a5a44 100644
--- a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/queue/StandardQueueEntryListTest.java
+++ b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/queue/StandardQueueEntryListTest.java
@@ -28,6 +28,7 @@ import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
import org.apache.qpid.server.configuration.updater.CurrentThreadTaskExecutor;
import org.apache.qpid.server.logging.EventLogger;
@@ -155,7 +156,7 @@ public class StandardQueueEntryListTest extends QueueEntryListTestBase
public void testScavenge() throws Exception
{
OrderedQueueEntryList sqel = new StandardQueueEntryList(null);
- ConcurrentHashMap<Integer,QueueEntry> entriesMap = new ConcurrentHashMap<Integer,QueueEntry>();
+ ConcurrentMap<Integer,QueueEntry> entriesMap = new ConcurrentHashMap<Integer,QueueEntry>();
//Add messages to generate QueueEntry's