summaryrefslogtreecommitdiff
path: root/qpid/java
diff options
context:
space:
mode:
authorRobert Godfrey <rgodfrey@apache.org = rgodfrey = Robert Godfrey rgodfrey@apache.org@apache.org>2014-04-13 23:41:53 +0000
committerRobert Godfrey <rgodfrey@apache.org = rgodfrey = Robert Godfrey rgodfrey@apache.org@apache.org>2014-04-13 23:41:53 +0000
commit981b8f5357355f842a523e4b50a1d5c711095a68 (patch)
tree8b3f05d036802077af1ae280c3c357b39dc3a4f0 /qpid/java
parent529183e95ce802787694ec7b5b72a50f2c895821 (diff)
downloadqpid-python-981b8f5357355f842a523e4b50a1d5c711095a68.tar.gz
QPID-5690 : [Java Broker] Improve mechanisms for validating and reacting to changes in configured object attribute values
git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@1587123 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'qpid/java')
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/Broker.java3
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/AbstractExchange.java12
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/AbstractConfiguredObject.java265
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/AuthenticationProvider.java45
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/Broker.java2
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/ExternalFileBasedAuthenticationManager.java27
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/ManagedAttributeField.java2
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/Model.java72
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/SystemContext.java295
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/SystemContextImpl.java331
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/AbstractPluginAdapter.java12
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java19
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapterFactory.java8
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/FileBasedGroupProvider.java582
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/FileBasedGroupProviderFactory.java16
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/FileBasedGroupProviderImpl.java592
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/FileSystemPreferencesProvider.java567
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/FileSystemPreferencesProviderFactory.java16
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/FileSystemPreferencesProviderImpl.java588
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/AbstractPort.java12
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/AbstractPortWithAuthProvider.java (renamed from qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/PortWithAuthProvider.java)16
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/AmqpPort.java248
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/AmqpPortFactory.java16
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/AmqpPortImpl.java256
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/HttpPort.java37
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/HttpPortFactory.java16
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/HttpPortImpl.java47
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/JmxPort.java42
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/JmxPortFactory.java16
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/JmxPortImpl.java54
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/queue/AMQQueue.java4
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/queue/AbstractQueue.java38
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/registry/ApplicationRegistry.java1
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/FileKeyStore.java341
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/FileKeyStoreFactory.java16
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/FileKeyStoreImpl.java331
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/FileTrustStore.java363
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/FileTrustStoreFactory.java16
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/FileTrustStoreImpl.java369
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/AbstractAuthenticationManager.java17
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationManager.java101
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationManagerFactory.java18
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationManagerImpl.java121
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManager.java22
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationManager.java442
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationManagerFactory.java18
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationManagerImpl.java468
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/virtualhost/AbstractVirtualHost.java12
-rw-r--r--qpid/java/broker-core/src/test/java/org/apache/qpid/server/configuration/BrokerConfigurationStoreCreatorTest.java3
-rw-r--r--qpid/java/broker-core/src/test/java/org/apache/qpid/server/configuration/startup/BrokerRecovererTest.java13
-rw-r--r--qpid/java/broker-core/src/test/java/org/apache/qpid/server/configuration/startup/FileTrustStoreCreationTest.java5
-rw-r--r--qpid/java/broker-core/src/test/java/org/apache/qpid/server/configuration/startup/PreferencesProviderCreationTest.java6
-rw-r--r--qpid/java/broker-core/src/test/java/org/apache/qpid/server/configuration/store/JsonConfigurationEntryStoreTest.java3
-rw-r--r--qpid/java/broker-core/src/test/java/org/apache/qpid/server/configuration/store/ManagementModeStoreHandlerTest.java3
-rw-r--r--qpid/java/broker-core/src/test/java/org/apache/qpid/server/configuration/store/MemoryConfigurationEntryStoreTest.java3
-rw-r--r--qpid/java/broker-core/src/test/java/org/apache/qpid/server/model/adapter/FileSystemPreferencesProviderFactoryTest.java3
-rw-r--r--qpid/java/broker-core/src/test/java/org/apache/qpid/server/model/adapter/FileSystemPreferencesProviderTest.java17
-rw-r--r--qpid/java/broker-core/src/test/java/org/apache/qpid/server/model/adapter/PortFactoryTest.java4
-rw-r--r--qpid/java/broker-core/src/test/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationManagerTest.java6
-rw-r--r--qpid/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/ACLFileAccessControlProvider.java221
-rw-r--r--qpid/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/ACLFileAccessControlProviderFactory.java12
-rw-r--r--qpid/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/ACLFileAccessControlProviderImpl.java241
-rw-r--r--qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagement.java8
-rw-r--r--qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagedObjectRegistry.java4
-rw-r--r--qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagementFactory.java16
-rw-r--r--qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagementPlugin.java35
-rw-r--r--qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagementPluginImpl.java (renamed from qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagement.java)24
-rw-r--r--qpid/java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/server/jmx/JMXManagementFactoryTest.java8
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/systest/rest/QueueRestTest.java2
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/test/utils/TestBrokerConfiguration.java4
70 files changed, 4118 insertions, 3435 deletions
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/Broker.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/Broker.java
index d58e906b0a..038667249e 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/Broker.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/Broker.java
@@ -46,6 +46,7 @@ import org.apache.qpid.server.logging.messages.BrokerMessages;
import org.apache.qpid.server.model.ConfiguredObjectFactory;
import org.apache.qpid.server.model.Model;
import org.apache.qpid.server.model.SystemContext;
+import org.apache.qpid.server.model.SystemContextImpl;
import org.apache.qpid.server.registry.ApplicationRegistry;
import org.apache.qpid.server.registry.IApplicationRegistry;
import org.apache.qpid.server.security.SecurityManager;
@@ -136,7 +137,7 @@ public class Broker
TaskExecutor taskExecutor = new TaskExecutor();
taskExecutor.start();
ConfiguredObjectFactory configuredObjectFactory = new ConfiguredObjectFactory(Model.getInstance());
- SystemContext systemContext = new SystemContext(taskExecutor, configuredObjectFactory, _eventLogger, logRecorder, options);
+ SystemContext systemContext = new SystemContextImpl(taskExecutor, configuredObjectFactory, _eventLogger, logRecorder, options);
BrokerConfigurationStoreCreator storeCreator = new BrokerConfigurationStoreCreator();
DurableConfigurationStore store = storeCreator.createStore(systemContext, storeType, options.getInitialConfigurationLocation(),
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 b94f73854b..933f2700bf 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
@@ -27,6 +27,7 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
@@ -913,19 +914,14 @@ public abstract class AbstractExchange<T extends AbstractExchange<T>>
@Override
- protected void changeAttributes(Map<String, Object> attributes)
+ protected void validateChange(final ConfiguredObject<?> proxyForValidation, final Set<String> changedAttributes)
{
+ super.validateChange(proxyForValidation, changedAttributes);
throw new UnsupportedOperationException("Changing attributes on exchange is not supported.");
}
@Override
- protected void authoriseSetAttribute(String name, Object expected, Object desired) throws AccessControlException
- {
- _virtualHost.getSecurityManager().authoriseUpdate(this);
- }
-
- @Override
- protected void authoriseSetAttributes(Map<String, Object> attributes) throws AccessControlException
+ protected void authoriseSetAttributes(ConfiguredObject<?> modified, Set<String> attributes) throws AccessControlException
{
_virtualHost.getSecurityManager().authoriseUpdate(this);
}
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 12bd2dc7f8..9359429501 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
@@ -21,8 +21,11 @@
package org.apache.qpid.server.model;
import java.lang.reflect.Field;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
+import java.lang.reflect.Proxy;
import java.security.AccessControlException;
import java.security.AccessController;
import java.security.PrivilegedAction;
@@ -69,8 +72,8 @@ public abstract class AbstractConfiguredObject<X extends ConfiguredObject<X>> im
private static final Map<Class<? extends ConfiguredObject>, Map<String, ConfiguredObjectAttribute<?,?>>> _allAttributeTypes =
Collections.synchronizedMap(new HashMap<Class<? extends ConfiguredObject>, Map<String, ConfiguredObjectAttribute<?, ?>>>());
- private static final Map<Class<? extends ConfiguredObject>, Map<String, Field>> _allAutomatedFields =
- Collections.synchronizedMap(new HashMap<Class<? extends ConfiguredObject>, Map<String, Field>>());
+ private static final Map<Class<? extends ConfiguredObject>, Map<String, AutomatedField>> _allAutomatedFields =
+ Collections.synchronizedMap(new HashMap<Class<? extends ConfiguredObject>, Map<String, AutomatedField>>());
private static final Map<Class, Object> SECURE_VALUES;
public static final String SECURED_STRING_VALUE = "********";
@@ -108,6 +111,9 @@ public abstract class AbstractConfiguredObject<X extends ConfiguredObject<X>> im
private final TaskExecutor _taskExecutor;
+ private final Class<? extends ConfiguredObject> _category;
+ private final Class<? extends ConfiguredObject> _bestFitInterface;
+
@ManagedAttributeField
private long _createdTime;
@@ -127,7 +133,7 @@ public abstract class AbstractConfiguredObject<X extends ConfiguredObject<X>> im
private Map<String,String> _context;
private final Map<String, ConfiguredObjectAttribute<?,?>> _attributeTypes;
- private final Map<String, Field> _automatedFields;
+ private final Map<String, AutomatedField> _automatedFields;
@ManagedAttributeField
private String _type;
@@ -173,7 +179,11 @@ public abstract class AbstractConfiguredObject<X extends ConfiguredObject<X>> im
_attributeTypes = getAttributeTypes(getClass());
_automatedFields = getAutomatedFields(getClass());
+
+ _category = Model.getCategory(getClass());
_type = Model.getType(getClass());
+ _bestFitInterface = calculateBestFitInterface();
+
if(attributes.get(TYPE) != null)
{
if(!_type.equals(attributes.get(TYPE)))
@@ -239,7 +249,61 @@ public abstract class AbstractConfiguredObject<X extends ConfiguredObject<X>> im
throw new IllegalArgumentException("Mandatory attribute " + attr.getName() + " not supplied for instance of " + getClass().getName());
}
}
+ }
+
+ private Class<? extends ConfiguredObject> calculateBestFitInterface()
+ {
+ Set<Class<? extends ConfiguredObject>> candidates = new HashSet<Class<? extends ConfiguredObject>>();
+ findBestFitInterface(getClass(), candidates);
+ switch(candidates.size())
+ {
+ case 0:
+ throw new ServerScopedRuntimeException("The configured object class " + getClass().getSimpleName() + " does not seem to implement an interface");
+ case 1:
+ return candidates.iterator().next();
+ default:
+ throw new ServerScopedRuntimeException("The configured object class " + getClass().getSimpleName() + " implements no single common interface which extends ConfiguredObject");
+ }
+ }
+
+ private static final void findBestFitInterface(Class<? extends ConfiguredObject> clazz, Set<Class<? extends ConfiguredObject>> candidates)
+ {
+ for(Class<?> interfaceClass : clazz.getInterfaces())
+ {
+ if(ConfiguredObject.class.isAssignableFrom(interfaceClass))
+ {
+ checkCandidate((Class<? extends ConfiguredObject>) interfaceClass, candidates);
+ }
+ }
+ if(clazz.getSuperclass() != null & ConfiguredObject.class.isAssignableFrom(clazz.getSuperclass()))
+ {
+ findBestFitInterface((Class<? extends ConfiguredObject>) clazz.getSuperclass(), candidates);
+ }
+ }
+
+ private static void checkCandidate(final Class<? extends ConfiguredObject> interfaceClass,
+ final Set<Class<? extends ConfiguredObject>> candidates)
+ {
+ if(!candidates.contains(interfaceClass))
+ {
+ Iterator<Class<? extends ConfiguredObject>> candidateIterator = candidates.iterator();
+ while(candidateIterator.hasNext())
+ {
+ Class<? extends ConfiguredObject> existingCandidate = candidateIterator.next();
+ if(existingCandidate.isAssignableFrom(interfaceClass))
+ {
+ candidateIterator.remove();
+ }
+ else if(interfaceClass.isAssignableFrom(existingCandidate))
+ {
+ return;
+ }
+ }
+
+ candidates.add(interfaceClass);
+
+ }
}
private void automatedSetValue(final String name, Object value)
@@ -251,12 +315,27 @@ public abstract class AbstractConfiguredObject<X extends ConfiguredObject<X>> im
{
value = attribute.getAnnotation().defaultValue();
}
- _automatedFields.get(name).set(this, attribute.convert(value, this));
+ AutomatedField field = _automatedFields.get(name);
+
+ if(field.getPreSettingAction() != null)
+ {
+ field.getPreSettingAction().invoke(this);
+ }
+ field.getField().set(this, attribute.convert(value, this));
+
+ if(field.getPostSettingAction() != null)
+ {
+ field.getPostSettingAction().invoke(this);
+ }
}
catch (IllegalAccessException e)
{
throw new ServerScopedRuntimeException("Unable to set the automated attribute " + name + " on the configure object type " + getClass().getName(),e);
}
+ catch (InvocationTargetException e)
+ {
+ throw new ServerScopedRuntimeException("Unable to set the automated attribute " + name + " on the configure object type " + getClass().getName(),e);
+ }
}
public void open()
@@ -406,7 +485,7 @@ public abstract class AbstractConfiguredObject<X extends ConfiguredObject<X>> im
public Class<? extends ConfiguredObject> getCategoryClass()
{
- return Model.getCategory(getClass());
+ return _category;
}
public Map<String,String> getContext()
@@ -602,7 +681,9 @@ public abstract class AbstractConfiguredObject<X extends ConfiguredObject<X>> im
{
if (_taskExecutor.isTaskExecutorThread())
{
- authoriseSetAttribute(name, expected, desired);
+ authoriseSetAttributes(createProxyForValidation(Collections.singletonMap(name, desired)),
+ Collections.singleton(name));
+
if (changeAttribute(name, expected, desired))
{
attributeSet(name, expected, desired);
@@ -803,7 +884,7 @@ public abstract class AbstractConfiguredObject<X extends ConfiguredObject<X>> im
{
if (getTaskExecutor().isTaskExecutorThread())
{
- authoriseSetAttributes(attributes);
+ authoriseSetAttributes(createProxyForValidation(attributes), attributes.keySet());
changeAttributes(attributes);
}
else
@@ -812,9 +893,15 @@ public abstract class AbstractConfiguredObject<X extends ConfiguredObject<X>> im
}
}
+ protected void authoriseSetAttributes(final ConfiguredObject<?> proxyForValidation,
+ final Set<String> modifiedAttributes)
+ {
+
+ }
+
protected void changeAttributes(final Map<String, Object> attributes)
{
- validateChangeAttributes(attributes);
+ validateChange(createProxyForValidation(attributes), attributes.keySet());
Collection<String> names = getAttributeNames();
for (String name : names)
{
@@ -830,25 +917,21 @@ public abstract class AbstractConfiguredObject<X extends ConfiguredObject<X>> im
}
}
- protected void validateChangeAttributes(final Map<String, Object> attributes)
+ protected void validateChange(final ConfiguredObject<?> proxyForValidation, final Set<String> changedAttributes)
{
- if (attributes.containsKey(ID))
+ if(!getId().equals(proxyForValidation.getId()))
{
- UUID id = getId();
- Object idAttributeValue = attributes.get(ID);
- if (idAttributeValue != null && !(idAttributeValue.equals(id) || idAttributeValue.equals(id.toString())))
- {
- throw new IllegalConfigurationException("Cannot change existing configured object id");
- }
+ throw new IllegalConfigurationException("Cannot change existing configured object id");
}
}
- protected void authoriseSetDesiredState(State currentState, State desiredState) throws AccessControlException
+ private ConfiguredObject<?> createProxyForValidation(final Map<String, Object> attributes)
{
- // allowed by default
+ return (ConfiguredObject<?>) Proxy.newProxyInstance(getClass().getClassLoader(),new Class<?>[]{_bestFitInterface},
+ new AttributeGettingHandler(attributes));
}
- protected void authoriseSetAttribute(String name, Object expected, Object desired) throws AccessControlException
+ protected void authoriseSetDesiredState(State currentState, State desiredState) throws AccessControlException
{
// allowed by default
}
@@ -858,11 +941,6 @@ public abstract class AbstractConfiguredObject<X extends ConfiguredObject<X>> im
// allowed by default
}
- protected void authoriseSetAttributes(Map<String, Object> attributes) throws AccessControlException
- {
- // allowed by default
- }
-
/**
* Returns a map of effective attribute values that would result
* if applying the supplied changes. Does not apply the changes.
@@ -1071,6 +1149,34 @@ public abstract class AbstractConfiguredObject<X extends ConfiguredObject<X>> im
}
}
+ private static class AutomatedField
+ {
+ private final Field _field;
+ private final Method _preSettingAction;
+ private final Method _postSettingAction;
+
+ private AutomatedField(final Field field, final Method preSettingAction, final Method postSettingAction)
+ {
+ _field = field;
+ _preSettingAction = preSettingAction;
+ _postSettingAction = postSettingAction;
+ }
+
+ public Field getField()
+ {
+ return _field;
+ }
+
+ public Method getPreSettingAction()
+ {
+ return _preSettingAction;
+ }
+
+ public Method getPostSettingAction()
+ {
+ return _postSettingAction;
+ }
+ }
private static <X extends ConfiguredObject> void processAttributes(final Class<X> clazz)
{
@@ -1149,6 +1255,10 @@ public abstract class AbstractConfiguredObject<X extends ConfiguredObject<X>> im
ManagedAttribute annotation = m.getAnnotation(ManagedAttribute.class);
if(annotation != null)
{
+ if(!clazz.isInterface() || !ConfiguredObject.class.isAssignableFrom(clazz))
+ {
+ throw new ServerScopedRuntimeException("Can only define ManagedAttributes on interfaces which extend " + ConfiguredObject.class.getSimpleName() + ". " + clazz.getSimpleName() + " does not meet these criteria.");
+ }
addToAttributesSet(clazz, new ConfiguredObjectAttribute(clazz, m, annotation));
}
else
@@ -1156,13 +1266,17 @@ public abstract class AbstractConfiguredObject<X extends ConfiguredObject<X>> im
ManagedStatistic statAnnotation = m.getAnnotation(ManagedStatistic.class);
if(statAnnotation != null)
{
+ if(!clazz.isInterface() || !ConfiguredObject.class.isAssignableFrom(clazz))
+ {
+ throw new ServerScopedRuntimeException("Can only define ManagedStatistics on interfaces which extend " + ConfiguredObject.class.getSimpleName() + ". " + clazz.getSimpleName() + " does not meet these criteria.");
+ }
addToStatisticsSet(clazz, new ConfiguredObjectStatistic(clazz,m));
}
}
}
Map<String,ConfiguredObjectAttribute<?,?>> attrMap = new HashMap<String, ConfiguredObjectAttribute<?, ?>>();
- Map<String,Field> fieldMap = new HashMap<String, Field>();
+ Map<String,AutomatedField> fieldMap = new HashMap<String, AutomatedField>();
Collection<ConfiguredObjectAttribute<?, ?>> attrCol = _allAttributes.get(clazz);
@@ -1204,17 +1318,46 @@ public abstract class AbstractConfiguredObject<X extends ConfiguredObject<X>> im
}
}
- private static Field findField(final ConfiguredObjectAttribute<?, ?> attr, Class<?> objClass)
+ private static AutomatedField findField(final ConfiguredObjectAttribute<?, ?> attr, Class<?> objClass)
{
Class<?> clazz = objClass;
while(clazz != null)
{
for(Field field : clazz.getDeclaredFields())
{
- if(field.getAnnotation(ManagedAttributeField.class) != null && field.getName().equals("_" + attr.getName().replace('.','_')))
+ if(field.isAnnotationPresent(ManagedAttributeField.class) && field.getName().equals("_" + attr.getName().replace('.','_')))
{
- field.setAccessible(true);
- return field;
+ try
+ {
+ ManagedAttributeField annotation = field.getAnnotation(ManagedAttributeField.class);
+ field.setAccessible(true);
+ Method beforeSet;
+ if (!"".equals(annotation.beforeSet()))
+ {
+ beforeSet = clazz.getDeclaredMethod(annotation.beforeSet());
+ beforeSet.setAccessible(true);
+ }
+ else
+ {
+ beforeSet = null;
+ }
+ Method afterSet;
+ if (!"".equals(annotation.afterSet()))
+ {
+ afterSet = clazz.getDeclaredMethod(annotation.afterSet());
+ afterSet.setAccessible(true);
+ }
+ else
+ {
+ afterSet = null;
+ }
+ return new AutomatedField(field, beforeSet, afterSet);
+ }
+ catch (NoSuchMethodException e)
+ {
+ throw new ServerScopedRuntimeException("Cannot find method referenced by annotation for pre/post setting action", e);
+ }
+
}
}
clazz = clazz.getSuperclass();
@@ -1298,7 +1441,7 @@ public abstract class AbstractConfiguredObject<X extends ConfiguredObject<X>> im
return _allAttributeTypes.get(clazz);
}
- private static Map<String, Field> getAutomatedFields(Class<? extends ConfiguredObject> clazz)
+ private static Map<String, AutomatedField> getAutomatedFields(Class<? extends ConfiguredObject> clazz)
{
if(!_allAutomatedFields.containsKey(clazz))
{
@@ -1426,4 +1569,66 @@ public abstract class AbstractConfiguredObject<X extends ConfiguredObject<X>> im
}
+ private class AttributeGettingHandler implements InvocationHandler
+ {
+ private Map<String,Object> _attributes;
+
+ AttributeGettingHandler(final Map<String, Object> modifiedAttributes)
+ {
+ Map<String,Object> combinedAttributes = new HashMap<String, Object>(getActualAttributes());
+ combinedAttributes.putAll(modifiedAttributes);
+ _attributes = combinedAttributes;
+ }
+
+ @Override
+ public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable
+ {
+
+ if(method.isAnnotationPresent(ManagedAttribute.class))
+ {
+ ConfiguredObjectAttribute attribute = getAttributeFromMethod(method);
+ return getValue(attribute);
+ }
+ else if(method.getName().equals("getAttribute") && args != null && args.length == 1 && args[0] instanceof String)
+ {
+ ConfiguredObjectAttribute attribute = _attributeTypes.get((String)args[0]);
+ if(attribute != null)
+ {
+ return getValue(attribute);
+ }
+ else
+ {
+ return null;
+ }
+ }
+ throw new UnsupportedOperationException("This class is only intended for value validation, and only getters on managed attributes are permitted.");
+ }
+
+ protected Object getValue(final ConfiguredObjectAttribute attribute)
+ {
+ ManagedAttribute annotation = attribute.getAnnotation();
+ if(annotation.automate())
+ {
+ Object value = _attributes.get(attribute.getName());
+ return attribute.convert(value == null && !"".equals(annotation.defaultValue()) ? annotation.defaultValue() : value , AbstractConfiguredObject.this);
+ }
+ else
+ {
+ return _attributes.get(attribute.getName());
+ }
+ }
+
+ private ConfiguredObjectAttribute getAttributeFromMethod(final Method method)
+ {
+ for(ConfiguredObjectAttribute attribute : _attributeTypes.values())
+ {
+ if(attribute.getGetter().getName().equals(method.getName())
+ && !Modifier.isStatic(method.getModifiers()))
+ {
+ return attribute;
+ }
+ }
+ throw new ServerScopedRuntimeException("Unable to find attribute definition for method " + method.getName());
+ }
+ }
}
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/AuthenticationProvider.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/AuthenticationProvider.java
index 8f40ca4060..4c8b5bd083 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/AuthenticationProvider.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/AuthenticationProvider.java
@@ -20,9 +20,14 @@
*/
package org.apache.qpid.server.model;
+import java.security.Principal;
import java.util.Collection;
+import javax.security.sasl.SaslException;
+import javax.security.sasl.SaslServer;
+
import org.apache.qpid.server.security.SubjectCreator;
+import org.apache.qpid.server.security.auth.AuthenticationResult;
@ManagedObject( creatable = false )
public interface AuthenticationProvider<X extends AuthenticationProvider<X>> extends ConfiguredObject<X>
@@ -55,4 +60,44 @@ public interface AuthenticationProvider<X extends AuthenticationProvider<X>> ext
void setPreferencesProvider(PreferencesProvider preferencesProvider);
void recoverUser(User user);
+
+ /**
+ * Gets the SASL mechanisms known to this manager.
+ *
+ * @return SASL mechanism names, space separated.
+ */
+ String getMechanisms();
+
+ /**
+ * Creates a SASL server for the specified mechanism name for the given
+ * fully qualified domain name.
+ *
+ * @param mechanism mechanism name
+ * @param localFQDN domain name
+ * @param externalPrincipal externally authenticated Principal
+ * @return SASL server
+ * @throws javax.security.sasl.SaslException
+ */
+ SaslServer createSaslServer(String mechanism, String localFQDN, Principal externalPrincipal) throws SaslException;
+
+ /**
+ * Authenticates a user using SASL negotiation.
+ *
+ * @param server SASL server
+ * @param response SASL response to process
+ *
+ * @return authentication result
+ */
+ AuthenticationResult authenticate(SaslServer server, byte[] response);
+
+ /**
+ * Authenticates a user using their username and password.
+ *
+ * @param username username
+ * @param password password
+ *
+ * @return authentication result
+ */
+ AuthenticationResult authenticate(String username, String password);
+
}
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 5700f20356..aabcc5844e 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
@@ -32,7 +32,7 @@ import org.apache.qpid.server.security.SubjectCreator;
import org.apache.qpid.server.stats.StatisticsGatherer;
import org.apache.qpid.server.virtualhost.VirtualHostRegistry;
-@ManagedObject( defaultType = "adapter" )
+@ManagedObject( defaultType = "broker" )
public interface Broker<X extends Broker<X>> extends ConfiguredObject<X>, EventLoggerProvider, StatisticsGatherer
{
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/ExternalFileBasedAuthenticationManager.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/ExternalFileBasedAuthenticationManager.java
new file mode 100644
index 0000000000..54d69fe516
--- /dev/null
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/ExternalFileBasedAuthenticationManager.java
@@ -0,0 +1,27 @@
+/*
+ *
+ * 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.model;
+
+public interface ExternalFileBasedAuthenticationManager<X extends ExternalFileBasedAuthenticationManager<X>> extends PasswordCredentialManagingAuthenticationProvider<X>
+{
+ @ManagedAttribute( automate = true , mandatory = true )
+ public String getPath();
+}
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/ManagedAttributeField.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/ManagedAttributeField.java
index c9b2f44b18..89cf32f252 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/ManagedAttributeField.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/ManagedAttributeField.java
@@ -27,4 +27,6 @@ import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface ManagedAttributeField
{
+ String beforeSet() default "";
+ String afterSet() default "";
}
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/Model.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/Model.java
index 36049950e7..39f26887a6 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/Model.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/Model.java
@@ -74,21 +74,40 @@ public abstract class Model
public static String getType(final Class<? extends ConfiguredObject> clazz)
{
- ManagedObject annotation = clazz.getAnnotation(ManagedObject.class);
- if(annotation != null)
+ String type = getActualType(clazz);
+
+ if("".equals(type))
{
- if(!"".equals(annotation.type()))
+ Class<? extends ConfiguredObject> category = getCategory(clazz);
+ if (category == null)
{
- return annotation.type();
+ throw new IllegalArgumentException("No category for " + clazz.getSimpleName());
+ }
+ ManagedObject annotation = category.getAnnotation(ManagedObject.class);
+ if (annotation == null)
+ {
+ throw new NullPointerException("No definition found for category " + category.getSimpleName());
+ }
+ if (!"".equals(annotation.defaultType()))
+ {
+ type = annotation.defaultType();
+ }
+ else
+ {
+ type = category.getSimpleName();
}
}
+ return type;
+ }
- if(clazz.getSuperclass() != null && ConfiguredObject.class.isAssignableFrom(clazz.getSuperclass()))
+ private static String getActualType(final Class<? extends ConfiguredObject> clazz)
+ {
+ ManagedObject annotation = clazz.getAnnotation(ManagedObject.class);
+ if(annotation != null)
{
- String type = getType((Class<? extends ConfiguredObject>) clazz.getSuperclass());
- if(!"".equals(type))
+ if(!"".equals(annotation.type()))
{
- return type;
+ return annotation.type();
}
}
@@ -96,34 +115,30 @@ public abstract class Model
{
if(ConfiguredObject.class.isAssignableFrom(iface))
{
- String type = getType((Class<? extends ConfiguredObject>) iface);
+ String type = getActualType((Class<? extends ConfiguredObject>) iface);
if(!"".equals(type))
{
return type;
}
}
}
- Class<? extends ConfiguredObject> category = getCategory(clazz);
- if(category == null)
- {
- return "";
- }
- annotation = category.getAnnotation(ManagedObject.class);
- if(annotation == null)
- {
- throw new NullPointerException("No definition found for category " + category.getSimpleName());
- }
- if(!"".equals(annotation.defaultType()))
+
+ if(clazz.getSuperclass() != null && ConfiguredObject.class.isAssignableFrom(clazz.getSuperclass()))
{
- return annotation.defaultType();
+ String type = getActualType((Class<? extends ConfiguredObject>) clazz.getSuperclass());
+ if(!"".equals(type))
+ {
+ return type;
+ }
}
- return category.getSimpleName();
+
+ return "";
}
public abstract Collection<Class<? extends ConfiguredObject>> getSupportedCategories();
public abstract Collection<Class<? extends ConfiguredObject>> getChildTypes(Class<? extends ConfiguredObject> parent);
- public abstract Class<? extends ConfiguredObject<?>> getRootCategory();
+ public abstract Class<? extends ConfiguredObject> getRootCategory();
public abstract Collection<Class<? extends ConfiguredObject>> getParentTypes(Class<? extends ConfiguredObject> child);
public abstract int getMajorVersion();
@@ -141,11 +156,11 @@ public abstract class Model
private final Set<Class<? extends ConfiguredObject>> _supportedTypes =
new HashSet<Class<? extends ConfiguredObject>>();
- private final Class<? extends ConfiguredObject<?>> _rootCategory;
+ private Class<? extends ConfiguredObject> _rootCategory;
private ModelImpl()
{
- _rootCategory = SystemContext.class;
+ setRootCategory(SystemContext.class);
addRelationship(SystemContext.class, Broker.class);
@@ -186,7 +201,7 @@ public abstract class Model
}
@Override
- public Class<? extends ConfiguredObject<?>> getRootCategory()
+ public Class<? extends ConfiguredObject> getRootCategory()
{
return _rootCategory;
}
@@ -223,6 +238,11 @@ public abstract class Model
return Collections.unmodifiableSet(_supportedTypes);
}
+ public void setRootCategory(final Class<? extends ConfiguredObject> rootCategory)
+ {
+ _rootCategory = rootCategory;
+ }
+
private void addRelationship(Class<? extends ConfiguredObject> parent, Class<? extends ConfiguredObject> child)
{
Collection<Class<? extends ConfiguredObject>> parents = _parents.get(child);
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/SystemContext.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/SystemContext.java
index dda65d2b3e..6e0f331d5e 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/SystemContext.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/SystemContext.java
@@ -20,307 +20,34 @@
*/
package org.apache.qpid.server.model;
-import java.security.AccessControlException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.UUID;
-
import org.apache.qpid.server.BrokerOptions;
-import org.apache.qpid.server.configuration.IllegalConfigurationException;
import org.apache.qpid.server.configuration.updater.TaskExecutor;
import org.apache.qpid.server.logging.EventLogger;
import org.apache.qpid.server.logging.LogRecorder;
-import org.apache.qpid.server.logging.messages.BrokerMessages;
-import org.apache.qpid.server.store.ConfiguredObjectDependency;
-import org.apache.qpid.server.store.ConfiguredObjectIdDependency;
-import org.apache.qpid.server.store.ConfiguredObjectNameDependency;
import org.apache.qpid.server.store.ConfiguredObjectRecord;
-import org.apache.qpid.server.store.UnresolvedConfiguredObject;
-import org.apache.qpid.server.util.ServerScopedRuntimeException;
@ManagedObject (creatable = false)
-public class SystemContext extends AbstractConfiguredObject<SystemContext>
+public interface SystemContext<X extends SystemContext<X>> extends ConfiguredObject<X>
{
- private static final UUID SYSTEM_ID = new UUID(0l, 0l);
- private final ConfiguredObjectFactory _objectFactory;
- private final EventLogger _eventLogger;
- private final LogRecorder _logRecorder;
- private final BrokerOptions _brokerOptions;
-
- @ManagedAttributeField
- private String _storePath;
-
- @ManagedAttributeField
- private String _storeType;
-
- public SystemContext(final TaskExecutor taskExecutor,
- final ConfiguredObjectFactory configuredObjectFactory,
- final EventLogger eventLogger,
- final LogRecorder logRecorder,
- final BrokerOptions brokerOptions)
- {
- super(parentsMap(),
- combineIdWithAttributes(SYSTEM_ID, createAttributes(brokerOptions)),
- taskExecutor);
- _eventLogger = eventLogger;
- getTaskExecutor().start();
- _objectFactory = configuredObjectFactory;
- _logRecorder = logRecorder;
- _brokerOptions = brokerOptions;
- open();
- }
-
- public static Map<String, Object> createAttributes(final BrokerOptions brokerOptions)
- {
- Map<String,Object> attributes = new HashMap<String, Object>();
- attributes.put(NAME, "System");
- attributes.put("storePath", brokerOptions.getConfigurationStoreLocation());
- attributes.put("storeTye", brokerOptions.getConfigurationStoreType());
- attributes.put(ConfiguredObject.CONTEXT, brokerOptions.getConfigProperties());
- return attributes;
- }
-
- public void resolveObjects(ConfiguredObjectRecord... records)
- {
-
- ConfiguredObjectFactory factory = getObjectFactory();
-
- Map<UUID, ConfiguredObject<?>> resolvedObjects = new HashMap<UUID, ConfiguredObject<?>>();
- resolvedObjects.put(getId(), this);
-
- Collection<ConfiguredObjectRecord> recordsWithUnresolvedParents = new ArrayList<ConfiguredObjectRecord>(Arrays.asList(records));
- Collection<UnresolvedConfiguredObject<? extends ConfiguredObject>> recordsWithUnresolvedDependencies =
- new ArrayList<UnresolvedConfiguredObject<? extends ConfiguredObject>>();
-
- boolean updatesMade;
-
- do
- {
- updatesMade = false;
- Iterator<ConfiguredObjectRecord> iter = recordsWithUnresolvedParents.iterator();
- while (iter.hasNext())
- {
- ConfiguredObjectRecord record = iter.next();
- Collection<ConfiguredObject<?>> parents = new ArrayList<ConfiguredObject<?>>();
- boolean foundParents = true;
- for (ConfiguredObjectRecord parent : record.getParents().values())
- {
- if (!resolvedObjects.containsKey(parent.getId()))
- {
- foundParents = false;
- break;
- }
- else
- {
- parents.add(resolvedObjects.get(parent.getId()));
- }
- }
- if (foundParents)
- {
- iter.remove();
- UnresolvedConfiguredObject<? extends ConfiguredObject> recovered =
- factory.recover(record, parents.toArray(new ConfiguredObject<?>[parents.size()]));
- Collection<ConfiguredObjectDependency<?>> dependencies =
- recovered.getUnresolvedDependencies();
- if (dependencies.isEmpty())
- {
- updatesMade = true;
- ConfiguredObject<?> resolved = recovered.resolve();
- resolvedObjects.put(resolved.getId(), resolved);
- }
- else
- {
- recordsWithUnresolvedDependencies.add(recovered);
- }
- }
-
- }
-
- Iterator<UnresolvedConfiguredObject<? extends ConfiguredObject>> unresolvedIter =
- recordsWithUnresolvedDependencies.iterator();
-
- while(unresolvedIter.hasNext())
- {
- UnresolvedConfiguredObject<? extends ConfiguredObject> unresolvedObject = unresolvedIter.next();
- Collection<ConfiguredObjectDependency<?>> dependencies =
- new ArrayList<ConfiguredObjectDependency<?>>(unresolvedObject.getUnresolvedDependencies());
-
- for(ConfiguredObjectDependency dependency : dependencies)
- {
- if(dependency instanceof ConfiguredObjectIdDependency)
- {
- UUID id = ((ConfiguredObjectIdDependency)dependency).getId();
- if(resolvedObjects.containsKey(id))
- {
- dependency.resolve(resolvedObjects.get(id));
- }
- }
- else if(dependency instanceof ConfiguredObjectNameDependency)
- {
- ConfiguredObject<?> dependentObject = null;
- for(ConfiguredObject<?> parent : unresolvedObject.getParents())
- {
- dependentObject = parent.findConfiguredObject(dependency.getCategoryClass(), ((ConfiguredObjectNameDependency)dependency).getName());
- if(dependentObject != null)
- {
- break;
- }
- }
- if(dependentObject != null)
- {
- dependency.resolve(dependentObject);
- }
- }
- else
- {
- throw new ServerScopedRuntimeException("Unknown dependency type " + dependency.getClass().getSimpleName());
- }
- }
- if(unresolvedObject.getUnresolvedDependencies().isEmpty())
- {
- updatesMade = true;
- unresolvedIter.remove();
- ConfiguredObject<?> resolved = unresolvedObject.resolve();
- resolvedObjects.put(resolved.getId(), resolved);
- }
- }
+ void resolveObjects(ConfiguredObjectRecord... records);
- } while(updatesMade && !(recordsWithUnresolvedDependencies.isEmpty() && recordsWithUnresolvedParents.isEmpty()));
+ ConfiguredObjectFactory getObjectFactory();
- if(!recordsWithUnresolvedDependencies.isEmpty())
- {
- throw new IllegalArgumentException("Cannot resolve some objects: " + recordsWithUnresolvedDependencies);
- }
- if(!recordsWithUnresolvedParents.isEmpty())
- {
- throw new IllegalArgumentException("Cannot resolve object because their parents cannot be found" + recordsWithUnresolvedParents);
- }
- }
+ EventLogger getEventLogger();
- @Override
- protected boolean setState(final State currentState, final State desiredState)
- {
- throw new IllegalArgumentException("Cannot change the state of the SystemContext object");
- }
-
- @Override
- public String setName(final String currentName, final String desiredName)
- throws IllegalStateException, AccessControlException
- {
- return null;
- }
-
- @Override
- public State getState()
- {
- return State.ACTIVE;
- }
-
- @Override
- public boolean isDurable()
- {
- return true;
- }
-
- @Override
- public void setDurable(final boolean durable)
- throws IllegalStateException, AccessControlException, IllegalArgumentException
- {
- throw new IllegalArgumentException("Cannot change the durability of the SystemContext object");
- }
-
- @Override
- public LifetimePolicy getLifetimePolicy()
- {
- return LifetimePolicy.PERMANENT;
- }
-
- @Override
- public LifetimePolicy setLifetimePolicy(final LifetimePolicy expected, final LifetimePolicy desired)
- throws IllegalStateException, AccessControlException, IllegalArgumentException
- {
- throw new IllegalArgumentException("Cannot change the lifetime of the SystemContext object");
- }
-
- public ConfiguredObjectFactory getObjectFactory()
- {
- return _objectFactory;
- }
-
- public EventLogger getEventLogger()
- {
- return _eventLogger;
- }
-
- public LogRecorder getLogRecorder()
- {
- return _logRecorder;
- }
-
- public BrokerOptions getBrokerOptions()
- {
- return _brokerOptions;
- }
+ BrokerOptions getBrokerOptions();
@ManagedAttribute( automate = true )
- public String getStorePath()
- {
- return _storePath;
- }
+ String getStorePath();
@ManagedAttribute( automate = true )
- public String getStoreType()
- {
- return _storeType;
- }
-
- public void close()
- {
- try
- {
-
-
- if (getTaskExecutor() != null)
- {
- getTaskExecutor().stop();
- }
-
- _eventLogger.message(BrokerMessages.STOPPED());
-
- _logRecorder.closeLogRecorder();
+ String getStoreType();
- }
- finally
- {
- if (getTaskExecutor() != null)
- {
- getTaskExecutor().stopImmediately();
- }
- }
+ void close();
- }
+ Broker getBroker();
- @Override
- public Collection<String> getAttributeNames()
- {
- return getAttributeNames(getClass());
- }
+ TaskExecutor getTaskExecutor();
- public Broker getBroker()
- {
- Collection<Broker> children = getChildren(Broker.class);
- if(children == null || children.isEmpty())
- {
- return null;
- }
- else if(children.size() != 1)
- {
- throw new IllegalConfigurationException("More than one broker has been registered in a single context");
- }
- return children.iterator().next();
- }
+ LogRecorder getLogRecorder();
}
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/SystemContextImpl.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/SystemContextImpl.java
new file mode 100644
index 0000000000..b4af364634
--- /dev/null
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/SystemContextImpl.java
@@ -0,0 +1,331 @@
+/*
+ *
+ * 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.model;
+
+import java.security.AccessControlException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.UUID;
+
+import org.apache.qpid.server.BrokerOptions;
+import org.apache.qpid.server.configuration.IllegalConfigurationException;
+import org.apache.qpid.server.configuration.updater.TaskExecutor;
+import org.apache.qpid.server.logging.EventLogger;
+import org.apache.qpid.server.logging.LogRecorder;
+import org.apache.qpid.server.logging.messages.BrokerMessages;
+import org.apache.qpid.server.store.ConfiguredObjectDependency;
+import org.apache.qpid.server.store.ConfiguredObjectIdDependency;
+import org.apache.qpid.server.store.ConfiguredObjectNameDependency;
+import org.apache.qpid.server.store.ConfiguredObjectRecord;
+import org.apache.qpid.server.store.UnresolvedConfiguredObject;
+import org.apache.qpid.server.util.ServerScopedRuntimeException;
+
+public class SystemContextImpl extends AbstractConfiguredObject<SystemContextImpl> implements SystemContext<SystemContextImpl>
+{
+ private static final UUID SYSTEM_ID = new UUID(0l, 0l);
+ private final ConfiguredObjectFactory _objectFactory;
+ private final EventLogger _eventLogger;
+ private final LogRecorder _logRecorder;
+ private final BrokerOptions _brokerOptions;
+
+ @ManagedAttributeField
+ private String _storePath;
+
+ @ManagedAttributeField
+ private String _storeType;
+
+ public SystemContextImpl(final TaskExecutor taskExecutor,
+ final ConfiguredObjectFactory configuredObjectFactory,
+ final EventLogger eventLogger,
+ final LogRecorder logRecorder,
+ final BrokerOptions brokerOptions)
+ {
+ super(parentsMap(),
+ combineIdWithAttributes(SYSTEM_ID, createAttributes(brokerOptions)),
+ taskExecutor);
+ _eventLogger = eventLogger;
+ getTaskExecutor().start();
+ _objectFactory = configuredObjectFactory;
+ _logRecorder = logRecorder;
+ _brokerOptions = brokerOptions;
+ open();
+ }
+
+ public static Map<String, Object> createAttributes(final BrokerOptions brokerOptions)
+ {
+ Map<String,Object> attributes = new HashMap<String, Object>();
+ attributes.put(NAME, "System");
+ attributes.put("storePath", brokerOptions.getConfigurationStoreLocation());
+ attributes.put("storeTye", brokerOptions.getConfigurationStoreType());
+ attributes.put(ConfiguredObject.CONTEXT, brokerOptions.getConfigProperties());
+ return attributes;
+ }
+
+ @Override
+ public void resolveObjects(ConfiguredObjectRecord... records)
+ {
+
+ ConfiguredObjectFactory factory = getObjectFactory();
+
+ Map<UUID, ConfiguredObject<?>> resolvedObjects = new HashMap<UUID, ConfiguredObject<?>>();
+ resolvedObjects.put(getId(), this);
+
+ Collection<ConfiguredObjectRecord> recordsWithUnresolvedParents = new ArrayList<ConfiguredObjectRecord>(Arrays.asList(records));
+ Collection<UnresolvedConfiguredObject<? extends ConfiguredObject>> recordsWithUnresolvedDependencies =
+ new ArrayList<UnresolvedConfiguredObject<? extends ConfiguredObject>>();
+
+ boolean updatesMade;
+
+ do
+ {
+ updatesMade = false;
+ Iterator<ConfiguredObjectRecord> iter = recordsWithUnresolvedParents.iterator();
+ while (iter.hasNext())
+ {
+ ConfiguredObjectRecord record = iter.next();
+ Collection<ConfiguredObject<?>> parents = new ArrayList<ConfiguredObject<?>>();
+ boolean foundParents = true;
+ for (ConfiguredObjectRecord parent : record.getParents().values())
+ {
+ if (!resolvedObjects.containsKey(parent.getId()))
+ {
+ foundParents = false;
+ break;
+ }
+ else
+ {
+ parents.add(resolvedObjects.get(parent.getId()));
+ }
+ }
+ if (foundParents)
+ {
+ iter.remove();
+ UnresolvedConfiguredObject<? extends ConfiguredObject> recovered =
+ factory.recover(record, parents.toArray(new ConfiguredObject<?>[parents.size()]));
+ Collection<ConfiguredObjectDependency<?>> dependencies =
+ recovered.getUnresolvedDependencies();
+ if (dependencies.isEmpty())
+ {
+ updatesMade = true;
+ ConfiguredObject<?> resolved = recovered.resolve();
+ resolvedObjects.put(resolved.getId(), resolved);
+ }
+ else
+ {
+ recordsWithUnresolvedDependencies.add(recovered);
+ }
+ }
+
+ }
+
+ Iterator<UnresolvedConfiguredObject<? extends ConfiguredObject>> unresolvedIter =
+ recordsWithUnresolvedDependencies.iterator();
+
+ while(unresolvedIter.hasNext())
+ {
+ UnresolvedConfiguredObject<? extends ConfiguredObject> unresolvedObject = unresolvedIter.next();
+ Collection<ConfiguredObjectDependency<?>> dependencies =
+ new ArrayList<ConfiguredObjectDependency<?>>(unresolvedObject.getUnresolvedDependencies());
+
+ for(ConfiguredObjectDependency dependency : dependencies)
+ {
+ if(dependency instanceof ConfiguredObjectIdDependency)
+ {
+ UUID id = ((ConfiguredObjectIdDependency)dependency).getId();
+ if(resolvedObjects.containsKey(id))
+ {
+ dependency.resolve(resolvedObjects.get(id));
+ }
+ }
+ else if(dependency instanceof ConfiguredObjectNameDependency)
+ {
+ ConfiguredObject<?> dependentObject = null;
+ for(ConfiguredObject<?> parent : unresolvedObject.getParents())
+ {
+ dependentObject = parent.findConfiguredObject(dependency.getCategoryClass(), ((ConfiguredObjectNameDependency)dependency).getName());
+ if(dependentObject != null)
+ {
+ break;
+ }
+ }
+ if(dependentObject != null)
+ {
+ dependency.resolve(dependentObject);
+ }
+ }
+ else
+ {
+ throw new ServerScopedRuntimeException("Unknown dependency type " + dependency.getClass().getSimpleName());
+ }
+ }
+ if(unresolvedObject.getUnresolvedDependencies().isEmpty())
+ {
+ updatesMade = true;
+ unresolvedIter.remove();
+ ConfiguredObject<?> resolved = unresolvedObject.resolve();
+ resolvedObjects.put(resolved.getId(), resolved);
+ }
+ }
+
+ } while(updatesMade && !(recordsWithUnresolvedDependencies.isEmpty() && recordsWithUnresolvedParents.isEmpty()));
+
+ if(!recordsWithUnresolvedDependencies.isEmpty())
+ {
+ throw new IllegalArgumentException("Cannot resolve some objects: " + recordsWithUnresolvedDependencies);
+ }
+ if(!recordsWithUnresolvedParents.isEmpty())
+ {
+ throw new IllegalArgumentException("Cannot resolve object because their parents cannot be found" + recordsWithUnresolvedParents);
+ }
+ }
+
+ @Override
+ protected boolean setState(final State currentState, final State desiredState)
+ {
+ throw new IllegalArgumentException("Cannot change the state of the SystemContext object");
+ }
+
+ @Override
+ public String setName(final String currentName, final String desiredName)
+ throws IllegalStateException, AccessControlException
+ {
+ return null;
+ }
+
+ @Override
+ public State getState()
+ {
+ return State.ACTIVE;
+ }
+
+ @Override
+ public boolean isDurable()
+ {
+ return true;
+ }
+
+ @Override
+ public void setDurable(final boolean durable)
+ throws IllegalStateException, AccessControlException, IllegalArgumentException
+ {
+ throw new IllegalArgumentException("Cannot change the durability of the SystemContext object");
+ }
+
+ @Override
+ public LifetimePolicy getLifetimePolicy()
+ {
+ return LifetimePolicy.PERMANENT;
+ }
+
+ @Override
+ public LifetimePolicy setLifetimePolicy(final LifetimePolicy expected, final LifetimePolicy desired)
+ throws IllegalStateException, AccessControlException, IllegalArgumentException
+ {
+ throw new IllegalArgumentException("Cannot change the lifetime of the SystemContext object");
+ }
+
+ @Override
+ public ConfiguredObjectFactory getObjectFactory()
+ {
+ return _objectFactory;
+ }
+
+ @Override
+ public EventLogger getEventLogger()
+ {
+ return _eventLogger;
+ }
+
+ public LogRecorder getLogRecorder()
+ {
+ return _logRecorder;
+ }
+
+ @Override
+ public BrokerOptions getBrokerOptions()
+ {
+ return _brokerOptions;
+ }
+
+ @Override
+ public String getStorePath()
+ {
+ return _storePath;
+ }
+
+ @Override
+ public String getStoreType()
+ {
+ return _storeType;
+ }
+
+ @Override
+ public void close()
+ {
+ try
+ {
+
+
+ if (getTaskExecutor() != null)
+ {
+ getTaskExecutor().stop();
+ }
+
+ _eventLogger.message(BrokerMessages.STOPPED());
+
+ _logRecorder.closeLogRecorder();
+
+ }
+ finally
+ {
+ if (getTaskExecutor() != null)
+ {
+ getTaskExecutor().stopImmediately();
+ }
+ }
+
+ }
+
+ @Override
+ public Collection<String> getAttributeNames()
+ {
+ return getAttributeNames(getClass());
+ }
+
+ @Override
+ public Broker getBroker()
+ {
+ Collection<Broker> children = getChildren(Broker.class);
+ if(children == null || children.isEmpty())
+ {
+ return null;
+ }
+ else if(children.size() != 1)
+ {
+ throw new IllegalConfigurationException("More than one broker has been registered in a single context");
+ }
+ return children.iterator().next();
+ }
+}
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/AbstractPluginAdapter.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/AbstractPluginAdapter.java
index 4502a7e53f..1143ae0a4a 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/AbstractPluginAdapter.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/AbstractPluginAdapter.java
@@ -24,6 +24,7 @@ import java.security.AccessControlException;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
+import java.util.Set;
import java.util.UUID;
import org.apache.qpid.server.model.AbstractConfiguredObject;
@@ -130,16 +131,7 @@ public abstract class AbstractPluginAdapter<X extends Plugin<X>> extends Abstrac
}
@Override
- protected void authoriseSetAttribute(String name, Object expected, Object desired) throws AccessControlException
- {
- if (!_broker.getSecurityManager().authoriseConfiguringBroker(getName(), Plugin.class, Operation.UPDATE))
- {
- throw new AccessControlException("Setting of plugin attribute is denied");
- }
- }
-
- @Override
- protected void authoriseSetAttributes(Map<String, Object> attributes) throws AccessControlException
+ protected void authoriseSetAttributes(ConfiguredObject<?> modified, Set<String> attributes) throws AccessControlException
{
if (!_broker.getSecurityManager().authoriseConfiguringBroker(getName(), Plugin.class, Operation.UPDATE))
{
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 d8ad780be0..fb00ee7fb3 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
@@ -30,6 +30,7 @@ import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
+import java.util.Set;
import java.util.Timer;
import java.util.TimerTask;
import java.util.UUID;
@@ -48,8 +49,8 @@ import org.apache.qpid.server.logging.LogRecorder;
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.model.port.AmqpPort;
-import org.apache.qpid.server.model.port.PortWithAuthProvider;
import org.apache.qpid.server.plugin.ConfiguredObjectTypeFactory;
import org.apache.qpid.server.plugin.MessageStoreFactory;
import org.apache.qpid.server.security.SecurityManager;
@@ -63,7 +64,6 @@ import org.apache.qpid.server.virtualhost.VirtualHostImpl;
import org.apache.qpid.server.virtualhost.VirtualHostRegistry;
import org.apache.qpid.util.SystemUtils;
-@ManagedObject(category = false, type = "adapter")
public class BrokerAdapter extends AbstractConfiguredObject<BrokerAdapter> implements Broker<BrokerAdapter>, ConfigurationChangeListener, StatisticsGatherer, StatisticsGatherer.Source
{
private static final Logger LOGGER = Logger.getLogger(BrokerAdapter.class);
@@ -1136,9 +1136,9 @@ public class BrokerAdapter extends AbstractConfiguredObject<BrokerAdapter> imple
Collection<Port<?>> ports = getPorts();
for (Port<?> p : ports)
{
- if (p instanceof PortWithAuthProvider && inetSocketAddress.getPort() == p.getPort())
+ if (p instanceof AbstractPortWithAuthProvider && inetSocketAddress.getPort() == p.getPort())
{
- provider = ((PortWithAuthProvider<?>) p).getAuthenticationProvider();
+ provider = ((AbstractPortWithAuthProvider<?>) p).getAuthenticationProvider();
break;
}
}
@@ -1214,15 +1214,6 @@ public class BrokerAdapter extends AbstractConfiguredObject<BrokerAdapter> imple
}
@Override
- protected void authoriseSetAttribute(String name, Object expected, Object desired) throws AccessControlException
- {
- if (!_securityManager.authoriseConfiguringBroker(getName(), Broker.class, Operation.UPDATE))
- {
- throw new AccessControlException("Setting of broker attributes is denied");
- }
- }
-
- @Override
protected <C extends ConfiguredObject> void authoriseCreateChild(Class<C> childClass, Map<String, Object> attributes,
ConfiguredObject... otherParents) throws AccessControlException
{
@@ -1233,7 +1224,7 @@ public class BrokerAdapter extends AbstractConfiguredObject<BrokerAdapter> imple
}
@Override
- protected void authoriseSetAttributes(Map<String, Object> attributes) throws AccessControlException
+ protected void authoriseSetAttributes(ConfiguredObject<?> modified, Set<String> attributes) throws AccessControlException
{
if (!_securityManager.authoriseConfiguringBroker(getName(), Broker.class, Operation.UPDATE))
{
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapterFactory.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapterFactory.java
index 8bbe446dc3..ca28aa1a68 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapterFactory.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapterFactory.java
@@ -20,14 +20,14 @@
*/
package org.apache.qpid.server.model.adapter;
-import org.apache.qpid.server.model.AbstractConfiguredObjectTypeFactory;
-import org.apache.qpid.server.model.ConfiguredObject;
-import org.apache.qpid.server.model.SystemContext;
-
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
+import org.apache.qpid.server.model.AbstractConfiguredObjectTypeFactory;
+import org.apache.qpid.server.model.ConfiguredObject;
+import org.apache.qpid.server.model.SystemContext;
+
public class BrokerAdapterFactory extends AbstractConfiguredObjectTypeFactory<BrokerAdapter>
{
public BrokerAdapterFactory()
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/FileBasedGroupProvider.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/FileBasedGroupProvider.java
index 3578fba7a4..5dc47f04aa 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/FileBasedGroupProvider.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/FileBasedGroupProvider.java
@@ -1,4 +1,5 @@
/*
+ *
* 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
@@ -19,584 +20,13 @@
*/
package org.apache.qpid.server.model.adapter;
-import java.io.File;
-import java.io.IOException;
-import java.security.AccessControlException;
-import java.security.Principal;
-import java.util.*;
-import java.util.concurrent.atomic.AtomicReference;
-
-import org.apache.log4j.Logger;
-import org.apache.qpid.server.configuration.IllegalConfigurationException;
-import org.apache.qpid.server.model.*;
-import org.apache.qpid.server.configuration.updater.TaskExecutor;
-import org.apache.qpid.server.security.access.Operation;
-import org.apache.qpid.server.security.group.FileGroupManager;
-import org.apache.qpid.server.security.group.GroupManager;
-import org.apache.qpid.server.security.SecurityManager;
-import org.apache.qpid.server.util.MapValueConverter;
+import org.apache.qpid.server.model.GroupProvider;
+import org.apache.qpid.server.model.ManagedAttribute;
+import org.apache.qpid.server.model.ManagedObject;
@ManagedObject( category = false, type = "GroupFile" )
-public class FileBasedGroupProvider
- extends AbstractConfiguredObject<FileBasedGroupProvider> implements GroupProvider<FileBasedGroupProvider>
+public interface FileBasedGroupProvider<X extends FileBasedGroupProvider<X>> extends GroupProvider<X>
{
- private static Logger LOGGER = Logger.getLogger(FileBasedGroupProvider.class);
-
- private GroupManager _groupManager;
- private final Broker<?> _broker;
- private AtomicReference<State> _state;
-
- @ManagedAttributeField
- private String _path;
-
- public FileBasedGroupProvider(UUID id,
- Broker broker,
- Map<String, Object> attributes)
- {
- super(parentsMap(broker),
- combineIdWithAttributes(id, attributes), broker.getTaskExecutor());
-
-
- _broker = broker;
-
- State state = MapValueConverter.getEnumAttribute(State.class, STATE, attributes, State.INITIALISING);
- _state = new AtomicReference<State>(state);
- }
-
- public void validate()
- {
- Collection<GroupProvider<?>> groupProviders = _broker.getGroupProviders();
- for(GroupProvider<?> provider : groupProviders)
- {
- if(provider instanceof FileBasedGroupProvider && provider != this)
- {
- try
- {
- if(new File(getPath()).getCanonicalPath().equals(new File(((FileBasedGroupProvider)provider).getPath()).getCanonicalPath()))
- {
- throw new IllegalConfigurationException("Cannot have two group providers using the same file: " + getPath());
- }
- }
- catch (IOException e)
- {
- throw new IllegalArgumentException("Invalid path", e);
- }
- }
- }
- }
-
- protected void onOpen()
- {
- super.onOpen();
- if(_groupManager == null)
- {
- _groupManager = new FileGroupManager(getPath());
- }
- }
-
- @Override
- protected void onCreate()
- {
- super.onCreate();
- _groupManager = new FileGroupManager(getPath());
- _groupManager.onCreate();
- }
-
@ManagedAttribute( automate = true, mandatory = true)
- public String getPath()
- {
- return _path;
- }
-
- @Override
- public String setName(String currentName, String desiredName)
- throws IllegalStateException, AccessControlException
- {
- return null;
- }
-
- @Override
- public State getState()
- {
- return _state.get();
- }
-
- @Override
- public boolean isDurable()
- {
- return true;
- }
-
- @Override
- public void setDurable(boolean durable) throws IllegalStateException,
- AccessControlException, IllegalArgumentException
- {
- }
-
- @Override
- public LifetimePolicy getLifetimePolicy()
- {
- return LifetimePolicy.PERMANENT;
- }
-
- @Override
- public LifetimePolicy setLifetimePolicy(LifetimePolicy expected,
- LifetimePolicy desired) throws IllegalStateException,
- AccessControlException, IllegalArgumentException
- {
- return null;
- }
-
- @Override
- public Collection<String> getAttributeNames()
- {
- return getAttributeNames(getClass());
- }
-
- @Override
- public Object getAttribute(String name)
- {
- if (DURABLE.equals(name))
- {
- return true;
- }
- else if (LIFETIME_POLICY.equals(name))
- {
- return LifetimePolicy.PERMANENT;
- }
- else if (STATE.equals(name))
- {
- return getState();
- }
-
- return super.getAttribute(name);
- }
-
- @Override
- public <C extends ConfiguredObject> C addChild(Class<C> childClass,
- Map<String, Object> attributes, ConfiguredObject... otherParents)
- {
- if (childClass == Group.class)
- {
- String groupName = (String) attributes.get(Group.NAME);
-
- getSecurityManager().authoriseGroupOperation(Operation.CREATE, groupName);
- _groupManager.createGroup(groupName);
- Map<String,Object> attrMap = new HashMap<String, Object>();
- UUID id = UUIDGenerator.generateGroupUUID(getName(),groupName);
- attrMap.put(Group.ID, id);
- attrMap.put(Group.NAME, groupName);
- return (C) new GroupAdapter(attrMap, getTaskExecutor());
-
- }
-
- throw new IllegalArgumentException(
- "This group provider does not support creating children of type: "
- + childClass);
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public <C extends ConfiguredObject> Collection<C> getChildren(Class<C> clazz)
- {
- if (clazz == Group.class)
- {
- Set<Principal> groups = _groupManager == null ? Collections.<Principal>emptySet() : _groupManager.getGroupPrincipals();
- Collection<Group> principals = new ArrayList<Group>(groups.size());
- for (Principal group : groups)
- {
- Map<String,Object> attrMap = new HashMap<String, Object>();
- UUID id = UUIDGenerator.generateGroupUUID(getName(),group.getName());
- attrMap.put(Group.ID, id);
- attrMap.put(Group.NAME, group.getName());
- principals.add(new GroupAdapter(attrMap, getTaskExecutor()));
- }
- return (Collection<C>) Collections
- .unmodifiableCollection(principals);
- }
- else
- {
- return null;
- }
- }
-
- public GroupManager getGroupManager()
- {
- return _groupManager;
- }
-
- private SecurityManager getSecurityManager()
- {
- return _broker.getSecurityManager();
- }
-
- @Override
- protected boolean setState(State currentState, State desiredState)
- {
- State state = _state.get();
- if (desiredState == State.ACTIVE)
- {
- if ((state == State.INITIALISING || state == State.QUIESCED || state == State.STOPPED)
- && _state.compareAndSet(state, State.ACTIVE))
- {
- try
- {
- _groupManager.open();
- return true;
- }
- catch(RuntimeException e)
- {
- _state.compareAndSet(State.ACTIVE, State.ERRORED);
- if (_broker.isManagementMode())
- {
- LOGGER.warn("Failed to activate group provider: " + getName(), e);
- }
- else
- {
- throw e;
- }
- }
- }
- else
- {
- throw new IllegalStateException("Cannot activate group provider in state: " + state);
- }
- }
- else if (desiredState == State.STOPPED)
- {
- if (_state.compareAndSet(state, State.STOPPED))
- {
- _groupManager.close();
- return true;
- }
- else
- {
- throw new IllegalStateException("Cannot stop group provider in state: " + state);
- }
- }
- else if (desiredState == State.DELETED)
- {
- if ((state == State.INITIALISING || state == State.ACTIVE || state == State.STOPPED || state == State.QUIESCED || state == State.ERRORED)
- && _state.compareAndSet(state, State.DELETED))
- {
- _groupManager.close();
- _groupManager.onDelete();
- deleted();
- return true;
- }
- else
- {
- throw new IllegalStateException("Cannot delete group provider in state: " + state);
- }
- }
- else if (desiredState == State.QUIESCED)
- {
- if (state == State.INITIALISING && _state.compareAndSet(state, State.QUIESCED))
- {
- return true;
- }
- }
- return false;
- }
-
- public Set<Principal> getGroupPrincipalsForUser(String username)
- {
- return _groupManager.getGroupPrincipalsForUser(username);
- }
-
- @Override
- protected void childAdded(ConfiguredObject child)
- {
- // no-op, prevent storing groups in the broker store
- }
-
- @Override
- protected void childRemoved(ConfiguredObject child)
- {
- // no-op, as per above, groups are not in the store
- }
-
- @Override
- protected void authoriseSetDesiredState(State currentState, State desiredState) throws AccessControlException
- {
- if(desiredState == State.DELETED)
- {
- if (!_broker.getSecurityManager().authoriseConfiguringBroker(getName(), GroupProvider.class, Operation.DELETE))
- {
- throw new AccessControlException("Deletion of groups provider is denied");
- }
- }
- }
-
- @Override
- protected void authoriseSetAttribute(String name, Object expected, Object desired) throws AccessControlException
- {
- if (!_broker.getSecurityManager().authoriseConfiguringBroker(getName(), GroupProvider.class, Operation.UPDATE))
- {
- throw new AccessControlException("Setting of group provider attributes is denied");
- }
- }
-
- @Override
- protected void authoriseSetAttributes(Map<String, Object> attributes) throws AccessControlException
- {
- if (!_broker.getSecurityManager().authoriseConfiguringBroker(getName(), GroupProvider.class, Operation.UPDATE))
- {
- throw new AccessControlException("Setting of group provider attributes is denied");
- }
- }
-
- @Override
- protected void changeAttributes(Map<String, Object> attributes)
- {
- throw new UnsupportedOperationException("Changing attributes on group providers is not supported.");
- }
-
-
- private class GroupAdapter extends AbstractConfiguredObject<GroupAdapter> implements Group<GroupAdapter>
- {
-
- public GroupAdapter(Map<String,Object> attributes, TaskExecutor taskExecutor)
- {
- super(parentsMap(FileBasedGroupProvider.this), attributes, taskExecutor);
- }
-
-
- @Override
- public String setName(String currentName, String desiredName)
- throws IllegalStateException, AccessControlException
- {
- throw new IllegalStateException("Names cannot be updated");
- }
-
- @Override
- public State getState()
- {
- return State.ACTIVE;
- }
-
- @Override
- public boolean isDurable()
- {
- return true;
- }
-
- @Override
- public void setDurable(boolean durable) throws IllegalStateException,
- AccessControlException, IllegalArgumentException
- {
- throw new IllegalStateException("Durability cannot be updated");
- }
-
- @Override
- public LifetimePolicy getLifetimePolicy()
- {
- return LifetimePolicy.PERMANENT;
- }
-
- @Override
- public LifetimePolicy setLifetimePolicy(LifetimePolicy expected,
- LifetimePolicy desired) throws IllegalStateException,
- AccessControlException, IllegalArgumentException
- {
- throw new IllegalStateException("LifetimePolicy cannot be updated");
- }
-
- @Override
- public <C extends ConfiguredObject> Collection<C> getChildren(
- Class<C> clazz)
- {
- if (clazz == GroupMember.class)
- {
- Set<Principal> usersInGroup = _groupManager
- .getUserPrincipalsForGroup(getName());
- Collection<GroupMember> members = new ArrayList<GroupMember>();
- for (Principal principal : usersInGroup)
- {
- UUID id = UUIDGenerator.generateGroupMemberUUID(FileBasedGroupProvider.this.getName(), getName(), principal.getName());
- Map<String,Object> attrMap = new HashMap<String, Object>();
- attrMap.put(GroupMember.ID,id);
- attrMap.put(GroupMember.NAME, principal.getName());
- members.add(new GroupMemberAdapter(attrMap, getTaskExecutor()));
- }
- return (Collection<C>) Collections
- .unmodifiableCollection(members);
- }
- else
- {
- return null;
- }
-
- }
-
- @Override
- public <C extends ConfiguredObject> C addChild(Class<C> childClass,
- Map<String, Object> attributes,
- ConfiguredObject... otherParents)
- {
- if (childClass == GroupMember.class)
- {
- String memberName = (String) attributes.get(GroupMember.NAME);
-
- getSecurityManager().authoriseGroupOperation(Operation.UPDATE, getName());
-
- _groupManager.addUserToGroup(memberName, getName());
- UUID id = UUIDGenerator.generateGroupMemberUUID(FileBasedGroupProvider.this.getName(), getName(), memberName);
- Map<String,Object> attrMap = new HashMap<String, Object>();
- attrMap.put(GroupMember.ID,id);
- attrMap.put(GroupMember.NAME, memberName);
- return (C) new GroupMemberAdapter(attrMap, getTaskExecutor());
-
- }
-
- throw new IllegalArgumentException(
- "This group provider does not support creating children of type: "
- + childClass);
- }
-
- @Override
- public Collection<String> getAttributeNames()
- {
- return getAttributeNames(Group.class);
- }
-
- @Override
- public Object getAttribute(String name)
- {
- if (ID.equals(name))
- {
- return getId();
- }
- else if (NAME.equals(name))
- {
- return getName();
- }
- return super.getAttribute(name);
- }
-
- @Override
- protected boolean setState(State currentState, State desiredState)
- throws IllegalStateTransitionException, AccessControlException
- {
- if (desiredState == State.DELETED)
- {
- getSecurityManager().authoriseGroupOperation(Operation.DELETE, getName());
- _groupManager.removeGroup(getName());
- return true;
- }
-
- return false;
- }
-
- @Override
- public Object setAttribute(final String name, final Object expected, final Object desired) throws IllegalStateException,
- AccessControlException, IllegalArgumentException
- {
- throw new UnsupportedOperationException("Changing attributes on group is not supported.");
- }
-
- @Override
- public void setAttributes(final Map<String, Object> attributes) throws IllegalStateException, AccessControlException,
- IllegalArgumentException
- {
- throw new UnsupportedOperationException("Changing attributes on group is not supported.");
- }
-
- private class GroupMemberAdapter extends AbstractConfiguredObject<GroupMemberAdapter> implements
- GroupMember<GroupMemberAdapter>
- {
-
- public GroupMemberAdapter(Map<String,Object> attrMap, TaskExecutor taskExecutor)
- {
- // TODO - need to relate to the User object
- super(parentsMap(GroupAdapter.this),attrMap, taskExecutor);
- }
-
- @Override
- public Collection<String> getAttributeNames()
- {
- return getAttributeNames(GroupMember.class);
- }
-
-
- @Override
- public String setName(String currentName, String desiredName)
- throws IllegalStateException, AccessControlException
- {
- return null;
- }
-
- @Override
- public State getState()
- {
- return null;
- }
-
- @Override
- public boolean isDurable()
- {
- return false;
- }
-
- @Override
- public void setDurable(boolean durable)
- throws IllegalStateException, AccessControlException,
- IllegalArgumentException
- {
- }
-
- @Override
- public LifetimePolicy getLifetimePolicy()
- {
- return null;
- }
-
- @Override
- public LifetimePolicy setLifetimePolicy(LifetimePolicy expected,
- LifetimePolicy desired) throws IllegalStateException,
- AccessControlException, IllegalArgumentException
- {
- return null;
- }
-
- @Override
- public <C extends ConfiguredObject> Collection<C> getChildren(
- Class<C> clazz)
- {
- return null;
- }
-
- @Override
- protected boolean setState(State currentState, State desiredState)
- throws IllegalStateTransitionException,
- AccessControlException
- {
- if (desiredState == State.DELETED)
- {
- getSecurityManager().authoriseGroupOperation(Operation.UPDATE, GroupAdapter.this.getName());
-
- _groupManager.removeUserFromGroup(getName(), GroupAdapter.this.getName());
- return true;
-
- }
- return false;
- }
-
- @Override
- public Object setAttribute(final String name, final Object expected, final Object desired) throws IllegalStateException,
- AccessControlException, IllegalArgumentException
- {
- throw new UnsupportedOperationException("Changing attributes on group member is not supported.");
- }
-
- @Override
- public void setAttributes(final Map<String, Object> attributes) throws IllegalStateException, AccessControlException,
- IllegalArgumentException
- {
- throw new UnsupportedOperationException("Changing attributes on group member is not supported.");
- }
- }
- }
-
-
+ String getPath();
}
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/FileBasedGroupProviderFactory.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/FileBasedGroupProviderFactory.java
index 8d7ec4bff2..10673596a3 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/FileBasedGroupProviderFactory.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/FileBasedGroupProviderFactory.java
@@ -20,29 +20,29 @@
*/
package org.apache.qpid.server.model.adapter;
-import org.apache.qpid.server.model.AbstractConfiguredObjectTypeFactory;
-import org.apache.qpid.server.model.Broker;
-import org.apache.qpid.server.model.ConfiguredObject;
-
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
-public class FileBasedGroupProviderFactory extends AbstractConfiguredObjectTypeFactory<FileBasedGroupProvider>
+import org.apache.qpid.server.model.AbstractConfiguredObjectTypeFactory;
+import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.model.ConfiguredObject;
+
+public class FileBasedGroupProviderFactory extends AbstractConfiguredObjectTypeFactory<FileBasedGroupProviderImpl>
{
public FileBasedGroupProviderFactory()
{
- super(FileBasedGroupProvider.class);
+ super(FileBasedGroupProviderImpl.class);
}
@Override
- public FileBasedGroupProvider createInstance(final Map<String, Object> attributes,
+ public FileBasedGroupProviderImpl createInstance(final Map<String, Object> attributes,
final ConfiguredObject<?>... parents)
{
Map<String,Object> attributesWithoutId = new HashMap<String, Object>(attributes);
Object idObj = attributesWithoutId.remove(ConfiguredObject.ID);
UUID id = idObj == null ? UUID.randomUUID() : idObj instanceof UUID ? (UUID) idObj : UUID.fromString(idObj.toString());
- return new FileBasedGroupProvider(id, getParent(Broker.class, parents), attributesWithoutId);
+ return new FileBasedGroupProviderImpl(id, getParent(Broker.class, parents), attributesWithoutId);
}
}
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/FileBasedGroupProviderImpl.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/FileBasedGroupProviderImpl.java
new file mode 100644
index 0000000000..f80d043c02
--- /dev/null
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/FileBasedGroupProviderImpl.java
@@ -0,0 +1,592 @@
+/*
+ * 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.model.adapter;
+
+import java.io.File;
+import java.io.IOException;
+import java.security.AccessControlException;
+import java.security.Principal;
+import java.util.*;
+import java.util.concurrent.atomic.AtomicReference;
+
+import org.apache.log4j.Logger;
+import org.apache.qpid.server.configuration.IllegalConfigurationException;
+import org.apache.qpid.server.model.*;
+import org.apache.qpid.server.configuration.updater.TaskExecutor;
+import org.apache.qpid.server.security.access.Operation;
+import org.apache.qpid.server.security.group.FileGroupManager;
+import org.apache.qpid.server.security.group.GroupManager;
+import org.apache.qpid.server.security.SecurityManager;
+import org.apache.qpid.server.util.MapValueConverter;
+
+public class FileBasedGroupProviderImpl
+ extends AbstractConfiguredObject<FileBasedGroupProviderImpl> implements FileBasedGroupProvider<FileBasedGroupProviderImpl>
+{
+ private static Logger LOGGER = Logger.getLogger(FileBasedGroupProviderImpl.class);
+
+ private GroupManager _groupManager;
+ private final Broker<?> _broker;
+ private AtomicReference<State> _state;
+
+ @ManagedAttributeField
+ private String _path;
+
+ public FileBasedGroupProviderImpl(UUID id,
+ Broker broker,
+ Map<String, Object> attributes)
+ {
+ super(parentsMap(broker),
+ combineIdWithAttributes(id, attributes), broker.getTaskExecutor());
+
+
+ _broker = broker;
+
+ State state = MapValueConverter.getEnumAttribute(State.class, STATE, attributes, State.INITIALISING);
+ _state = new AtomicReference<State>(state);
+ }
+
+ public void validate()
+ {
+ Collection<GroupProvider<?>> groupProviders = _broker.getGroupProviders();
+ for(GroupProvider<?> provider : groupProviders)
+ {
+ if(provider instanceof FileBasedGroupProvider && provider != this)
+ {
+ try
+ {
+ if(new File(getPath()).getCanonicalPath().equals(new File(((FileBasedGroupProvider)provider).getPath()).getCanonicalPath()))
+ {
+ throw new IllegalConfigurationException("Cannot have two group providers using the same file: " + getPath());
+ }
+ }
+ catch (IOException e)
+ {
+ throw new IllegalArgumentException("Invalid path", e);
+ }
+ }
+ }
+ }
+
+ protected void onOpen()
+ {
+ super.onOpen();
+ if(_groupManager == null)
+ {
+ _groupManager = new FileGroupManager(getPath());
+ }
+ }
+
+ @Override
+ protected void onCreate()
+ {
+ super.onCreate();
+ _groupManager = new FileGroupManager(getPath());
+ _groupManager.onCreate();
+ }
+
+ @Override
+ public String getPath()
+ {
+ return _path;
+ }
+
+ @Override
+ public String setName(String currentName, String desiredName)
+ throws IllegalStateException, AccessControlException
+ {
+ return null;
+ }
+
+ @Override
+ public State getState()
+ {
+ return _state.get();
+ }
+
+ @Override
+ public boolean isDurable()
+ {
+ return true;
+ }
+
+ @Override
+ public void setDurable(boolean durable) throws IllegalStateException,
+ AccessControlException, IllegalArgumentException
+ {
+ }
+
+ @Override
+ public LifetimePolicy getLifetimePolicy()
+ {
+ return LifetimePolicy.PERMANENT;
+ }
+
+ @Override
+ public LifetimePolicy setLifetimePolicy(LifetimePolicy expected,
+ LifetimePolicy desired) throws IllegalStateException,
+ AccessControlException, IllegalArgumentException
+ {
+ return null;
+ }
+
+ @Override
+ public Collection<String> getAttributeNames()
+ {
+ return getAttributeNames(getClass());
+ }
+
+ @Override
+ public Object getAttribute(String name)
+ {
+ if (DURABLE.equals(name))
+ {
+ return true;
+ }
+ else if (LIFETIME_POLICY.equals(name))
+ {
+ return LifetimePolicy.PERMANENT;
+ }
+ else if (STATE.equals(name))
+ {
+ return getState();
+ }
+
+ return super.getAttribute(name);
+ }
+
+ @Override
+ public <C extends ConfiguredObject> C addChild(Class<C> childClass,
+ Map<String, Object> attributes, ConfiguredObject... otherParents)
+ {
+ if (childClass == Group.class)
+ {
+ String groupName = (String) attributes.get(Group.NAME);
+
+ getSecurityManager().authoriseGroupOperation(Operation.CREATE, groupName);
+ _groupManager.createGroup(groupName);
+ Map<String,Object> attrMap = new HashMap<String, Object>();
+ UUID id = UUIDGenerator.generateGroupUUID(getName(),groupName);
+ attrMap.put(Group.ID, id);
+ attrMap.put(Group.NAME, groupName);
+ return (C) new GroupAdapter(attrMap, getTaskExecutor());
+
+ }
+
+ throw new IllegalArgumentException(
+ "This group provider does not support creating children of type: "
+ + childClass);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public <C extends ConfiguredObject> Collection<C> getChildren(Class<C> clazz)
+ {
+ if (clazz == Group.class)
+ {
+ Set<Principal> groups = _groupManager == null ? Collections.<Principal>emptySet() : _groupManager.getGroupPrincipals();
+ Collection<Group> principals = new ArrayList<Group>(groups.size());
+ for (Principal group : groups)
+ {
+ Map<String,Object> attrMap = new HashMap<String, Object>();
+ UUID id = UUIDGenerator.generateGroupUUID(getName(),group.getName());
+ attrMap.put(Group.ID, id);
+ attrMap.put(Group.NAME, group.getName());
+ principals.add(new GroupAdapter(attrMap, getTaskExecutor()));
+ }
+ return (Collection<C>) Collections
+ .unmodifiableCollection(principals);
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ public GroupManager getGroupManager()
+ {
+ return _groupManager;
+ }
+
+ private SecurityManager getSecurityManager()
+ {
+ return _broker.getSecurityManager();
+ }
+
+ @Override
+ protected boolean setState(State currentState, State desiredState)
+ {
+ State state = _state.get();
+ if (desiredState == State.ACTIVE)
+ {
+ if ((state == State.INITIALISING || state == State.QUIESCED || state == State.STOPPED)
+ && _state.compareAndSet(state, State.ACTIVE))
+ {
+ try
+ {
+ _groupManager.open();
+ return true;
+ }
+ catch(RuntimeException e)
+ {
+ _state.compareAndSet(State.ACTIVE, State.ERRORED);
+ if (_broker.isManagementMode())
+ {
+ LOGGER.warn("Failed to activate group provider: " + getName(), e);
+ }
+ else
+ {
+ throw e;
+ }
+ }
+ }
+ else
+ {
+ throw new IllegalStateException("Cannot activate group provider in state: " + state);
+ }
+ }
+ else if (desiredState == State.STOPPED)
+ {
+ if (_state.compareAndSet(state, State.STOPPED))
+ {
+ _groupManager.close();
+ return true;
+ }
+ else
+ {
+ throw new IllegalStateException("Cannot stop group provider in state: " + state);
+ }
+ }
+ else if (desiredState == State.DELETED)
+ {
+ if ((state == State.INITIALISING || state == State.ACTIVE || state == State.STOPPED || state == State.QUIESCED || state == State.ERRORED)
+ && _state.compareAndSet(state, State.DELETED))
+ {
+ _groupManager.close();
+ _groupManager.onDelete();
+ deleted();
+ return true;
+ }
+ else
+ {
+ throw new IllegalStateException("Cannot delete group provider in state: " + state);
+ }
+ }
+ else if (desiredState == State.QUIESCED)
+ {
+ if (state == State.INITIALISING && _state.compareAndSet(state, State.QUIESCED))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public Set<Principal> getGroupPrincipalsForUser(String username)
+ {
+ return _groupManager.getGroupPrincipalsForUser(username);
+ }
+
+ @Override
+ protected void childAdded(ConfiguredObject child)
+ {
+ // no-op, prevent storing groups in the broker store
+ }
+
+ @Override
+ protected void childRemoved(ConfiguredObject child)
+ {
+ // no-op, as per above, groups are not in the store
+ }
+
+ @Override
+ protected void authoriseSetDesiredState(State currentState, State desiredState) throws AccessControlException
+ {
+ if(desiredState == State.DELETED)
+ {
+ if (!_broker.getSecurityManager().authoriseConfiguringBroker(getName(), GroupProvider.class, Operation.DELETE))
+ {
+ throw new AccessControlException("Deletion of groups provider is denied");
+ }
+ }
+ }
+
+ @Override
+ protected void authoriseSetAttributes(ConfiguredObject<?> modified, Set<String> attributes) throws AccessControlException
+ {
+ if (!_broker.getSecurityManager().authoriseConfiguringBroker(getName(), GroupProvider.class, Operation.UPDATE))
+ {
+ throw new AccessControlException("Setting of group provider attributes is denied");
+ }
+ }
+
+ @Override
+ protected void changeAttributes(Map<String, Object> attributes)
+ {
+ throw new UnsupportedOperationException("Changing attributes on group providers is not supported.");
+ }
+
+
+ private class GroupAdapter extends AbstractConfiguredObject<GroupAdapter> implements Group<GroupAdapter>
+ {
+
+ public GroupAdapter(Map<String,Object> attributes, TaskExecutor taskExecutor)
+ {
+ super(parentsMap(FileBasedGroupProviderImpl.this), attributes, taskExecutor);
+ }
+
+
+ @Override
+ public String setName(String currentName, String desiredName)
+ throws IllegalStateException, AccessControlException
+ {
+ throw new IllegalStateException("Names cannot be updated");
+ }
+
+ @Override
+ public State getState()
+ {
+ return State.ACTIVE;
+ }
+
+ @Override
+ public boolean isDurable()
+ {
+ return true;
+ }
+
+ @Override
+ public void setDurable(boolean durable) throws IllegalStateException,
+ AccessControlException, IllegalArgumentException
+ {
+ throw new IllegalStateException("Durability cannot be updated");
+ }
+
+ @Override
+ public LifetimePolicy getLifetimePolicy()
+ {
+ return LifetimePolicy.PERMANENT;
+ }
+
+ @Override
+ public LifetimePolicy setLifetimePolicy(LifetimePolicy expected,
+ LifetimePolicy desired) throws IllegalStateException,
+ AccessControlException, IllegalArgumentException
+ {
+ throw new IllegalStateException("LifetimePolicy cannot be updated");
+ }
+
+ @Override
+ public <C extends ConfiguredObject> Collection<C> getChildren(
+ Class<C> clazz)
+ {
+ if (clazz == GroupMember.class)
+ {
+ Set<Principal> usersInGroup = _groupManager
+ .getUserPrincipalsForGroup(getName());
+ Collection<GroupMember> members = new ArrayList<GroupMember>();
+ for (Principal principal : usersInGroup)
+ {
+ UUID id = UUIDGenerator.generateGroupMemberUUID(FileBasedGroupProviderImpl.this.getName(), getName(), principal.getName());
+ Map<String,Object> attrMap = new HashMap<String, Object>();
+ attrMap.put(GroupMember.ID,id);
+ attrMap.put(GroupMember.NAME, principal.getName());
+ members.add(new GroupMemberAdapter(attrMap, getTaskExecutor()));
+ }
+ return (Collection<C>) Collections
+ .unmodifiableCollection(members);
+ }
+ else
+ {
+ return null;
+ }
+
+ }
+
+ @Override
+ public <C extends ConfiguredObject> C addChild(Class<C> childClass,
+ Map<String, Object> attributes,
+ ConfiguredObject... otherParents)
+ {
+ if (childClass == GroupMember.class)
+ {
+ String memberName = (String) attributes.get(GroupMember.NAME);
+
+ getSecurityManager().authoriseGroupOperation(Operation.UPDATE, getName());
+
+ _groupManager.addUserToGroup(memberName, getName());
+ UUID id = UUIDGenerator.generateGroupMemberUUID(FileBasedGroupProviderImpl.this.getName(), getName(), memberName);
+ Map<String,Object> attrMap = new HashMap<String, Object>();
+ attrMap.put(GroupMember.ID,id);
+ attrMap.put(GroupMember.NAME, memberName);
+ return (C) new GroupMemberAdapter(attrMap, getTaskExecutor());
+
+ }
+
+ throw new IllegalArgumentException(
+ "This group provider does not support creating children of type: "
+ + childClass);
+ }
+
+ @Override
+ public Collection<String> getAttributeNames()
+ {
+ return getAttributeNames(Group.class);
+ }
+
+ @Override
+ public Object getAttribute(String name)
+ {
+ if (ID.equals(name))
+ {
+ return getId();
+ }
+ else if (NAME.equals(name))
+ {
+ return getName();
+ }
+ return super.getAttribute(name);
+ }
+
+ @Override
+ protected boolean setState(State currentState, State desiredState)
+ throws IllegalStateTransitionException, AccessControlException
+ {
+ if (desiredState == State.DELETED)
+ {
+ getSecurityManager().authoriseGroupOperation(Operation.DELETE, getName());
+ _groupManager.removeGroup(getName());
+ return true;
+ }
+
+ return false;
+ }
+
+ @Override
+ public Object setAttribute(final String name, final Object expected, final Object desired) throws IllegalStateException,
+ AccessControlException, IllegalArgumentException
+ {
+ throw new UnsupportedOperationException("Changing attributes on group is not supported.");
+ }
+
+ @Override
+ public void setAttributes(final Map<String, Object> attributes) throws IllegalStateException, AccessControlException,
+ IllegalArgumentException
+ {
+ throw new UnsupportedOperationException("Changing attributes on group is not supported.");
+ }
+
+ private class GroupMemberAdapter extends AbstractConfiguredObject<GroupMemberAdapter> implements
+ GroupMember<GroupMemberAdapter>
+ {
+
+ public GroupMemberAdapter(Map<String,Object> attrMap, TaskExecutor taskExecutor)
+ {
+ // TODO - need to relate to the User object
+ super(parentsMap(GroupAdapter.this),attrMap, taskExecutor);
+ }
+
+ @Override
+ public Collection<String> getAttributeNames()
+ {
+ return getAttributeNames(GroupMember.class);
+ }
+
+
+ @Override
+ public String setName(String currentName, String desiredName)
+ throws IllegalStateException, AccessControlException
+ {
+ return null;
+ }
+
+ @Override
+ public State getState()
+ {
+ return null;
+ }
+
+ @Override
+ public boolean isDurable()
+ {
+ return false;
+ }
+
+ @Override
+ public void setDurable(boolean durable)
+ throws IllegalStateException, AccessControlException,
+ IllegalArgumentException
+ {
+ }
+
+ @Override
+ public LifetimePolicy getLifetimePolicy()
+ {
+ return null;
+ }
+
+ @Override
+ public LifetimePolicy setLifetimePolicy(LifetimePolicy expected,
+ LifetimePolicy desired) throws IllegalStateException,
+ AccessControlException, IllegalArgumentException
+ {
+ return null;
+ }
+
+ @Override
+ public <C extends ConfiguredObject> Collection<C> getChildren(
+ Class<C> clazz)
+ {
+ return null;
+ }
+
+ @Override
+ protected boolean setState(State currentState, State desiredState)
+ throws IllegalStateTransitionException,
+ AccessControlException
+ {
+ if (desiredState == State.DELETED)
+ {
+ getSecurityManager().authoriseGroupOperation(Operation.UPDATE, GroupAdapter.this.getName());
+
+ _groupManager.removeUserFromGroup(getName(), GroupAdapter.this.getName());
+ return true;
+
+ }
+ return false;
+ }
+
+ @Override
+ public Object setAttribute(final String name, final Object expected, final Object desired) throws IllegalStateException,
+ AccessControlException, IllegalArgumentException
+ {
+ throw new UnsupportedOperationException("Changing attributes on group member is not supported.");
+ }
+
+ @Override
+ public void setAttributes(final Map<String, Object> attributes) throws IllegalStateException, AccessControlException,
+ IllegalArgumentException
+ {
+ throw new UnsupportedOperationException("Changing attributes on group member is not supported.");
+ }
+ }
+ }
+
+
+}
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/FileSystemPreferencesProvider.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/FileSystemPreferencesProvider.java
index b1df475322..42b93db3e7 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/FileSystemPreferencesProvider.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/FileSystemPreferencesProvider.java
@@ -18,577 +18,18 @@
* under the License.
*
*/
-
package org.apache.qpid.server.model.adapter;
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.IOException;
-import java.io.RandomAccessFile;
-import java.lang.reflect.Type;
-import java.nio.ByteBuffer;
-import java.nio.channels.FileChannel;
-import java.nio.channels.FileLock;
-import java.nio.channels.OverlappingFileLockException;
-import java.security.AccessControlException;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeMap;
-import java.util.UUID;
-import java.util.concurrent.atomic.AtomicReference;
-
-import org.apache.log4j.Logger;
-import org.codehaus.jackson.JsonParser;
-import org.codehaus.jackson.JsonProcessingException;
-import org.codehaus.jackson.map.ObjectMapper;
-import org.codehaus.jackson.map.SerializationConfig;
-import org.codehaus.jackson.type.TypeReference;
-
-import org.apache.qpid.server.configuration.IllegalConfigurationException;
-import org.apache.qpid.server.model.AbstractConfiguredObject;
-import org.apache.qpid.server.model.AuthenticationProvider;
-import org.apache.qpid.server.model.Broker;
-import org.apache.qpid.server.model.ConfiguredObject;
-import org.apache.qpid.server.model.IllegalStateTransitionException;
-import org.apache.qpid.server.model.LifetimePolicy;
import org.apache.qpid.server.model.ManagedAttribute;
import org.apache.qpid.server.model.ManagedObject;
import org.apache.qpid.server.model.PreferencesProvider;
-import org.apache.qpid.server.model.State;
-import org.apache.qpid.server.util.MapValueConverter;
@ManagedObject( category = false, type = "FileSystemPreferences" )
-public class FileSystemPreferencesProvider extends AbstractConfiguredObject<FileSystemPreferencesProvider> implements PreferencesProvider<FileSystemPreferencesProvider>
+public interface FileSystemPreferencesProvider<X extends FileSystemPreferencesProvider<X>> extends PreferencesProvider<X>
{
- private static final Logger LOGGER = Logger.getLogger(FileSystemPreferencesProvider.class);
- public static String PATH = "path";
- public static final String PROVIDER_TYPE = "FileSystemPreferences";
-
-
-
- @SuppressWarnings("serial")
- private static final Map<String, Type> ATTRIBUTE_TYPES = Collections.unmodifiableMap(new HashMap<String, Type>()
- {{
- put(NAME, String.class);
- put(PATH, String.class);
- }});
-
- private final AuthenticationProvider<? extends AuthenticationProvider> _authenticationProvider;
- private AtomicReference<State> _state;
-
- private FileSystemPreferencesStore _store;
-
- public FileSystemPreferencesProvider(UUID id, Map<String, Object> attributes,
- AuthenticationProvider<? extends AuthenticationProvider> authenticationProvider)
- {
- super(parentsMap(authenticationProvider),
- combineIdWithAttributes(id,MapValueConverter.convert(attributes, ATTRIBUTE_TYPES)),
- authenticationProvider.getParent(Broker.class).getTaskExecutor());
- State state = MapValueConverter.getEnumAttribute(State.class, STATE, attributes, State.INITIALISING);
- _state = new AtomicReference<State>(state);
- _authenticationProvider = authenticationProvider;
- _store = new FileSystemPreferencesStore(new File(MapValueConverter.getStringAttribute(PATH, attributes)));
- createStoreIfNotExist();
- }
-
- @Override
- public Collection<String> getAttributeNames()
- {
- return getAttributeNames(FileSystemPreferencesProvider.class);
- }
+ String PATH = "path";
+ String PROVIDER_TYPE = "FileSystemPreferences";
@ManagedAttribute
- public String getPath()
- {
- return (String) getAttribute(PATH);
- }
-
- @Override
- public String setName(String currentName, String desiredName) throws IllegalStateException, AccessControlException
- {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public State getState()
- {
- return _state.get();
- }
-
- @Override
- public boolean isDurable()
- {
- return true;
- }
-
- @Override
- public void setDurable(boolean durable) throws IllegalStateException, AccessControlException, IllegalArgumentException
- {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public LifetimePolicy getLifetimePolicy()
- {
- return LifetimePolicy.PERMANENT;
- }
-
- @Override
- public LifetimePolicy setLifetimePolicy(LifetimePolicy expected, LifetimePolicy desired) throws IllegalStateException,
- AccessControlException, IllegalArgumentException
- {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public <C extends ConfiguredObject> Collection<C> getChildren(Class<C> clazz)
- {
- return Collections.emptySet();
- }
-
- @Override
- public Object getAttribute(String name)
- {
- if (DURABLE.equals(name))
- {
- return true;
- }
- else if (ID.equals(name))
- {
- return getId();
- }
- else if (LIFETIME_POLICY.equals(name))
- {
- return LifetimePolicy.PERMANENT;
- }
- else if (STATE.equals(name))
- {
- return getState();
- }
- return super.getAttribute(name);
- }
-
- @Override
- public boolean setState(State currentState, State desiredState) throws IllegalStateTransitionException, AccessControlException
- {
- State state = _state.get();
- if (desiredState == State.DELETED)
- {
- if ((state == State.INITIALISING || state == State.ACTIVE || state == State.STOPPED || state == State.QUIESCED || state == State.ERRORED)
- && _state.compareAndSet(state, State.DELETED))
- {
- try
- {
- _store.close();
- }
- finally
- {
- _store.delete();
- deleted();
- _authenticationProvider.setPreferencesProvider(null);
- }
- return true;
- }
- else
- {
- throw new IllegalStateException("Cannot delete preferences provider in state: " + state);
- }
- }
- else if (desiredState == State.ACTIVE)
- {
- if ((state == State.INITIALISING || state == State.QUIESCED || state == State.STOPPED)
- && _state.compareAndSet(state, State.ACTIVE))
- {
- try
- {
- _store.open();
- return true;
- }
- catch (RuntimeException e)
- {
- _state.compareAndSet(State.ACTIVE, State.ERRORED);
- Broker<?> broker = getAuthenticationProvider().getParent(Broker.class);
- if (broker != null && broker.isManagementMode())
- {
- LOGGER.warn("Failed to activate preferences provider: " + getName(), e);
- }
- else
- {
- throw e;
- }
- }
- }
- else
- {
- throw new IllegalStateException("Cannot activate preferences provider in state: " + state);
- }
- }
- else if (desiredState == State.QUIESCED)
- {
- if (state == State.INITIALISING && _state.compareAndSet(state, State.QUIESCED))
- {
- _store.close();
- return true;
- }
- }
- else if (desiredState == State.STOPPED)
- {
- if (_state.compareAndSet(state, State.STOPPED))
- {
- _store.close();
- return true;
- }
- else
- {
- throw new IllegalStateException("Cannot stop preferences preferences in state: " + state);
- }
- }
-
- return false;
- }
-
- @Override
- public Map<String, Object> getPreferences(String userId)
- {
- return _store.getPreferences(userId);
- }
-
- @Override
- public Map<String, Object> setPreferences(String userId, Map<String, Object> preferences)
- {
- return _store.setPreferences(userId, preferences);
- }
-
- @Override
- public String[] deletePreferences(String... userIDs)
- {
- return _store.deletePreferences(userIDs);
- }
-
- @Override
- public Set<String> listUserIDs()
- {
- return _store.listUserIDs();
- }
-
- public AuthenticationProvider<? extends AuthenticationProvider> getAuthenticationProvider()
- {
- return _authenticationProvider;
- }
-
- @Override
- protected void changeAttributes(Map<String, Object> attributes)
- {
- Map<String, Object> effectiveAttributes = MapValueConverter.convert(super.generateEffectiveAttributes(attributes),
- ATTRIBUTE_TYPES);
- validateAttributes(effectiveAttributes);
- String effectivePath = (String) effectiveAttributes.get(PATH);
- String currentPath = (String) getAttribute(PATH);
-
- File storeFile = new File(effectivePath);
- FileSystemPreferencesStore newStore = null;
- if (!effectivePath.equals(currentPath))
- {
- if (!storeFile.exists())
- {
- throw new IllegalConfigurationException("Path to preferences file does not exist!");
- }
- newStore = new FileSystemPreferencesStore(storeFile);
- newStore.open();
- }
-
- try
- {
- super.changeAttributes(attributes);
-
- if (newStore != null)
- {
- _store.close();
- _store = newStore;
- newStore = null;
- }
- }
- finally
- {
- if (newStore != null)
- {
- newStore.close();
- }
- }
- // if provider was previously in ERRORED state then set its state to ACTIVE
- _state.compareAndSet(State.ERRORED, State.ACTIVE);
- }
-
- private void validateAttributes(Map<String, Object> attributes)
- {
- super.validateChangeAttributes(attributes);
-
- String newName = (String) attributes.get(NAME);
- String currentName = getName();
- if (!currentName.equals(newName))
- {
- throw new IllegalConfigurationException("Changing the name of preferences provider is not supported");
- }
- String newType = (String) attributes.get(TYPE);
- String currentType = (String) getAttribute(TYPE);
- if (newType != null && !currentType.equals(newType))
- {
- throw new IllegalConfigurationException("Changing the type of preferences provider is not supported");
- }
- String path = (String) attributes.get(PATH);
- if (path == null || path.equals(""))
- {
- throw new IllegalConfigurationException("Path to preferences file is not specified");
- }
- }
-
- public void createStoreIfNotExist()
- {
- _store.createIfNotExist();
- }
-
- public static class FileSystemPreferencesStore
- {
- private final ObjectMapper _objectMapper;
- private final Map<String, Map<String, Object>> _preferences;
- private File _storeFile;
- private FileLock _storeLock;
- private RandomAccessFile _storeRAF;
-
- public FileSystemPreferencesStore(File preferencesFile)
- {
- _storeFile = preferencesFile;
- _objectMapper = new ObjectMapper();
- _objectMapper.configure(SerializationConfig.Feature.INDENT_OUTPUT, true);
- _objectMapper.configure(JsonParser.Feature.ALLOW_COMMENTS, true);
- _preferences = new TreeMap<String, Map<String, Object>>();
- }
-
- public void createIfNotExist()
- {
- if (!_storeFile.exists())
- {
- File parent = _storeFile.getParentFile();
- if (!parent.exists() && !parent.mkdirs())
- {
- throw new IllegalConfigurationException("Cannot create preferences store folders");
- }
- try
- {
- if (_storeFile.createNewFile() && !_storeFile.exists())
- {
- throw new IllegalConfigurationException("Preferences store file was not created:" + _storeFile.getAbsolutePath());
- }
- }
- catch (IOException e)
- {
- throw new IllegalConfigurationException("Cannot create preferences store file");
- }
- }
- }
-
- public void delete()
- {
- if (_storeFile.exists() && !_storeFile.delete())
- {
- LOGGER.warn("Failed to delete preferences provider file '" + _storeFile.getName() + "'");
- }
- }
-
- public void open()
- {
- if (!_storeFile.exists())
- {
- throw new IllegalConfigurationException("Preferences file does not exist");
- }
-
- if (_storeLock != null)
- {
- throw new IllegalStateException("Preferences store is already opened");
- }
- try
- {
- _storeRAF = new RandomAccessFile(_storeFile, "rw");
- FileChannel fileChannel = _storeRAF.getChannel();
- try
- {
- _storeLock = fileChannel.tryLock();
- }
- catch (OverlappingFileLockException e)
- {
- _storeLock = null;
- }
- if (_storeLock == null)
- {
- throw new IllegalConfigurationException("Cannot get lock on store file " + _storeFile.getName()
- + " is another instance running?");
- }
- long fileSize = fileChannel.size();
- if (fileSize > 0)
- {
- ByteBuffer buffer = ByteBuffer.allocate((int) fileSize);
- fileChannel.read(buffer);
- buffer.rewind();
- buffer.flip();
- byte[] data = buffer.array();
- try
- {
- Map<String, Map<String, Object>> preferencesMap = _objectMapper.readValue(data,
- new TypeReference<Map<String, Map<String, Object>>>()
- {
- });
- _preferences.putAll(preferencesMap);
- }
- catch (JsonProcessingException e)
- {
- throw new IllegalConfigurationException("Cannot parse preferences json in " + _storeFile.getName(), e);
- }
- }
- }
- catch (IOException e)
- {
- throw new IllegalConfigurationException("Cannot load preferences from " + _storeFile.getName(), e);
- }
- }
-
- public void close()
- {
- synchronized (_preferences)
- {
- try
- {
- if (_storeLock != null)
- {
- _storeLock.release();
- }
- }
- catch (IOException e)
- {
- LOGGER.error("Cannot release file lock for preferences file store", e);
- }
- finally
- {
- _storeLock = null;
- try
- {
- if (_storeRAF != null)
- {
- _storeRAF.close();
- }
- }
- catch (IOException e)
- {
- LOGGER.error("Cannot close preferences file", e);
- }
- finally
- {
- _storeRAF = null;
- _preferences.clear();
- }
- }
- }
- }
-
- public Map<String, Object> getPreferences(String userId)
- {
- checkStoreOpened();
- Map<String, Object> userPreferences = null;
- synchronized (_preferences)
- {
- userPreferences = _preferences.get(userId);
- }
- if (userPreferences != null)
- {
- return new HashMap<String, Object>(userPreferences);
- }
- return Collections.emptyMap();
- }
-
- public Map<String, Object> setPreferences(String userId, Map<String, Object> preferences)
- {
- checkStoreOpened();
- Map<String, Object> userPreferences = null;
- synchronized (_preferences)
- {
- userPreferences = _preferences.get(userId);
- if (userPreferences == null)
- {
- userPreferences = new HashMap<String, Object>(preferences);
- _preferences.put(userId, userPreferences);
- }
- else
- {
- userPreferences.putAll(preferences);
- }
- save();
- }
- return userPreferences;
- }
-
- public String[] deletePreferences(String... userIDs)
- {
- checkStoreOpened();
- Set<String> deletedUsers = new HashSet<String>();
- synchronized (_preferences)
- {
- for (String id : userIDs)
- {
- if (_preferences.containsKey(id))
- {
- _preferences.remove(id);
- deletedUsers.add(id);
- }
- }
- if (!deletedUsers.isEmpty())
- {
- save();
- }
- }
- return deletedUsers.toArray(new String[deletedUsers.size()]);
- }
-
- public Set<String> listUserIDs()
- {
- checkStoreOpened();
- synchronized (_preferences)
- {
- return Collections.unmodifiableSet(_preferences.keySet());
- }
- }
-
- private void save()
- {
- checkStoreOpened();
- try
- {
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- _objectMapper.writeValue(baos, _preferences);
- FileChannel channel = _storeRAF.getChannel();
- long currentSize = channel.size();
- channel.position(0);
- channel.write(ByteBuffer.wrap(baos.toByteArray()));
- if (currentSize > baos.size())
- {
- channel.truncate(baos.size());
- }
- }
- catch (IOException e)
- {
- throw new IllegalConfigurationException("Cannot store preferences", e);
- }
- }
-
- private void checkStoreOpened()
- {
- if (_storeLock == null)
- {
- throw new IllegalStateException("Preferences store is not opened");
- }
- }
-
- }
+ String getPath();
}
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/FileSystemPreferencesProviderFactory.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/FileSystemPreferencesProviderFactory.java
index abf0dbb863..18f1884778 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/FileSystemPreferencesProviderFactory.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/FileSystemPreferencesProviderFactory.java
@@ -21,29 +21,29 @@
package org.apache.qpid.server.model.adapter;
-import org.apache.qpid.server.model.AbstractConfiguredObjectTypeFactory;
-import org.apache.qpid.server.model.AuthenticationProvider;
-import org.apache.qpid.server.model.ConfiguredObject;
-
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
-public class FileSystemPreferencesProviderFactory extends AbstractConfiguredObjectTypeFactory<FileSystemPreferencesProvider>
+import org.apache.qpid.server.model.AbstractConfiguredObjectTypeFactory;
+import org.apache.qpid.server.model.AuthenticationProvider;
+import org.apache.qpid.server.model.ConfiguredObject;
+
+public class FileSystemPreferencesProviderFactory extends AbstractConfiguredObjectTypeFactory<FileSystemPreferencesProviderImpl>
{
public FileSystemPreferencesProviderFactory()
{
- super(FileSystemPreferencesProvider.class);
+ super(FileSystemPreferencesProviderImpl.class);
}
@Override
- public FileSystemPreferencesProvider createInstance(final Map<String, Object> attributes,
+ public FileSystemPreferencesProviderImpl createInstance(final Map<String, Object> attributes,
final ConfiguredObject<?>... parents)
{
Map<String,Object> attributesWithoutId = new HashMap<String, Object>(attributes);
Object idObj = attributesWithoutId.remove(ConfiguredObject.ID);
UUID id = idObj == null ? UUID.randomUUID() : idObj instanceof UUID ? (UUID) idObj : UUID.fromString(idObj.toString());
- return new FileSystemPreferencesProvider(id, attributesWithoutId, getParent(AuthenticationProvider.class,parents));
+ return new FileSystemPreferencesProviderImpl(id, attributesWithoutId, getParent(AuthenticationProvider.class,parents));
}
}
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/FileSystemPreferencesProviderImpl.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/FileSystemPreferencesProviderImpl.java
new file mode 100644
index 0000000000..c3a2cfde61
--- /dev/null
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/FileSystemPreferencesProviderImpl.java
@@ -0,0 +1,588 @@
+/*
+ *
+ * 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.model.adapter;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.lang.reflect.Type;
+import java.nio.ByteBuffer;
+import java.nio.channels.FileChannel;
+import java.nio.channels.FileLock;
+import java.nio.channels.OverlappingFileLockException;
+import java.security.AccessControlException;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.UUID;
+import java.util.concurrent.atomic.AtomicReference;
+
+import org.apache.log4j.Logger;
+import org.codehaus.jackson.JsonParser;
+import org.codehaus.jackson.JsonProcessingException;
+import org.codehaus.jackson.map.ObjectMapper;
+import org.codehaus.jackson.map.SerializationConfig;
+import org.codehaus.jackson.type.TypeReference;
+
+import org.apache.qpid.server.configuration.IllegalConfigurationException;
+import org.apache.qpid.server.model.AbstractConfiguredObject;
+import org.apache.qpid.server.model.AuthenticationProvider;
+import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.model.ConfiguredObject;
+import org.apache.qpid.server.model.IllegalStateTransitionException;
+import org.apache.qpid.server.model.LifetimePolicy;
+import org.apache.qpid.server.model.State;
+import org.apache.qpid.server.util.MapValueConverter;
+
+
+public class FileSystemPreferencesProviderImpl
+ extends AbstractConfiguredObject<FileSystemPreferencesProviderImpl> implements FileSystemPreferencesProvider<FileSystemPreferencesProviderImpl>
+{
+ private static final Logger LOGGER = Logger.getLogger(FileSystemPreferencesProviderImpl.class);
+
+
+ @SuppressWarnings("serial")
+ private static final Map<String, Type> ATTRIBUTE_TYPES = Collections.unmodifiableMap(new HashMap<String, Type>()
+ {{
+ put(NAME, String.class);
+ put(PATH, String.class);
+ }});
+
+ private final AuthenticationProvider<? extends AuthenticationProvider> _authenticationProvider;
+ private AtomicReference<State> _state;
+
+ private FileSystemPreferencesStore _store;
+
+ public FileSystemPreferencesProviderImpl(UUID id, Map<String, Object> attributes,
+ AuthenticationProvider<? extends AuthenticationProvider> authenticationProvider)
+ {
+ super(parentsMap(authenticationProvider),
+ combineIdWithAttributes(id,MapValueConverter.convert(attributes, ATTRIBUTE_TYPES)),
+ authenticationProvider.getParent(Broker.class).getTaskExecutor());
+ State state = MapValueConverter.getEnumAttribute(State.class, STATE, attributes, State.INITIALISING);
+ _state = new AtomicReference<State>(state);
+ _authenticationProvider = authenticationProvider;
+ _store = new FileSystemPreferencesStore(new File(MapValueConverter.getStringAttribute(PATH, attributes)));
+ createStoreIfNotExist();
+ }
+
+ @Override
+ public Collection<String> getAttributeNames()
+ {
+ return getAttributeNames(FileSystemPreferencesProviderImpl.class);
+ }
+
+ @Override
+ public String getPath()
+ {
+ return (String) getAttribute(PATH);
+ }
+
+ @Override
+ public String setName(String currentName, String desiredName) throws IllegalStateException, AccessControlException
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public State getState()
+ {
+ return _state.get();
+ }
+
+ @Override
+ public boolean isDurable()
+ {
+ return true;
+ }
+
+ @Override
+ public void setDurable(boolean durable) throws IllegalStateException, AccessControlException, IllegalArgumentException
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public LifetimePolicy getLifetimePolicy()
+ {
+ return LifetimePolicy.PERMANENT;
+ }
+
+ @Override
+ public LifetimePolicy setLifetimePolicy(LifetimePolicy expected, LifetimePolicy desired) throws IllegalStateException,
+ AccessControlException, IllegalArgumentException
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public <C extends ConfiguredObject> Collection<C> getChildren(Class<C> clazz)
+ {
+ return Collections.emptySet();
+ }
+
+ @Override
+ public Object getAttribute(String name)
+ {
+ if (DURABLE.equals(name))
+ {
+ return true;
+ }
+ else if (ID.equals(name))
+ {
+ return getId();
+ }
+ else if (LIFETIME_POLICY.equals(name))
+ {
+ return LifetimePolicy.PERMANENT;
+ }
+ else if (STATE.equals(name))
+ {
+ return getState();
+ }
+ return super.getAttribute(name);
+ }
+
+ @Override
+ public boolean setState(State currentState, State desiredState) throws IllegalStateTransitionException, AccessControlException
+ {
+ State state = _state.get();
+ if (desiredState == State.DELETED)
+ {
+ if ((state == State.INITIALISING || state == State.ACTIVE || state == State.STOPPED || state == State.QUIESCED || state == State.ERRORED)
+ && _state.compareAndSet(state, State.DELETED))
+ {
+ try
+ {
+ _store.close();
+ }
+ finally
+ {
+ _store.delete();
+ deleted();
+ _authenticationProvider.setPreferencesProvider(null);
+ }
+ return true;
+ }
+ else
+ {
+ throw new IllegalStateException("Cannot delete preferences provider in state: " + state);
+ }
+ }
+ else if (desiredState == State.ACTIVE)
+ {
+ if ((state == State.INITIALISING || state == State.QUIESCED || state == State.STOPPED)
+ && _state.compareAndSet(state, State.ACTIVE))
+ {
+ try
+ {
+ _store.open();
+ return true;
+ }
+ catch (RuntimeException e)
+ {
+ _state.compareAndSet(State.ACTIVE, State.ERRORED);
+ Broker<?> broker = getAuthenticationProvider().getParent(Broker.class);
+ if (broker != null && broker.isManagementMode())
+ {
+ LOGGER.warn("Failed to activate preferences provider: " + getName(), e);
+ }
+ else
+ {
+ throw e;
+ }
+ }
+ }
+ else
+ {
+ throw new IllegalStateException("Cannot activate preferences provider in state: " + state);
+ }
+ }
+ else if (desiredState == State.QUIESCED)
+ {
+ if (state == State.INITIALISING && _state.compareAndSet(state, State.QUIESCED))
+ {
+ _store.close();
+ return true;
+ }
+ }
+ else if (desiredState == State.STOPPED)
+ {
+ if (_state.compareAndSet(state, State.STOPPED))
+ {
+ _store.close();
+ return true;
+ }
+ else
+ {
+ throw new IllegalStateException("Cannot stop preferences preferences in state: " + state);
+ }
+ }
+
+ return false;
+ }
+
+ @Override
+ public Map<String, Object> getPreferences(String userId)
+ {
+ return _store.getPreferences(userId);
+ }
+
+ @Override
+ public Map<String, Object> setPreferences(String userId, Map<String, Object> preferences)
+ {
+ return _store.setPreferences(userId, preferences);
+ }
+
+ @Override
+ public String[] deletePreferences(String... userIDs)
+ {
+ return _store.deletePreferences(userIDs);
+ }
+
+ @Override
+ public Set<String> listUserIDs()
+ {
+ return _store.listUserIDs();
+ }
+
+ public AuthenticationProvider<? extends AuthenticationProvider> getAuthenticationProvider()
+ {
+ return _authenticationProvider;
+ }
+
+ @Override
+ protected void changeAttributes(Map<String, Object> attributes)
+ {
+ Map<String, Object> effectiveAttributes = MapValueConverter.convert(super.generateEffectiveAttributes(attributes),
+ ATTRIBUTE_TYPES);
+
+ String effectivePath = (String) effectiveAttributes.get(PATH);
+ String currentPath = (String) getAttribute(PATH);
+
+ File storeFile = new File(effectivePath);
+ FileSystemPreferencesStore newStore = null;
+ if (!effectivePath.equals(currentPath))
+ {
+ if (!storeFile.exists())
+ {
+ throw new IllegalConfigurationException("Path to preferences file does not exist!");
+ }
+ newStore = new FileSystemPreferencesStore(storeFile);
+ newStore.open();
+ }
+
+ try
+ {
+ super.changeAttributes(attributes);
+
+ if (newStore != null)
+ {
+ _store.close();
+ _store = newStore;
+ newStore = null;
+ }
+ }
+ finally
+ {
+ if (newStore != null)
+ {
+ newStore.close();
+ }
+ }
+ // if provider was previously in ERRORED state then set its state to ACTIVE
+ _state.compareAndSet(State.ERRORED, State.ACTIVE);
+ }
+
+ @Override
+ protected void validateChange(final ConfiguredObject<?> updatedObject, final Set<String> changedAttributes)
+ {
+ super.validateChange(updatedObject, changedAttributes);
+ FileSystemPreferencesProvider<?> updated = (FileSystemPreferencesProvider<?>) updatedObject;
+
+ if (changedAttributes.contains(NAME) && !getName().equals(updated.getName()))
+ {
+ throw new IllegalConfigurationException("Changing the name of preferences provider is not supported");
+ }
+
+ if (changedAttributes.contains(TYPE) && getType() != null && !getType().equals(updated.getType()))
+ {
+ throw new IllegalConfigurationException("Changing the type of preferences provider is not supported");
+ }
+
+ if (changedAttributes.contains(PATH) && (updated.getPath() == null || updated.getPath().equals("")))
+ {
+ throw new IllegalConfigurationException("Path to preferences file is not specified");
+ }
+ }
+
+ public void createStoreIfNotExist()
+ {
+ _store.createIfNotExist();
+ }
+
+ public static class FileSystemPreferencesStore
+ {
+ private final ObjectMapper _objectMapper;
+ private final Map<String, Map<String, Object>> _preferences;
+ private File _storeFile;
+ private FileLock _storeLock;
+ private RandomAccessFile _storeRAF;
+
+ public FileSystemPreferencesStore(File preferencesFile)
+ {
+ _storeFile = preferencesFile;
+ _objectMapper = new ObjectMapper();
+ _objectMapper.configure(SerializationConfig.Feature.INDENT_OUTPUT, true);
+ _objectMapper.configure(JsonParser.Feature.ALLOW_COMMENTS, true);
+ _preferences = new TreeMap<String, Map<String, Object>>();
+ }
+
+ public void createIfNotExist()
+ {
+ if (!_storeFile.exists())
+ {
+ File parent = _storeFile.getParentFile();
+ if (!parent.exists() && !parent.mkdirs())
+ {
+ throw new IllegalConfigurationException("Cannot create preferences store folders");
+ }
+ try
+ {
+ if (_storeFile.createNewFile() && !_storeFile.exists())
+ {
+ throw new IllegalConfigurationException("Preferences store file was not created:" + _storeFile.getAbsolutePath());
+ }
+ }
+ catch (IOException e)
+ {
+ throw new IllegalConfigurationException("Cannot create preferences store file");
+ }
+ }
+ }
+
+ public void delete()
+ {
+ if (_storeFile.exists() && !_storeFile.delete())
+ {
+ LOGGER.warn("Failed to delete preferences provider file '" + _storeFile.getName() + "'");
+ }
+ }
+
+ public void open()
+ {
+ if (!_storeFile.exists())
+ {
+ throw new IllegalConfigurationException("Preferences file does not exist");
+ }
+
+ if (_storeLock != null)
+ {
+ throw new IllegalStateException("Preferences store is already opened");
+ }
+ try
+ {
+ _storeRAF = new RandomAccessFile(_storeFile, "rw");
+ FileChannel fileChannel = _storeRAF.getChannel();
+ try
+ {
+ _storeLock = fileChannel.tryLock();
+ }
+ catch (OverlappingFileLockException e)
+ {
+ _storeLock = null;
+ }
+ if (_storeLock == null)
+ {
+ throw new IllegalConfigurationException("Cannot get lock on store file " + _storeFile.getName()
+ + " is another instance running?");
+ }
+ long fileSize = fileChannel.size();
+ if (fileSize > 0)
+ {
+ ByteBuffer buffer = ByteBuffer.allocate((int) fileSize);
+ fileChannel.read(buffer);
+ buffer.rewind();
+ buffer.flip();
+ byte[] data = buffer.array();
+ try
+ {
+ Map<String, Map<String, Object>> preferencesMap = _objectMapper.readValue(data,
+ new TypeReference<Map<String, Map<String, Object>>>()
+ {
+ });
+ _preferences.putAll(preferencesMap);
+ }
+ catch (JsonProcessingException e)
+ {
+ throw new IllegalConfigurationException("Cannot parse preferences json in " + _storeFile.getName(), e);
+ }
+ }
+ }
+ catch (IOException e)
+ {
+ throw new IllegalConfigurationException("Cannot load preferences from " + _storeFile.getName(), e);
+ }
+ }
+
+ public void close()
+ {
+ synchronized (_preferences)
+ {
+ try
+ {
+ if (_storeLock != null)
+ {
+ _storeLock.release();
+ }
+ }
+ catch (IOException e)
+ {
+ LOGGER.error("Cannot release file lock for preferences file store", e);
+ }
+ finally
+ {
+ _storeLock = null;
+ try
+ {
+ if (_storeRAF != null)
+ {
+ _storeRAF.close();
+ }
+ }
+ catch (IOException e)
+ {
+ LOGGER.error("Cannot close preferences file", e);
+ }
+ finally
+ {
+ _storeRAF = null;
+ _preferences.clear();
+ }
+ }
+ }
+ }
+
+ public Map<String, Object> getPreferences(String userId)
+ {
+ checkStoreOpened();
+ Map<String, Object> userPreferences = null;
+ synchronized (_preferences)
+ {
+ userPreferences = _preferences.get(userId);
+ }
+ if (userPreferences != null)
+ {
+ return new HashMap<String, Object>(userPreferences);
+ }
+ return Collections.emptyMap();
+ }
+
+ public Map<String, Object> setPreferences(String userId, Map<String, Object> preferences)
+ {
+ checkStoreOpened();
+ Map<String, Object> userPreferences = null;
+ synchronized (_preferences)
+ {
+ userPreferences = _preferences.get(userId);
+ if (userPreferences == null)
+ {
+ userPreferences = new HashMap<String, Object>(preferences);
+ _preferences.put(userId, userPreferences);
+ }
+ else
+ {
+ userPreferences.putAll(preferences);
+ }
+ save();
+ }
+ return userPreferences;
+ }
+
+ public String[] deletePreferences(String... userIDs)
+ {
+ checkStoreOpened();
+ Set<String> deletedUsers = new HashSet<String>();
+ synchronized (_preferences)
+ {
+ for (String id : userIDs)
+ {
+ if (_preferences.containsKey(id))
+ {
+ _preferences.remove(id);
+ deletedUsers.add(id);
+ }
+ }
+ if (!deletedUsers.isEmpty())
+ {
+ save();
+ }
+ }
+ return deletedUsers.toArray(new String[deletedUsers.size()]);
+ }
+
+ public Set<String> listUserIDs()
+ {
+ checkStoreOpened();
+ synchronized (_preferences)
+ {
+ return Collections.unmodifiableSet(_preferences.keySet());
+ }
+ }
+
+ private void save()
+ {
+ checkStoreOpened();
+ try
+ {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ _objectMapper.writeValue(baos, _preferences);
+ FileChannel channel = _storeRAF.getChannel();
+ long currentSize = channel.size();
+ channel.position(0);
+ channel.write(ByteBuffer.wrap(baos.toByteArray()));
+ if (currentSize > baos.size())
+ {
+ channel.truncate(baos.size());
+ }
+ }
+ catch (IOException e)
+ {
+ throw new IllegalConfigurationException("Cannot store preferences", e);
+ }
+ }
+
+ private void checkStoreOpened()
+ {
+ if (_storeLock == null)
+ {
+ throw new IllegalStateException("Preferences store is not opened");
+ }
+ }
+
+ }
+}
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/AbstractPort.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/AbstractPort.java
index 80dab3c96c..518abb692f 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/AbstractPort.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/AbstractPort.java
@@ -349,6 +349,7 @@ abstract public class AbstractPort<X extends AbstractPort<X>> extends AbstractCo
// no-op: expected to be overridden by subclass
}
+
@Override
protected void changeAttributes(Map<String, Object> attributes)
{
@@ -481,16 +482,7 @@ abstract public class AbstractPort<X extends AbstractPort<X>> extends AbstractCo
}
@Override
- protected void authoriseSetAttribute(String name, Object expected, Object desired) throws AccessControlException
- {
- if (!_broker.getSecurityManager().authoriseConfiguringBroker(getName(), Port.class, Operation.UPDATE))
- {
- throw new AccessControlException("Setting of port attributes is denied");
- }
- }
-
- @Override
- protected void authoriseSetAttributes(Map<String, Object> attributes) throws AccessControlException
+ protected void authoriseSetAttributes(ConfiguredObject<?> modified, Set<String> attributes) throws AccessControlException
{
if (!_broker.getSecurityManager().authoriseConfiguringBroker(getName(), Port.class, Operation.UPDATE))
{
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/PortWithAuthProvider.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/AbstractPortWithAuthProvider.java
index 3aedbc9ecf..db3d9897c7 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/PortWithAuthProvider.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/AbstractPortWithAuthProvider.java
@@ -27,11 +27,10 @@ import org.apache.qpid.server.configuration.IllegalConfigurationException;
import org.apache.qpid.server.configuration.updater.TaskExecutor;
import org.apache.qpid.server.model.AuthenticationProvider;
import org.apache.qpid.server.model.Broker;
-import org.apache.qpid.server.model.ManagedAttribute;
import org.apache.qpid.server.model.ManagedAttributeField;
import org.apache.qpid.server.model.Transport;
-abstract public class PortWithAuthProvider<X extends PortWithAuthProvider<X>> extends AbstractPort<X>
+abstract public class AbstractPortWithAuthProvider<X extends AbstractPortWithAuthProvider<X>> extends AbstractPort<X>
{
public static final String DEFAULT_AMQP_NEED_CLIENT_AUTH = "false";
public static final String DEFAULT_AMQP_WANT_CLIENT_AUTH = "false";
@@ -45,28 +44,25 @@ abstract public class PortWithAuthProvider<X extends PortWithAuthProvider<X>> ex
@ManagedAttributeField
private boolean _wantClientAuth;
- public PortWithAuthProvider(final UUID id,
- final Broker<?> broker,
- final Map<String, Object> attributes,
- final Map<String, Object> defaults,
- final TaskExecutor taskExecutor)
+ public AbstractPortWithAuthProvider(final UUID id,
+ final Broker<?> broker,
+ final Map<String, Object> attributes,
+ final Map<String, Object> defaults,
+ final TaskExecutor taskExecutor)
{
super(id, broker, attributes, taskExecutor);
}
- @ManagedAttribute( automate = true, defaultValue = DEFAULT_AMQP_NEED_CLIENT_AUTH )
public boolean getNeedClientAuth()
{
return _needClientAuth;
}
- @ManagedAttribute( automate = true, defaultValue = DEFAULT_AMQP_WANT_CLIENT_AUTH )
public boolean getWantClientAuth()
{
return _wantClientAuth;
}
- @ManagedAttribute( automate = true, mandatory = true )
public AuthenticationProvider getAuthenticationProvider()
{
Broker<?> broker = getParent(Broker.class);
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/AmqpPort.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/AmqpPort.java
index 33f6cb7ad0..a986cd8179 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/AmqpPort.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/AmqpPort.java
@@ -1,4 +1,5 @@
/*
+ *
* 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
@@ -19,244 +20,37 @@
*/
package org.apache.qpid.server.model.port;
-import java.security.GeneralSecurityException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.EnumSet;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.UUID;
-
-import javax.net.ssl.KeyManager;
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.TrustManager;
-import javax.net.ssl.X509TrustManager;
-
-import org.apache.qpid.server.configuration.BrokerProperties;
-import org.apache.qpid.server.configuration.IllegalConfigurationException;
-import org.apache.qpid.server.configuration.updater.TaskExecutor;
-import org.apache.qpid.server.logging.messages.BrokerMessages;
-import org.apache.qpid.server.model.Broker;
-import org.apache.qpid.server.model.KeyStore;
+import org.apache.qpid.server.model.AuthenticationProvider;
import org.apache.qpid.server.model.ManagedAttribute;
-import org.apache.qpid.server.model.ManagedAttributeField;
import org.apache.qpid.server.model.ManagedObject;
-import org.apache.qpid.server.model.Protocol;
-import org.apache.qpid.server.model.Transport;
-import org.apache.qpid.server.model.TrustStore;
-import org.apache.qpid.server.plugin.QpidServiceLoader;
-import org.apache.qpid.server.plugin.TransportProviderFactory;
-import org.apache.qpid.server.transport.AcceptingTransport;
-import org.apache.qpid.server.transport.TransportProvider;
-import org.apache.qpid.server.util.ServerScopedRuntimeException;
-import org.apache.qpid.transport.network.security.ssl.QpidMultipleTrustManager;
+import org.apache.qpid.server.model.Port;
@ManagedObject( category = false, type = "AMQP")
-public class AmqpPort extends PortWithAuthProvider<AmqpPort>
+public interface AmqpPort<X extends AmqpPort<X>> extends Port<X>
{
- public static final String DEFAULT_AMQP_SEND_BUFFER_SIZE = "262144";
- public static final String DEFAULT_AMQP_RECEIVE_BUFFER_SIZE = "262144";
-
- public static final String DEFAULT_AMQP_TCP_NO_DELAY = "true";
- public static final String DEFAULT_BINDING_ADDRESS = "*";
-
- @ManagedAttributeField
- private boolean _tcpNoDelay;
-
- @ManagedAttributeField
- private int _sendBufferSize;
-
- @ManagedAttributeField
- private int _receiveBufferSize;
-
- private final Broker<?> _broker;
- private AcceptingTransport _transport;
-
- public AmqpPort(UUID id,
- Broker<?> broker,
- Map<String, Object> attributes,
- TaskExecutor taskExecutor)
- {
- super(id, broker, attributes, Collections.<String,Object>emptyMap(), taskExecutor);
- _broker = broker;
- }
-
- @ManagedAttribute( automate = true , defaultValue = DEFAULT_AMQP_TCP_NO_DELAY )
- public boolean isTcpNoDelay()
- {
- return _tcpNoDelay;
- }
-
- @ManagedAttribute( automate = true , defaultValue = DEFAULT_AMQP_SEND_BUFFER_SIZE )
- public int getSendBufferSize()
- {
- return _sendBufferSize;
- }
-
- @ManagedAttribute( automate = true , defaultValue = DEFAULT_AMQP_RECEIVE_BUFFER_SIZE )
- public int getReceiveBufferSize()
- {
- return _receiveBufferSize;
- }
-
- protected Set<Protocol> getDefaultProtocols()
- {
- Set<Protocol> defaultProtocols = EnumSet.of(Protocol.AMQP_0_8, Protocol.AMQP_0_9, Protocol.AMQP_0_9_1,
- Protocol.AMQP_0_10, Protocol.AMQP_1_0);
- String excludedProtocols = System.getProperty(BrokerProperties.PROPERTY_BROKER_DEFAULT_AMQP_PROTOCOL_EXCLUDES);
- if (excludedProtocols != null)
- {
- String[] excludes = excludedProtocols.split(",");
- for (String exclude : excludes)
- {
- Protocol protocol = Protocol.valueOf(exclude);
- defaultProtocols.remove(protocol);
- }
- }
- String includedProtocols = System.getProperty(BrokerProperties.PROPERTY_BROKER_DEFAULT_AMQP_PROTOCOL_INCLUDES);
- if (includedProtocols != null)
- {
- String[] includes = includedProtocols.split(",");
- for (String include : includes)
- {
- Protocol protocol = Protocol.valueOf(include);
- defaultProtocols.add(protocol);
- }
- }
- return defaultProtocols;
- }
-
-
- @Override
- protected void onActivate()
- {
- Collection<Transport> transports = getTransports();
-
- TransportProvider transportProvider = null;
- final HashSet<Transport> transportSet = new HashSet<Transport>(transports);
- for(TransportProviderFactory tpf : (new QpidServiceLoader<TransportProviderFactory>()).instancesOf(TransportProviderFactory.class))
- {
- if(tpf.getSupportedTransports().contains(transports))
- {
- transportProvider = tpf.getTransportProvider(transportSet);
- }
- }
-
- if(transportProvider == null)
- {
- throw new IllegalConfigurationException("No transport providers found which can satisfy the requirement to support the transports: " + transports);
- }
-
- SSLContext sslContext = null;
- if (transports.contains(Transport.SSL) || transports.contains(Transport.WSS))
- {
- sslContext = createSslContext();
- }
-
- Protocol defaultSupportedProtocolReply = getDefaultAmqpSupportedReply();
-
- _transport = transportProvider.createTransport(transportSet,
- sslContext,
- this,
- getAvailableProtocols(),
- defaultSupportedProtocolReply);
-
- _transport.start();
- for(Transport transport : getTransports())
- {
- _broker.getEventLogger().message(BrokerMessages.LISTENING(String.valueOf(transport), getPort()));
- }
- }
-
- @Override
- protected void onStop()
- {
- if (_transport != null)
- {
- for(Transport transport : getTransports())
- {
- _broker.getEventLogger().message(BrokerMessages.SHUTTING_DOWN(String.valueOf(transport), getPort()));
- }
- _transport.close();
- }
- }
-
- private SSLContext createSslContext()
- {
- KeyStore keyStore = getKeyStore();
- Collection<TrustStore> trustStores = getTrustStores();
+ String DEFAULT_AMQP_SEND_BUFFER_SIZE = "262144";
+ String DEFAULT_AMQP_RECEIVE_BUFFER_SIZE = "262144";
+ String DEFAULT_AMQP_TCP_NO_DELAY = "true";
- boolean needClientCert = (Boolean)getAttribute(NEED_CLIENT_AUTH) || (Boolean)getAttribute(WANT_CLIENT_AUTH);
- if (needClientCert && trustStores.isEmpty())
- {
- throw new IllegalConfigurationException("Client certificate authentication is enabled on AMQP port '"
- + this.getName() + "' but no trust store defined");
- }
+ String DEFAULT_AMQP_NEED_CLIENT_AUTH = "false";
+ String DEFAULT_AMQP_WANT_CLIENT_AUTH = "false";
- try
- {
- SSLContext sslContext = SSLContext.getInstance("TLS");
- KeyManager[] keyManagers = keyStore.getKeyManagers();
+ @ManagedAttribute( automate = true , defaultValue = AmqpPort.DEFAULT_AMQP_TCP_NO_DELAY )
+ boolean isTcpNoDelay();
- TrustManager[] trustManagers;
- if(trustStores == null || trustStores.isEmpty())
- {
- trustManagers = null;
- }
- else if(trustStores.size() == 1)
- {
- trustManagers = trustStores.iterator().next().getTrustManagers();
- }
- else
- {
- Collection<TrustManager> trustManagerList = new ArrayList<TrustManager>();
- final QpidMultipleTrustManager mulTrustManager = new QpidMultipleTrustManager();
+ @ManagedAttribute( automate = true , defaultValue = AmqpPort.DEFAULT_AMQP_SEND_BUFFER_SIZE )
+ int getSendBufferSize();
- for(TrustStore ts : trustStores)
- {
- TrustManager[] managers = ts.getTrustManagers();
- if(managers != null)
- {
- for(TrustManager manager : managers)
- {
- if(manager instanceof X509TrustManager)
- {
- mulTrustManager.addTrustManager((X509TrustManager)manager);
- }
- else
- {
- trustManagerList.add(manager);
- }
- }
- }
- }
- if(!mulTrustManager.isEmpty())
- {
- trustManagerList.add(mulTrustManager);
- }
- trustManagers = trustManagerList.toArray(new TrustManager[trustManagerList.size()]);
- }
- sslContext.init(keyManagers, trustManagers, null);
+ @ManagedAttribute( automate = true , defaultValue = AmqpPort.DEFAULT_AMQP_RECEIVE_BUFFER_SIZE )
+ int getReceiveBufferSize();
- return sslContext;
- }
- catch (GeneralSecurityException e)
- {
- throw new ServerScopedRuntimeException("Unable to create SSLContext for key or trust store", e);
- }
- }
+ @ManagedAttribute( automate = true, defaultValue = DEFAULT_AMQP_NEED_CLIENT_AUTH )
+ boolean getNeedClientAuth();
- private Protocol getDefaultAmqpSupportedReply()
- {
- String defaultAmqpSupportedReply = System.getProperty(BrokerProperties.PROPERTY_DEFAULT_SUPPORTED_PROTOCOL_REPLY);
- if (defaultAmqpSupportedReply != null && defaultAmqpSupportedReply.length() != 0)
- {
- return Protocol.valueOf("AMQP_" + defaultAmqpSupportedReply.substring(1));
- }
- return null;
- }
+ @ManagedAttribute( automate = true, defaultValue = DEFAULT_AMQP_WANT_CLIENT_AUTH )
+ boolean getWantClientAuth();
+ @ManagedAttribute( automate = true, mandatory = true )
+ AuthenticationProvider getAuthenticationProvider();
}
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/AmqpPortFactory.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/AmqpPortFactory.java
index f2f721f572..cdb8b8c7cb 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/AmqpPortFactory.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/AmqpPortFactory.java
@@ -20,31 +20,31 @@
*/
package org.apache.qpid.server.model.port;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
import org.apache.qpid.server.model.AbstractConfiguredObjectTypeFactory;
import org.apache.qpid.server.model.Broker;
import org.apache.qpid.server.model.ConfiguredObject;
import org.apache.qpid.server.model.Port;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.UUID;
-
-public class AmqpPortFactory extends AbstractConfiguredObjectTypeFactory<AmqpPort>
+public class AmqpPortFactory extends AbstractConfiguredObjectTypeFactory<AmqpPortImpl>
{
public AmqpPortFactory()
{
- super(AmqpPort.class);
+ super(AmqpPortImpl.class);
}
@Override
- public AmqpPort createInstance(final Map<String, Object> attributes, final ConfiguredObject<?>... parents)
+ public AmqpPortImpl createInstance(final Map<String, Object> attributes, final ConfiguredObject<?>... parents)
{
Broker broker = getParent(Broker.class, parents);
Map<String,Object> attributesWithoutId = new HashMap<String, Object>(attributes);
Object idObj = attributesWithoutId.remove(Port.ID);
UUID id = idObj == null ? UUID.randomUUID() : idObj instanceof UUID ? (UUID) idObj : UUID.fromString(idObj.toString());
- return new AmqpPort(id, broker, attributesWithoutId, broker.getTaskExecutor());
+ return new AmqpPortImpl(id, broker, attributesWithoutId, broker.getTaskExecutor());
}
}
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
new file mode 100644
index 0000000000..7e496c97ed
--- /dev/null
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/AmqpPortImpl.java
@@ -0,0 +1,256 @@
+/*
+ * 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.model.port;
+
+import java.security.GeneralSecurityException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+
+import javax.net.ssl.KeyManager;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509TrustManager;
+
+import org.apache.qpid.server.configuration.BrokerProperties;
+import org.apache.qpid.server.configuration.IllegalConfigurationException;
+import org.apache.qpid.server.configuration.updater.TaskExecutor;
+import org.apache.qpid.server.logging.messages.BrokerMessages;
+import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.model.KeyStore;
+import org.apache.qpid.server.model.ManagedAttributeField;
+import org.apache.qpid.server.model.Protocol;
+import org.apache.qpid.server.model.Transport;
+import org.apache.qpid.server.model.TrustStore;
+import org.apache.qpid.server.plugin.QpidServiceLoader;
+import org.apache.qpid.server.plugin.TransportProviderFactory;
+import org.apache.qpid.server.transport.AcceptingTransport;
+import org.apache.qpid.server.transport.TransportProvider;
+import org.apache.qpid.server.util.ServerScopedRuntimeException;
+import org.apache.qpid.transport.network.security.ssl.QpidMultipleTrustManager;
+
+public class AmqpPortImpl extends AbstractPortWithAuthProvider<AmqpPortImpl> implements AmqpPort<AmqpPortImpl>
+{
+
+ public static final String DEFAULT_BINDING_ADDRESS = "*";
+
+ @ManagedAttributeField
+ private boolean _tcpNoDelay;
+
+ @ManagedAttributeField
+ private int _sendBufferSize;
+
+ @ManagedAttributeField
+ private int _receiveBufferSize;
+
+ private final Broker<?> _broker;
+ private AcceptingTransport _transport;
+
+ public AmqpPortImpl(UUID id,
+ Broker<?> broker,
+ Map<String, Object> attributes,
+ TaskExecutor taskExecutor)
+ {
+ super(id, broker, attributes, Collections.<String,Object>emptyMap(), taskExecutor);
+ _broker = broker;
+ }
+
+ @Override
+ public boolean isTcpNoDelay()
+ {
+ return _tcpNoDelay;
+ }
+
+ @Override
+ public int getSendBufferSize()
+ {
+ return _sendBufferSize;
+ }
+
+ @Override
+ public int getReceiveBufferSize()
+ {
+ return _receiveBufferSize;
+ }
+
+ protected Set<Protocol> getDefaultProtocols()
+ {
+ Set<Protocol> defaultProtocols = EnumSet.of(Protocol.AMQP_0_8, Protocol.AMQP_0_9, Protocol.AMQP_0_9_1,
+ Protocol.AMQP_0_10, Protocol.AMQP_1_0);
+ String excludedProtocols = System.getProperty(BrokerProperties.PROPERTY_BROKER_DEFAULT_AMQP_PROTOCOL_EXCLUDES);
+ if (excludedProtocols != null)
+ {
+ String[] excludes = excludedProtocols.split(",");
+ for (String exclude : excludes)
+ {
+ Protocol protocol = Protocol.valueOf(exclude);
+ defaultProtocols.remove(protocol);
+ }
+ }
+ String includedProtocols = System.getProperty(BrokerProperties.PROPERTY_BROKER_DEFAULT_AMQP_PROTOCOL_INCLUDES);
+ if (includedProtocols != null)
+ {
+ String[] includes = includedProtocols.split(",");
+ for (String include : includes)
+ {
+ Protocol protocol = Protocol.valueOf(include);
+ defaultProtocols.add(protocol);
+ }
+ }
+ return defaultProtocols;
+ }
+
+
+ @Override
+ protected void onActivate()
+ {
+ Collection<Transport> transports = getTransports();
+
+ TransportProvider transportProvider = null;
+ final HashSet<Transport> transportSet = new HashSet<Transport>(transports);
+ for(TransportProviderFactory tpf : (new QpidServiceLoader<TransportProviderFactory>()).instancesOf(TransportProviderFactory.class))
+ {
+ if(tpf.getSupportedTransports().contains(transports))
+ {
+ transportProvider = tpf.getTransportProvider(transportSet);
+ }
+ }
+
+ if(transportProvider == null)
+ {
+ throw new IllegalConfigurationException("No transport providers found which can satisfy the requirement to support the transports: " + transports);
+ }
+
+ SSLContext sslContext = null;
+ if (transports.contains(Transport.SSL) || transports.contains(Transport.WSS))
+ {
+ sslContext = createSslContext();
+ }
+
+ Protocol defaultSupportedProtocolReply = getDefaultAmqpSupportedReply();
+
+ _transport = transportProvider.createTransport(transportSet,
+ sslContext,
+ this,
+ getAvailableProtocols(),
+ defaultSupportedProtocolReply);
+
+ _transport.start();
+ for(Transport transport : getTransports())
+ {
+ _broker.getEventLogger().message(BrokerMessages.LISTENING(String.valueOf(transport), getPort()));
+ }
+ }
+
+ @Override
+ protected void onStop()
+ {
+ if (_transport != null)
+ {
+ for(Transport transport : getTransports())
+ {
+ _broker.getEventLogger().message(BrokerMessages.SHUTTING_DOWN(String.valueOf(transport), getPort()));
+ }
+ _transport.close();
+ }
+ }
+
+ private SSLContext createSslContext()
+ {
+ KeyStore keyStore = getKeyStore();
+ Collection<TrustStore> trustStores = getTrustStores();
+
+ boolean needClientCert = (Boolean)getAttribute(NEED_CLIENT_AUTH) || (Boolean)getAttribute(WANT_CLIENT_AUTH);
+ if (needClientCert && trustStores.isEmpty())
+ {
+ throw new IllegalConfigurationException("Client certificate authentication is enabled on AMQP port '"
+ + this.getName() + "' but no trust store defined");
+ }
+
+ try
+ {
+ SSLContext sslContext = SSLContext.getInstance("TLS");
+ KeyManager[] keyManagers = keyStore.getKeyManagers();
+
+ TrustManager[] trustManagers;
+ if(trustStores == null || trustStores.isEmpty())
+ {
+ trustManagers = null;
+ }
+ else if(trustStores.size() == 1)
+ {
+ trustManagers = trustStores.iterator().next().getTrustManagers();
+ }
+ else
+ {
+ Collection<TrustManager> trustManagerList = new ArrayList<TrustManager>();
+ final QpidMultipleTrustManager mulTrustManager = new QpidMultipleTrustManager();
+
+ for(TrustStore ts : trustStores)
+ {
+ TrustManager[] managers = ts.getTrustManagers();
+ if(managers != null)
+ {
+ for(TrustManager manager : managers)
+ {
+ if(manager instanceof X509TrustManager)
+ {
+ mulTrustManager.addTrustManager((X509TrustManager)manager);
+ }
+ else
+ {
+ trustManagerList.add(manager);
+ }
+ }
+ }
+ }
+ if(!mulTrustManager.isEmpty())
+ {
+ trustManagerList.add(mulTrustManager);
+ }
+ trustManagers = trustManagerList.toArray(new TrustManager[trustManagerList.size()]);
+ }
+ sslContext.init(keyManagers, trustManagers, null);
+
+ return sslContext;
+
+ }
+ catch (GeneralSecurityException e)
+ {
+ throw new ServerScopedRuntimeException("Unable to create SSLContext for key or trust store", e);
+ }
+ }
+
+ private Protocol getDefaultAmqpSupportedReply()
+ {
+ String defaultAmqpSupportedReply = System.getProperty(BrokerProperties.PROPERTY_DEFAULT_SUPPORTED_PROTOCOL_REPLY);
+ if (defaultAmqpSupportedReply != null && defaultAmqpSupportedReply.length() != 0)
+ {
+ return Protocol.valueOf("AMQP_" + defaultAmqpSupportedReply.substring(1));
+ }
+ return null;
+ }
+
+}
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/HttpPort.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/HttpPort.java
index 6813ea020c..b2a7306284 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/HttpPort.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/HttpPort.java
@@ -20,30 +20,25 @@
*/
package org.apache.qpid.server.model.port;
-import java.util.Collections;
-import java.util.Map;
-import java.util.Set;
-import java.util.UUID;
-
-import org.apache.qpid.server.configuration.updater.TaskExecutor;
-import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.model.AuthenticationProvider;
+import org.apache.qpid.server.model.ManagedAttribute;
import org.apache.qpid.server.model.ManagedObject;
-import org.apache.qpid.server.model.Protocol;
+import org.apache.qpid.server.model.Port;
@ManagedObject( category = false, type = "HTTP")
-public class HttpPort extends PortWithAuthProvider<HttpPort>
+public interface HttpPort<X extends HttpPort<X>> extends Port<X>
{
- public HttpPort(final UUID id,
- final Broker<?> broker,
- final Map<String, Object> attributes,
- final TaskExecutor taskExecutor)
- {
- super(id, broker, attributes, Collections.<String,Object>emptyMap(), taskExecutor);
- }
- @Override
- protected Set<Protocol> getDefaultProtocols()
- {
- return Collections.singleton(Protocol.HTTP);
- }
+ String DEFAULT_AMQP_NEED_CLIENT_AUTH = "false";
+ String DEFAULT_AMQP_WANT_CLIENT_AUTH = "false";
+
+
+ @ManagedAttribute( automate = true, defaultValue = DEFAULT_AMQP_NEED_CLIENT_AUTH )
+ boolean getNeedClientAuth();
+
+ @ManagedAttribute( automate = true, defaultValue = DEFAULT_AMQP_WANT_CLIENT_AUTH )
+ boolean getWantClientAuth();
+
+ @ManagedAttribute( automate = true, mandatory = true )
+ AuthenticationProvider getAuthenticationProvider();
}
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/HttpPortFactory.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/HttpPortFactory.java
index c8bd257114..ec849c8b48 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/HttpPortFactory.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/HttpPortFactory.java
@@ -20,30 +20,30 @@
*/
package org.apache.qpid.server.model.port;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
import org.apache.qpid.server.model.AbstractConfiguredObjectTypeFactory;
import org.apache.qpid.server.model.Broker;
import org.apache.qpid.server.model.ConfiguredObject;
import org.apache.qpid.server.model.Port;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.UUID;
-
-public class HttpPortFactory extends AbstractConfiguredObjectTypeFactory<HttpPort>
+public class HttpPortFactory extends AbstractConfiguredObjectTypeFactory<HttpPortImpl>
{
public HttpPortFactory()
{
- super(HttpPort.class);
+ super(HttpPortImpl.class);
}
@Override
- public HttpPort createInstance(final Map<String, Object> attributes, final ConfiguredObject<?>... parents)
+ public HttpPortImpl createInstance(final Map<String, Object> attributes, final ConfiguredObject<?>... parents)
{
Broker broker = getParent(Broker.class, parents);
Map<String,Object> attributesWithoutId = new HashMap<String, Object>(attributes);
Object idObj = attributesWithoutId.remove(Port.ID);
UUID id = idObj == null ? UUID.randomUUID() : idObj instanceof UUID ? (UUID) idObj : UUID.fromString(idObj.toString());
- return new HttpPort(id, broker, attributesWithoutId, broker.getTaskExecutor());
+ return new HttpPortImpl(id, broker, attributesWithoutId, broker.getTaskExecutor());
}
}
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/HttpPortImpl.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/HttpPortImpl.java
new file mode 100644
index 0000000000..654156f782
--- /dev/null
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/HttpPortImpl.java
@@ -0,0 +1,47 @@
+/*
+ *
+ * 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.model.port;
+
+import java.util.Collections;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+
+import org.apache.qpid.server.configuration.updater.TaskExecutor;
+import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.model.Protocol;
+
+public class HttpPortImpl extends AbstractPortWithAuthProvider<HttpPortImpl> implements HttpPort<HttpPortImpl>
+{
+ public HttpPortImpl(final UUID id,
+ final Broker<?> broker,
+ final Map<String, Object> attributes,
+ final TaskExecutor taskExecutor)
+ {
+ super(id, broker, attributes, Collections.<String,Object>emptyMap(), taskExecutor);
+ }
+
+ @Override
+ protected Set<Protocol> getDefaultProtocols()
+ {
+ return Collections.singleton(Protocol.HTTP);
+ }
+}
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/JmxPort.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/JmxPort.java
index 73109ccb06..ca72fe962b 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/JmxPort.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/JmxPort.java
@@ -20,37 +20,25 @@
*/
package org.apache.qpid.server.model.port;
-import java.util.Collections;
-import java.util.Map;
-import java.util.Set;
-import java.util.UUID;
-
-import org.apache.qpid.server.configuration.updater.TaskExecutor;
-import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.model.AuthenticationProvider;
+import org.apache.qpid.server.model.ManagedAttribute;
import org.apache.qpid.server.model.ManagedObject;
-import org.apache.qpid.server.model.Protocol;
+import org.apache.qpid.server.model.Port;
@ManagedObject( category = false, type = "JMX")
-public class JmxPort extends PortWithAuthProvider<JmxPort>
+public interface JmxPort<X extends JmxPort<X>> extends Port<X>
{
- public JmxPort(final UUID id,
- final Broker<?> broker,
- final Map<String, Object> attributes,
- final TaskExecutor taskExecutor)
- {
- super(id, broker, attributes, Collections.<String,Object>emptyMap(), taskExecutor);
- }
- @Override
- public void validate()
- {
- super.validate();
- validateOnlyOneInstance();
- }
+ String DEFAULT_AMQP_NEED_CLIENT_AUTH = "false";
+ String DEFAULT_AMQP_WANT_CLIENT_AUTH = "false";
+
+
+ @ManagedAttribute( automate = true, defaultValue = DEFAULT_AMQP_NEED_CLIENT_AUTH )
+ boolean getNeedClientAuth();
+
+ @ManagedAttribute( automate = true, defaultValue = DEFAULT_AMQP_WANT_CLIENT_AUTH )
+ boolean getWantClientAuth();
- @Override
- protected Set<Protocol> getDefaultProtocols()
- {
- return Collections.singleton(Protocol.JMX_RMI);
- }
+ @ManagedAttribute( automate = true, mandatory = true )
+ AuthenticationProvider getAuthenticationProvider();
}
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/JmxPortFactory.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/JmxPortFactory.java
index c51a9815b7..dd47965dcc 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/JmxPortFactory.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/JmxPortFactory.java
@@ -20,30 +20,30 @@
*/
package org.apache.qpid.server.model.port;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
import org.apache.qpid.server.model.AbstractConfiguredObjectTypeFactory;
import org.apache.qpid.server.model.Broker;
import org.apache.qpid.server.model.ConfiguredObject;
import org.apache.qpid.server.model.Port;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.UUID;
-
-public class JmxPortFactory extends AbstractConfiguredObjectTypeFactory<JmxPort>
+public class JmxPortFactory extends AbstractConfiguredObjectTypeFactory<JmxPortImpl>
{
public JmxPortFactory()
{
- super(JmxPort.class);
+ super(JmxPortImpl.class);
}
@Override
- public JmxPort createInstance(final Map<String, Object> attributes, final ConfiguredObject<?>... parents)
+ public JmxPortImpl createInstance(final Map<String, Object> attributes, final ConfiguredObject<?>... parents)
{
Broker broker = getParent(Broker.class, parents);
Map<String,Object> attributesWithoutId = new HashMap<String, Object>(attributes);
Object idObj = attributesWithoutId.remove(Port.ID);
UUID id = idObj == null ? UUID.randomUUID() : idObj instanceof UUID ? (UUID) idObj : UUID.fromString(idObj.toString());
- return new JmxPort(id, broker, attributesWithoutId, broker.getTaskExecutor());
+ return new JmxPortImpl(id, broker, attributesWithoutId, broker.getTaskExecutor());
}
}
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/JmxPortImpl.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/JmxPortImpl.java
new file mode 100644
index 0000000000..78a4b824cb
--- /dev/null
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/JmxPortImpl.java
@@ -0,0 +1,54 @@
+/*
+ *
+ * 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.model.port;
+
+import java.util.Collections;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+
+import org.apache.qpid.server.configuration.updater.TaskExecutor;
+import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.model.Protocol;
+
+public class JmxPortImpl extends AbstractPortWithAuthProvider<JmxPortImpl> implements JmxPort<JmxPortImpl>
+{
+ public JmxPortImpl(final UUID id,
+ final Broker<?> broker,
+ final Map<String, Object> attributes,
+ final TaskExecutor taskExecutor)
+ {
+ super(id, broker, attributes, Collections.<String,Object>emptyMap(), taskExecutor);
+ }
+
+ @Override
+ public void validate()
+ {
+ super.validate();
+ validateOnlyOneInstance();
+ }
+
+ @Override
+ protected Set<Protocol> getDefaultProtocols()
+ {
+ return Collections.singleton(Protocol.JMX_RMI);
+ }
+}
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/queue/AMQQueue.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/queue/AMQQueue.java
index 6b25e20760..30c86dc732 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/queue/AMQQueue.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/queue/AMQQueue.java
@@ -38,8 +38,8 @@ import org.apache.qpid.server.util.Deletable;
import org.apache.qpid.server.virtualhost.VirtualHostImpl;
public interface AMQQueue<X extends AMQQueue<X>>
- extends Comparable<AMQQueue>, ExchangeReferrer, BaseQueue, MessageSource, CapacityChecker, MessageDestination,
- Deletable<AMQQueue>, Queue<X>
+ extends Queue<X>, Comparable<AMQQueue>, ExchangeReferrer, BaseQueue, MessageSource, CapacityChecker, MessageDestination,
+ Deletable<AMQQueue>
{
boolean isExclusive();
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/queue/AbstractQueue.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/queue/AbstractQueue.java
index 76002970b8..78fea5a39c 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/queue/AbstractQueue.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/queue/AbstractQueue.java
@@ -24,12 +24,10 @@ import java.security.AccessController;
import java.security.Principal;
import java.security.PrivilegedAction;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.EnumSet;
import java.util.HashMap;
-import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@@ -98,12 +96,6 @@ public abstract class AbstractQueue
MessageGroupManager.ConsumerResetHelper
{
- private static final Set<String> ALERT_ATTRIBUTE_NAMES =
- Collections.unmodifiableSet(new HashSet<String>(Arrays.asList(Queue.ALERT_THRESHOLD_MESSAGE_AGE,
- Queue.ALERT_THRESHOLD_MESSAGE_SIZE,
- Queue.ALERT_THRESHOLD_QUEUE_DEPTH_BYTES,
- Queue.ALERT_THRESHOLD_QUEUE_DEPTH_MESSAGES)));
-
private static final Logger _logger = Logger.getLogger(AbstractQueue.class);
public static final String SHARED_MSG_GROUP_ARG_VALUE = "1";
@@ -126,7 +118,6 @@ public abstract class AbstractQueue
private final VirtualHostImpl _virtualHost;
private final DeletedChildListener _deletedChildListener = new DeletedChildListener();
- /** null means shared */
private String _description;
private boolean _durable;
@@ -164,19 +155,19 @@ public abstract class AbstractQueue
private final AtomicInteger _bindingCountHigh = new AtomicInteger();
/** max allowed size(KB) of a single message */
- @ManagedAttributeField
+ @ManagedAttributeField( afterSet = "updateAlertChecks" )
private long _alertThresholdMessageSize;
/** max allowed number of messages on a queue. */
- @ManagedAttributeField
+ @ManagedAttributeField( afterSet = "updateAlertChecks" )
private long _alertThresholdQueueDepthMessages;
/** max queue depth for the queue */
- @ManagedAttributeField
+ @ManagedAttributeField( afterSet = "updateAlertChecks" )
private long _alertThresholdQueueDepthBytes;
/** maximum message age before alerts occur */
- @ManagedAttributeField
+ @ManagedAttributeField( afterSet = "updateAlertChecks" )
private long _alertThresholdMessageAge;
/** the minimum interval between sending out consecutive alerts of the same type */
@@ -186,7 +177,7 @@ public abstract class AbstractQueue
@ManagedAttributeField
private long _queueFlowControlSizeBytes;
- @ManagedAttributeField
+ @ManagedAttributeField( afterSet = "checkCapacity" )
private long _queueFlowResumeSizeBytes;
@ManagedAttributeField
@@ -2890,17 +2881,7 @@ public abstract class AbstractQueue
return true;
}
- final boolean updated = super.changeAttribute(name, expected, desired);
-
- if(updated && ALERT_ATTRIBUTE_NAMES.contains(name))
- {
- updateAlertChecks();
- }
- else if(updated && QUEUE_FLOW_RESUME_SIZE_BYTES.equals(name))
- {
- checkCapacity();
- }
- return updated;
+ return super.changeAttribute(name, expected, desired);
}
finally
{
@@ -2917,14 +2898,9 @@ public abstract class AbstractQueue
{
return getAttributeNames(getClass());
}
- @Override
- protected void authoriseSetAttribute(String name, Object expected, Object desired) throws AccessControlException
- {
- _virtualHost.getSecurityManager().authoriseUpdate(this);
- }
@Override
- protected void authoriseSetAttributes(Map<String, Object> attributes) throws AccessControlException
+ protected void authoriseSetAttributes(ConfiguredObject<?> modified, Set<String> attributes) throws AccessControlException
{
_virtualHost.getSecurityManager().authoriseUpdate(this);
}
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/registry/ApplicationRegistry.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/registry/ApplicationRegistry.java
index d70b32f7ca..6ddf5f83dd 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/registry/ApplicationRegistry.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/registry/ApplicationRegistry.java
@@ -21,6 +21,7 @@
package org.apache.qpid.server.registry;
import org.apache.log4j.Logger;
+
import org.apache.qpid.common.QpidProperties;
import org.apache.qpid.server.BrokerOptions;
import org.apache.qpid.server.configuration.BrokerProperties;
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/FileKeyStore.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/FileKeyStore.java
index b1be18dc97..cd73bec3b2 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/FileKeyStore.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/FileKeyStore.java
@@ -20,63 +20,24 @@
*/
package org.apache.qpid.server.security;
-import java.io.IOException;
-import java.lang.reflect.Type;
-import java.security.AccessControlException;
-import java.security.GeneralSecurityException;
-import java.security.KeyStoreException;
-import java.security.NoSuchAlgorithmException;
-import java.security.cert.Certificate;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.UUID;
-
-import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
-import org.apache.qpid.server.configuration.IllegalConfigurationException;
-import org.apache.qpid.server.model.AbstractConfiguredObject;
-import org.apache.qpid.server.model.Broker;
-import org.apache.qpid.server.model.IntegrityViolationException;
import org.apache.qpid.server.model.KeyStore;
-import org.apache.qpid.server.model.LifetimePolicy;
import org.apache.qpid.server.model.ManagedAttribute;
-import org.apache.qpid.server.model.ManagedAttributeField;
import org.apache.qpid.server.model.ManagedContextDefault;
import org.apache.qpid.server.model.ManagedObject;
-import org.apache.qpid.server.model.Port;
import org.apache.qpid.server.model.RuntimeDefault;
-import org.apache.qpid.server.model.State;
-import org.apache.qpid.server.security.access.Operation;
-import org.apache.qpid.server.util.MapValueConverter;
-import org.apache.qpid.server.util.ServerScopedRuntimeException;
-import org.apache.qpid.transport.network.security.ssl.QpidClientX509KeyManager;
-import org.apache.qpid.transport.network.security.ssl.SSLUtil;
-@ManagedObject( category = false )
-public class FileKeyStore extends AbstractConfiguredObject<FileKeyStore> implements KeyStore<FileKeyStore>
+@ManagedObject( category = false, type = "FileKeyStore" )
+public interface FileKeyStore<X extends FileKeyStore<X>> extends KeyStore<X>
{
- public static final String KEY_MANAGER_FACTORY_ALGORITHM = "keyManagerFactoryAlgorithm";
- public static final String CERTIFICATE_ALIAS = "certificateAlias";
- public static final String KEY_STORE_TYPE = "keyStoreType";
- public static final String PASSWORD = "password";
- public static final String PATH = "path";
- @SuppressWarnings("serial")
- public static final Map<String, Type> ATTRIBUTE_TYPES = Collections.unmodifiableMap(new HashMap<String, Type>(){{
- put(NAME, String.class);
- put(PATH, String.class);
- put(PASSWORD, String.class);
- put(KEY_STORE_TYPE, String.class);
- put(CERTIFICATE_ALIAS, String.class);
- put(KEY_MANAGER_FACTORY_ALGORITHM, String.class);
- }});
-
-
+ String KEY_MANAGER_FACTORY_ALGORITHM = "keyManagerFactoryAlgorithm";
+ String CERTIFICATE_ALIAS = "certificateAlias";
+ String KEY_STORE_TYPE = "keyStoreType";
+ String PASSWORD = "password";
+ String PATH = "path";
@ManagedContextDefault(name = "keyStoreFile.keyStoreType")
- public static final RuntimeDefault<String> DEFAULT_KEYSTORE_TYPE =
+ RuntimeDefault<String> DEFAULT_KEYSTORE_TYPE =
new RuntimeDefault<String>()
{
@Override
@@ -85,9 +46,8 @@ public class FileKeyStore extends AbstractConfiguredObject<FileKeyStore> impleme
return java.security.KeyStore.getDefaultType();
}
};
-
@ManagedContextDefault(name = "keyStoreFile.keyManagerFactoryAlgorithm")
- public static final RuntimeDefault<String> DEFAULT_KEY_MANAGER_FACTORY_ALGORITHM =
+ RuntimeDefault<String> DEFAULT_KEY_MANAGER_FACTORY_ALGORITHM =
new RuntimeDefault<String>()
{
@Override
@@ -97,291 +57,18 @@ public class FileKeyStore extends AbstractConfiguredObject<FileKeyStore> impleme
}
};
-
- @ManagedAttributeField
- private String _type;
- @ManagedAttributeField
- private String _keyStoreType;
- @ManagedAttributeField
- private String _certificateAlias;
- @ManagedAttributeField
- private String _keyManagerFactoryAlgorithm;
- @ManagedAttributeField
- private String _path;
- @ManagedAttributeField
- private String _password;
-
-
- private Broker<?> _broker;
-
- public FileKeyStore(UUID id, Broker<?> broker, Map<String, Object> attributes)
- {
- super(parentsMap(broker),
- combineIdWithAttributes(id, attributes),
- broker.getTaskExecutor());
-
- _broker = broker;
- }
-
- @Override
- public void validate()
- {
- super.validate();
- validateKeyStoreAttributes(_keyStoreType, _path, getPassword(),
- _certificateAlias, _keyManagerFactoryAlgorithm);
- }
-
- @Override
- public Collection<String> getAttributeNames()
- {
- return getAttributeNames(getClass());
- }
- @Override
- public String setName(String currentName, String desiredName) throws IllegalStateException, AccessControlException
- {
- throw new IllegalStateException();
- }
-
- @Override
- public State getState()
- {
- return State.ACTIVE;
- }
-
- @Override
- public boolean isDurable()
- {
- return true;
- }
-
- @Override
- public void setDurable(boolean durable) throws IllegalStateException, AccessControlException, IllegalArgumentException
- {
- throw new IllegalStateException();
- }
-
- @Override
- public LifetimePolicy getLifetimePolicy()
- {
- return LifetimePolicy.PERMANENT;
- }
-
- @Override
- public LifetimePolicy setLifetimePolicy(LifetimePolicy expected, LifetimePolicy desired) throws IllegalStateException, AccessControlException,
- IllegalArgumentException
- {
- throw new IllegalStateException();
- }
-
- @Override
- public Object getAttribute(String name)
- {
- if(KeyStore.STATE.equals(name))
- {
- return getState();
- }
- else if(KeyStore.DURABLE.equals(name))
- {
- return isDurable();
- }
- else if(KeyStore.LIFETIME_POLICY.equals(name))
- {
- return getLifetimePolicy();
- }
-
- return super.getAttribute(name);
- }
-
- @Override
- protected boolean setState(State currentState, State desiredState)
- {
- if(desiredState == State.DELETED)
- {
- // verify that it is not in use
- String storeName = getName();
-
- Collection<Port> ports = new ArrayList<Port>(_broker.getPorts());
- for (Port port : ports)
- {
- if (port.getKeyStore() == this)
- {
- throw new IntegrityViolationException("Key store '" + storeName + "' can't be deleted as it is in use by a port:" + port.getName());
- }
- }
- deleted();
- return true;
- }
-
- return false;
- }
-
- @Override
- protected void authoriseSetDesiredState(State currentState, State desiredState) throws AccessControlException
- {
- if(desiredState == State.DELETED)
- {
- if (!_broker.getSecurityManager().authoriseConfiguringBroker(getName(), KeyStore.class, Operation.DELETE))
- {
- throw new AccessControlException("Deletion of key store is denied");
- }
- }
- }
-
- @Override
- protected void authoriseSetAttribute(String name, Object expected, Object desired) throws AccessControlException
- {
- authoriseSetAttribute();
- }
-
- @Override
- protected void authoriseSetAttributes(Map<String, Object> attributes) throws AccessControlException
- {
- authoriseSetAttribute();
- }
-
- private void authoriseSetAttribute()
- {
- if (!_broker.getSecurityManager().authoriseConfiguringBroker(getName(), KeyStore.class, Operation.UPDATE))
- {
- throw new AccessControlException("Setting key store attributes is denied");
- }
- }
-
- @Override
- protected void changeAttributes(Map<String, Object> attributes)
- {
- Map<String, Object> changedValues = MapValueConverter.convert(attributes, ATTRIBUTE_TYPES);
- if(changedValues.containsKey(KeyStore.NAME))
- {
- String newName = (String) changedValues.get(KeyStore.NAME);
- if(!getName().equals(newName))
- {
- throw new IllegalConfigurationException("Changing the key store name is not allowed");
- }
- }
-
- String keyStorePath = changedValues.containsKey(PATH) ? (String)changedValues.get(PATH) : getPath();
- String keyStorePassword = changedValues.containsKey(PASSWORD) ? (String) changedValues.get(PASSWORD) : getPassword();
- String keyStoreType = changedValues.containsKey(KEY_STORE_TYPE) ? (String)changedValues.get(KEY_STORE_TYPE) : getKeyStoreType();
- String keyManagerFactoryAlgorithm = changedValues.containsKey(KEY_MANAGER_FACTORY_ALGORITHM) ?
- (String)changedValues.get(KEY_MANAGER_FACTORY_ALGORITHM) : getKeyManagerFactoryAlgorithm();
- String certAlias = changedValues.containsKey(CERTIFICATE_ALIAS) ? (String)changedValues.get(CERTIFICATE_ALIAS)
- : getCertificateAlias();
-
- validateKeyStoreAttributes(keyStoreType, keyStorePath, keyStorePassword,
- certAlias, keyManagerFactoryAlgorithm);
-
- super.changeAttributes(changedValues);
- }
-
- private void validateKeyStoreAttributes(String type, String keyStorePath,
- String keyStorePassword, String alias,
- String keyManagerFactoryAlgorithm)
- {
- java.security.KeyStore keyStore;
- try
- {
- keyStore = SSLUtil.getInitializedKeyStore(keyStorePath, keyStorePassword, type);
- }
- catch (Exception e)
- {
- throw new IllegalConfigurationException("Cannot instantiate key store at " + keyStorePath, e);
- }
-
- if (alias != null)
- {
- Certificate cert;
- try
- {
- cert = keyStore.getCertificate(alias);
- }
- catch (KeyStoreException e)
- {
- // key store should be initialized above
- throw new ServerScopedRuntimeException("Key store has not been initialized", e);
- }
- if (cert == null)
- {
- throw new IllegalConfigurationException("Cannot find a certificate with alias " + alias
- + "in key store : " + keyStorePath);
- }
- }
-
- try
- {
- KeyManagerFactory.getInstance(keyManagerFactoryAlgorithm);
- }
- catch (NoSuchAlgorithmException e)
- {
- throw new IllegalConfigurationException("Unknown keyManagerFactoryAlgorithm: "
- + keyManagerFactoryAlgorithm);
- }
- }
-
@ManagedAttribute( automate = true, mandatory = true)
- public String getPath()
- {
- return _path;
- }
+ String getPath();
@ManagedAttribute( automate = true )
- public String getCertificateAlias()
- {
- return _certificateAlias;
- }
+ String getCertificateAlias();
@ManagedAttribute( automate = true, defaultValue = "${keyStoreFile.keyManagerFactoryAlgorithm}" )
- public String getKeyManagerFactoryAlgorithm()
- {
- return _keyManagerFactoryAlgorithm;
- }
+ String getKeyManagerFactoryAlgorithm();
@ManagedAttribute( automate = true, defaultValue = "${keyStoreFile.keyStoreType}" )
- public String getKeyStoreType()
- {
- return _keyStoreType;
- }
+ String getKeyStoreType();
@ManagedAttribute( secure = true, automate = true, mandatory = true )
- public String getPassword()
- {
- return _password;
- }
-
- public void setPassword(String password)
- {
- _password = password;
- }
-
- public KeyManager[] getKeyManagers() throws GeneralSecurityException
- {
-
- try
- {
- if (_certificateAlias != null)
- {
- return new KeyManager[] {
- new QpidClientX509KeyManager( _certificateAlias, _path, _keyStoreType, getPassword(),
- _keyManagerFactoryAlgorithm)
- };
-
- }
- else
- {
- final java.security.KeyStore ks = SSLUtil.getInitializedKeyStore(_path, getPassword(), _keyStoreType);
-
- char[] keyStoreCharPassword = getPassword() == null ? null : getPassword().toCharArray();
-
- final KeyManagerFactory kmf = KeyManagerFactory.getInstance(_keyManagerFactoryAlgorithm);
-
- kmf.init(ks, keyStoreCharPassword);
-
- return kmf.getKeyManagers();
- }
- }
- catch (IOException e)
- {
- throw new GeneralSecurityException(e);
- }
- }
+ String getPassword();
}
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/FileKeyStoreFactory.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/FileKeyStoreFactory.java
index 3421bffeba..5e54d01832 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/FileKeyStoreFactory.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/FileKeyStoreFactory.java
@@ -20,29 +20,29 @@
*/
package org.apache.qpid.server.security;
-import org.apache.qpid.server.model.AbstractConfiguredObjectTypeFactory;
-import org.apache.qpid.server.model.Broker;
-import org.apache.qpid.server.model.ConfiguredObject;
-
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
-public class FileKeyStoreFactory extends AbstractConfiguredObjectTypeFactory<FileKeyStore>
+import org.apache.qpid.server.model.AbstractConfiguredObjectTypeFactory;
+import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.model.ConfiguredObject;
+
+public class FileKeyStoreFactory extends AbstractConfiguredObjectTypeFactory<FileKeyStoreImpl>
{
public FileKeyStoreFactory()
{
- super(FileKeyStore.class);
+ super(FileKeyStoreImpl.class);
}
@Override
- public FileKeyStore createInstance(final Map<String, Object> attributes, final ConfiguredObject<?>... parents)
+ public FileKeyStoreImpl createInstance(final Map<String, Object> attributes, final ConfiguredObject<?>... parents)
{
HashMap<String, Object> attributesWithoutId = new HashMap<String, Object>(attributes);
Object idObj = attributesWithoutId.remove(ConfiguredObject.ID);
UUID id = idObj == null ? UUID.randomUUID() : idObj instanceof UUID ? (UUID) idObj : UUID.fromString(idObj.toString());
- return new FileKeyStore(id, getParent(Broker.class, parents), attributesWithoutId);
+ return new FileKeyStoreImpl(id, getParent(Broker.class, parents), attributesWithoutId);
}
}
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/FileKeyStoreImpl.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/FileKeyStoreImpl.java
new file mode 100644
index 0000000000..cfc3987677
--- /dev/null
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/FileKeyStoreImpl.java
@@ -0,0 +1,331 @@
+/*
+ *
+ * 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;
+
+import java.io.IOException;
+import java.lang.reflect.Type;
+import java.security.AccessControlException;
+import java.security.GeneralSecurityException;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.Certificate;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+
+import javax.net.ssl.KeyManager;
+import javax.net.ssl.KeyManagerFactory;
+
+import org.apache.qpid.server.configuration.IllegalConfigurationException;
+import org.apache.qpid.server.model.AbstractConfiguredObject;
+import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.model.ConfiguredObject;
+import org.apache.qpid.server.model.IntegrityViolationException;
+import org.apache.qpid.server.model.KeyStore;
+import org.apache.qpid.server.model.LifetimePolicy;
+import org.apache.qpid.server.model.ManagedAttributeField;
+import org.apache.qpid.server.model.ManagedObject;
+import org.apache.qpid.server.model.Port;
+import org.apache.qpid.server.model.State;
+import org.apache.qpid.server.security.access.Operation;
+import org.apache.qpid.server.util.ServerScopedRuntimeException;
+import org.apache.qpid.transport.network.security.ssl.QpidClientX509KeyManager;
+import org.apache.qpid.transport.network.security.ssl.SSLUtil;
+
+@ManagedObject( category = false )
+public class FileKeyStoreImpl extends AbstractConfiguredObject<FileKeyStoreImpl> implements FileKeyStore<FileKeyStoreImpl>
+{
+ @SuppressWarnings("serial")
+ public static final Map<String, Type> ATTRIBUTE_TYPES = Collections.unmodifiableMap(new HashMap<String, Type>(){{
+ put(NAME, String.class);
+ put(PATH, String.class);
+ put(PASSWORD, String.class);
+ put(KEY_STORE_TYPE, String.class);
+ put(CERTIFICATE_ALIAS, String.class);
+ put(KEY_MANAGER_FACTORY_ALGORITHM, String.class);
+ }});
+
+
+ @ManagedAttributeField
+ private String _type;
+ @ManagedAttributeField
+ private String _keyStoreType;
+ @ManagedAttributeField
+ private String _certificateAlias;
+ @ManagedAttributeField
+ private String _keyManagerFactoryAlgorithm;
+ @ManagedAttributeField
+ private String _path;
+ @ManagedAttributeField
+ private String _password;
+
+
+ private Broker<?> _broker;
+
+ public FileKeyStoreImpl(UUID id, Broker<?> broker, Map<String, Object> attributes)
+ {
+ super(parentsMap(broker),
+ combineIdWithAttributes(id, attributes),
+ broker.getTaskExecutor());
+
+ _broker = broker;
+ }
+
+ @Override
+ public void validate()
+ {
+ super.validate();
+ validateKeyStoreAttributes(this);
+ }
+
+ @Override
+ public Collection<String> getAttributeNames()
+ {
+ return getAttributeNames(getClass());
+ }
+ @Override
+ public String setName(String currentName, String desiredName) throws IllegalStateException, AccessControlException
+ {
+ throw new IllegalStateException();
+ }
+
+ @Override
+ public State getState()
+ {
+ return State.ACTIVE;
+ }
+
+ @Override
+ public boolean isDurable()
+ {
+ return true;
+ }
+
+ @Override
+ public void setDurable(boolean durable) throws IllegalStateException, AccessControlException, IllegalArgumentException
+ {
+ throw new IllegalStateException();
+ }
+
+ @Override
+ public LifetimePolicy getLifetimePolicy()
+ {
+ return LifetimePolicy.PERMANENT;
+ }
+
+ @Override
+ public LifetimePolicy setLifetimePolicy(LifetimePolicy expected, LifetimePolicy desired) throws IllegalStateException, AccessControlException,
+ IllegalArgumentException
+ {
+ throw new IllegalStateException();
+ }
+
+ @Override
+ public Object getAttribute(String name)
+ {
+ if(KeyStore.STATE.equals(name))
+ {
+ return getState();
+ }
+ else if(KeyStore.DURABLE.equals(name))
+ {
+ return isDurable();
+ }
+ else if(KeyStore.LIFETIME_POLICY.equals(name))
+ {
+ return getLifetimePolicy();
+ }
+
+ return super.getAttribute(name);
+ }
+
+ @Override
+ protected boolean setState(State currentState, State desiredState)
+ {
+ if(desiredState == State.DELETED)
+ {
+ // verify that it is not in use
+ String storeName = getName();
+
+ Collection<Port> ports = new ArrayList<Port>(_broker.getPorts());
+ for (Port port : ports)
+ {
+ if (port.getKeyStore() == this)
+ {
+ throw new IntegrityViolationException("Key store '" + storeName + "' can't be deleted as it is in use by a port:" + port.getName());
+ }
+ }
+ deleted();
+ return true;
+ }
+
+ return false;
+ }
+
+ @Override
+ protected void authoriseSetDesiredState(State currentState, State desiredState) throws AccessControlException
+ {
+ if(desiredState == State.DELETED)
+ {
+ if (!_broker.getSecurityManager().authoriseConfiguringBroker(getName(), KeyStore.class, Operation.DELETE))
+ {
+ throw new AccessControlException("Deletion of key store is denied");
+ }
+ }
+ }
+
+ @Override
+ protected void authoriseSetAttributes(ConfiguredObject<?> modified, Set<String> attributes) throws AccessControlException
+ {
+ if (!_broker.getSecurityManager().authoriseConfiguringBroker(getName(), KeyStore.class, Operation.UPDATE))
+ {
+ throw new AccessControlException("Setting key store attributes is denied");
+ }
+ }
+
+ @Override
+ protected void validateChange(final ConfiguredObject<?> proxyForValidation, final Set<String> changedAttributes)
+ {
+ super.validateChange(proxyForValidation, changedAttributes);
+ FileKeyStore changedStore = (FileKeyStore) proxyForValidation;
+ if(changedAttributes.contains(NAME) && !getName().equals(changedStore.getName()))
+ {
+ throw new IllegalConfigurationException("Changing the key store name is not allowed");
+ }
+ validateKeyStoreAttributes(changedStore);
+ }
+
+ private void validateKeyStoreAttributes(FileKeyStore<?> fileKeyStore)
+ {
+ java.security.KeyStore keyStore;
+ try
+ {
+ String path = fileKeyStore.getPath();
+ String password = fileKeyStore.getPassword();
+ String keyStoreType = fileKeyStore.getKeyStoreType();
+ keyStore = SSLUtil.getInitializedKeyStore(path, password, keyStoreType);
+ }
+ catch (Exception e)
+ {
+ throw new IllegalConfigurationException("Cannot instantiate key store at " + fileKeyStore.getPath(), e);
+ }
+
+ if (fileKeyStore.getCertificateAlias() != null)
+ {
+ Certificate cert;
+ try
+ {
+ cert = keyStore.getCertificate(fileKeyStore.getCertificateAlias());
+ }
+ catch (KeyStoreException e)
+ {
+ // key store should be initialized above
+ throw new ServerScopedRuntimeException("Key store has not been initialized", e);
+ }
+ if (cert == null)
+ {
+ throw new IllegalConfigurationException("Cannot find a certificate with alias " + fileKeyStore.getCertificateAlias()
+ + "in key store : " + fileKeyStore.getPath());
+ }
+ }
+
+ try
+ {
+ KeyManagerFactory.getInstance(fileKeyStore.getKeyManagerFactoryAlgorithm());
+ }
+ catch (NoSuchAlgorithmException e)
+ {
+ throw new IllegalConfigurationException("Unknown keyManagerFactoryAlgorithm: "
+ + fileKeyStore.getKeyManagerFactoryAlgorithm());
+ }
+ }
+
+ @Override
+ public String getPath()
+ {
+ return _path;
+ }
+
+ @Override
+ public String getCertificateAlias()
+ {
+ return _certificateAlias;
+ }
+
+ @Override
+ public String getKeyManagerFactoryAlgorithm()
+ {
+ return _keyManagerFactoryAlgorithm;
+ }
+
+ @Override
+ public String getKeyStoreType()
+ {
+ return _keyStoreType;
+ }
+
+ @Override
+ public String getPassword()
+ {
+ return _password;
+ }
+
+ public void setPassword(String password)
+ {
+ _password = password;
+ }
+
+ public KeyManager[] getKeyManagers() throws GeneralSecurityException
+ {
+
+ try
+ {
+ if (_certificateAlias != null)
+ {
+ return new KeyManager[] {
+ new QpidClientX509KeyManager( _certificateAlias, _path, _keyStoreType, getPassword(),
+ _keyManagerFactoryAlgorithm)
+ };
+
+ }
+ else
+ {
+ final java.security.KeyStore ks = SSLUtil.getInitializedKeyStore(_path, getPassword(), _keyStoreType);
+
+ char[] keyStoreCharPassword = getPassword() == null ? null : getPassword().toCharArray();
+
+ final KeyManagerFactory kmf = KeyManagerFactory.getInstance(_keyManagerFactoryAlgorithm);
+
+ kmf.init(ks, keyStoreCharPassword);
+
+ return kmf.getKeyManagers();
+ }
+ }
+ catch (IOException e)
+ {
+ throw new GeneralSecurityException(e);
+ }
+ }
+}
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/FileTrustStore.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/FileTrustStore.java
index 8111724f0c..78de8b770f 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/FileTrustStore.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/FileTrustStore.java
@@ -20,41 +20,24 @@
*/
package org.apache.qpid.server.security;
-import java.io.IOException;
-import java.lang.reflect.Type;
-import java.security.AccessControlException;
-import java.security.GeneralSecurityException;
-import java.security.KeyStore;
-import java.security.NoSuchAlgorithmException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.UUID;
-
import javax.net.ssl.KeyManagerFactory;
-import javax.net.ssl.TrustManager;
-import javax.net.ssl.TrustManagerFactory;
-
-import javax.net.ssl.X509TrustManager;
-import org.apache.qpid.server.configuration.IllegalConfigurationException;
-import org.apache.qpid.server.model.*;
-import org.apache.qpid.server.security.access.Operation;
-import org.apache.qpid.server.security.auth.manager.SimpleLDAPAuthenticationManagerFactory;
-import org.apache.qpid.server.util.MapValueConverter;
-import org.apache.qpid.transport.network.security.ssl.QpidMultipleTrustManager;
-import org.apache.qpid.transport.network.security.ssl.QpidPeersOnlyTrustManager;
-import org.apache.qpid.transport.network.security.ssl.SSLUtil;
+import org.apache.qpid.server.model.ManagedAttribute;
+import org.apache.qpid.server.model.ManagedContextDefault;
+import org.apache.qpid.server.model.ManagedObject;
+import org.apache.qpid.server.model.RuntimeDefault;
+import org.apache.qpid.server.model.TrustStore;
-@ManagedObject( category = false )
-public class FileTrustStore extends AbstractConfiguredObject<FileTrustStore> implements TrustStore<FileTrustStore>
+@ManagedObject( category = false, type = "FileTrustStore" )
+public interface FileTrustStore<X extends FileTrustStore<X>> extends TrustStore<X>
{
-
-
+ String TRUST_MANAGER_FACTORY_ALGORITHM = "trustManagerFactoryAlgorithm";
+ String PEERS_ONLY = "peersOnly";
+ String TRUST_STORE_TYPE = "trustStoreType";
+ String PASSWORD = "password";
+ String PATH = "path";
@ManagedContextDefault(name = "trustStoreFile.trustStoreType")
- public static final RuntimeDefault<String> DEFAULT_TRUSTSTORE_TYPE =
+ RuntimeDefault<String> DEFAULT_TRUSTSTORE_TYPE =
new RuntimeDefault<String>()
{
@Override
@@ -64,7 +47,7 @@ public class FileTrustStore extends AbstractConfiguredObject<FileTrustStore> imp
}
};
@ManagedContextDefault(name = "trustStoreFile.trustManagerFactoryAlgorithm")
- public static final RuntimeDefault<String> DEFAULT_TRUST_MANAGER_FACTORY_ALGORITHM =
+ RuntimeDefault<String> DEFAULT_TRUST_MANAGER_FACTORY_ALGORITHM =
new RuntimeDefault<String>()
{
@Override
@@ -74,326 +57,18 @@ public class FileTrustStore extends AbstractConfiguredObject<FileTrustStore> imp
}
};
- public static final String TRUST_MANAGER_FACTORY_ALGORITHM = "trustManagerFactoryAlgorithm";
- public static final String PEERS_ONLY = "peersOnly";
- public static final String TRUST_STORE_TYPE = "trustStoreType";
- public static final String PASSWORD = "password";
- public static final String PATH = "path";
- @SuppressWarnings("serial")
- public static final Map<String, Type> ATTRIBUTE_TYPES = Collections.unmodifiableMap(new HashMap<String, Type>(){{
- put(NAME, String.class);
- put(PATH, String.class);
- put(PASSWORD, String.class);
- put(TRUST_STORE_TYPE, String.class);
- put(PEERS_ONLY, Boolean.class);
- put(TRUST_MANAGER_FACTORY_ALGORITHM, String.class);
- }});
-
- @ManagedAttributeField
- private String _trustStoreType;
- @ManagedAttributeField
- private String _trustManagerFactoryAlgorithm;
- @ManagedAttributeField
- private String _path;
- @ManagedAttributeField
- private boolean _peersOnly;
- @ManagedAttributeField
- private String _password;
-
- private Broker<?> _broker;
-
- public FileTrustStore(UUID id, Broker<?> broker, Map<String, Object> attributes)
- {
- super(parentsMap(broker),
- combineIdWithAttributes(id, attributes),
- broker.getTaskExecutor());
- _broker = broker;
- }
-
- @Override
- public void validate()
- {
- super.validate();
- validateTrustStoreAttributes(_trustStoreType, _path, getPassword(), _trustManagerFactoryAlgorithm);
- }
-
- @Override
- public Collection<String> getAttributeNames()
- {
- return getAttributeNames(getClass());
- }
- @Override
- public String setName(String currentName, String desiredName) throws IllegalStateException, AccessControlException
- {
- throw new IllegalStateException();
- }
-
- @Override
- public State getState()
- {
- return State.ACTIVE;
- }
-
- @Override
- public boolean isDurable()
- {
- return true;
- }
-
- @Override
- public void setDurable(boolean durable) throws IllegalStateException, AccessControlException, IllegalArgumentException
- {
- throw new IllegalStateException();
- }
-
- @Override
- public LifetimePolicy getLifetimePolicy()
- {
- return LifetimePolicy.PERMANENT;
- }
-
- @Override
- public LifetimePolicy setLifetimePolicy(LifetimePolicy expected, LifetimePolicy desired) throws IllegalStateException, AccessControlException,
- IllegalArgumentException
- {
- throw new IllegalStateException();
- }
-
- @Override
- protected boolean setState(State currentState, State desiredState)
- {
- if(desiredState == State.DELETED)
- {
- // verify that it is not in use
- String storeName = getName();
-
- Collection<Port<?>> ports = new ArrayList<Port<?>>(_broker.getPorts());
- for (Port port : ports)
- {
- Collection<TrustStore> trustStores = port.getTrustStores();
- if(trustStores != null)
- {
- for (TrustStore store : trustStores)
- {
- if (storeName.equals(store.getAttribute(TrustStore.NAME)))
- {
- throw new IntegrityViolationException("Trust store '"
- + storeName
- + "' can't be deleted as it is in use by a port: "
- + port.getName());
- }
- }
- }
- }
-
- Collection<AuthenticationProvider> authenticationProviders = new ArrayList<AuthenticationProvider>(_broker.getAuthenticationProviders());
- for (AuthenticationProvider authProvider : authenticationProviders)
- {
- Object attributeType = authProvider.getAttribute(AuthenticationProvider.TYPE);
- Object attributeValue = authProvider.getAttribute(SimpleLDAPAuthenticationManagerFactory.ATTRIBUTE_TRUST_STORE);
- if (SimpleLDAPAuthenticationManagerFactory.PROVIDER_TYPE.equals(attributeType)
- && storeName.equals(attributeValue))
- {
- throw new IntegrityViolationException("Trust store '" + storeName + "' can't be deleted as it is in use by an authentication manager: " + authProvider.getName());
- }
- }
- deleted();
- return true;
- }
- return false;
- }
-
- @Override
- protected void authoriseSetDesiredState(State currentState, State desiredState) throws AccessControlException
- {
- if(desiredState == State.DELETED)
- {
- if (!_broker.getSecurityManager().authoriseConfiguringBroker(getName(), TrustStore.class, Operation.DELETE))
- {
- throw new AccessControlException("Deletion of key store is denied");
- }
- }
- }
-
- @Override
- protected void authoriseSetAttribute(String name, Object expected, Object desired) throws AccessControlException
- {
- authoriseSetAttribute();
- }
-
- @Override
- protected void authoriseSetAttributes(Map<String, Object> attributes) throws AccessControlException
- {
- authoriseSetAttribute();
- }
-
- private void authoriseSetAttribute()
- {
- if (!_broker.getSecurityManager().authoriseConfiguringBroker(getName(), TrustStore.class, Operation.UPDATE))
- {
- throw new AccessControlException("Setting key store attributes is denied");
- }
- }
-
- @Override
- protected void changeAttributes(Map<String, Object> attributes)
- {
- Map<String, Object> changedValues = MapValueConverter.convert(attributes, ATTRIBUTE_TYPES);
- if(changedValues.containsKey(TrustStore.NAME))
- {
- String newName = (String) changedValues.get(TrustStore.NAME);
- if(!getName().equals(newName))
- {
- throw new IllegalConfigurationException("Changing the trust store name is not allowed");
- }
- }
-
- Map<String, Object> merged = generateEffectiveAttributes(changedValues);
-
- String trustStorePath = changedValues.containsKey(PATH) ? (String) changedValues.get(PATH) : getPath();
- String trustStorePassword =
- changedValues.containsKey(PASSWORD) ? (String) changedValues.get(PASSWORD) : getPassword();
- String trustStoreType = changedValues.containsKey(TRUST_STORE_TYPE)
- ? (String) changedValues.get(TRUST_STORE_TYPE)
- : getTrustStoreType();
- String trustManagerFactoryAlgorithm =
- changedValues.containsKey(TRUST_MANAGER_FACTORY_ALGORITHM)
- ? (String) changedValues.get(TRUST_MANAGER_FACTORY_ALGORITHM)
- : getTrustManagerFactoryAlgorithm();
-
- validateTrustStoreAttributes(trustStoreType, trustStorePath,
- trustStorePassword, trustManagerFactoryAlgorithm);
-
- super.changeAttributes(changedValues);
- }
-
- private void validateTrustStoreAttributes(String type, String trustStorePath,
- String password, String trustManagerFactoryAlgorithm)
- {
- try
- {
- SSLUtil.getInitializedKeyStore(trustStorePath, password, type);
- }
- catch (Exception e)
- {
- throw new IllegalConfigurationException("Cannot instantiate trust store at " + trustStorePath, e);
- }
-
- try
- {
- TrustManagerFactory.getInstance(trustManagerFactoryAlgorithm);
- }
- catch (NoSuchAlgorithmException e)
- {
- throw new IllegalConfigurationException("Unknown trustManagerFactoryAlgorithm: " + trustManagerFactoryAlgorithm);
- }
- }
-
- @Override
- public Object getAttribute(String name)
- {
- if(STATE.equals(name))
- {
- return getState();
- }
- else if(DURABLE.equals(name))
- {
- return isDurable();
- }
- else if(org.apache.qpid.server.model.KeyStore.LIFETIME_POLICY.equals(name))
- {
- return getLifetimePolicy();
- }
-
- return super.getAttribute(name);
- }
@ManagedAttribute( automate = true, mandatory = true )
- public String getPath()
- {
- return _path;
- }
+ String getPath();
@ManagedAttribute( automate = true, defaultValue = "${trustStoreFile.trustManagerFactoryAlgorithm}")
- public String getTrustManagerFactoryAlgorithm()
- {
- return _trustManagerFactoryAlgorithm;
- }
+ String getTrustManagerFactoryAlgorithm();
@ManagedAttribute( automate = true, defaultValue = "${trustStoreFile.trustStoreType}")
- public String getTrustStoreType()
- {
- return _trustStoreType;
- }
+ String getTrustStoreType();
@ManagedAttribute( automate = true, defaultValue = "false" )
- public boolean isPeersOnly()
- {
- return _peersOnly;
- }
+ boolean isPeersOnly();
@ManagedAttribute( secure = true, automate = true, mandatory = true )
- public String getPassword()
- {
- return _password;
- }
-
- public void setPassword(String password)
- {
- _password = password;
- }
- public TrustManager[] getTrustManagers() throws GeneralSecurityException
- {
- String trustStorePath = _path;
- String trustStorePassword = getPassword();
- String trustStoreType = _trustStoreType;
- String trustManagerFactoryAlgorithm = _trustManagerFactoryAlgorithm;
-
- try
- {
- KeyStore ts = SSLUtil.getInitializedKeyStore(trustStorePath, trustStorePassword, trustStoreType);
- final TrustManagerFactory tmf = TrustManagerFactory
- .getInstance(trustManagerFactoryAlgorithm);
- tmf.init(ts);
- final Collection<TrustManager> trustManagersCol = new ArrayList<TrustManager>();
- final QpidMultipleTrustManager mulTrustManager = new QpidMultipleTrustManager();
- TrustManager[] delegateManagers = tmf.getTrustManagers();
- for (TrustManager tm : delegateManagers)
- {
- if (tm instanceof X509TrustManager)
- {
- if (_peersOnly)
- {
- // truststore is supposed to trust only clients which peers certificates
- // are directly in the store. CA signing will not be considered.
- mulTrustManager.addTrustManager(new QpidPeersOnlyTrustManager(ts, (X509TrustManager) tm));
- }
- else
- {
- mulTrustManager.addTrustManager((X509TrustManager) tm);
- }
- }
- else
- {
- trustManagersCol.add(tm);
- }
- }
- if (! mulTrustManager.isEmpty())
- {
- trustManagersCol.add(mulTrustManager);
- }
-
- if (trustManagersCol.isEmpty())
- {
- return null;
- }
- else
- {
- return trustManagersCol.toArray(new TrustManager[trustManagersCol.size()]);
- }
- }
- catch (IOException e)
- {
- throw new GeneralSecurityException(e);
- }
- }
+ String getPassword();
}
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/FileTrustStoreFactory.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/FileTrustStoreFactory.java
index 42a0c49308..6e08104444 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/FileTrustStoreFactory.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/FileTrustStoreFactory.java
@@ -20,19 +20,19 @@
*/
package org.apache.qpid.server.security;
-import org.apache.qpid.server.model.AbstractConfiguredObjectTypeFactory;
-import org.apache.qpid.server.model.Broker;
-import org.apache.qpid.server.model.ConfiguredObject;
-
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
-public class FileTrustStoreFactory extends AbstractConfiguredObjectTypeFactory<FileTrustStore>
+import org.apache.qpid.server.model.AbstractConfiguredObjectTypeFactory;
+import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.model.ConfiguredObject;
+
+public class FileTrustStoreFactory extends AbstractConfiguredObjectTypeFactory<FileTrustStoreImpl>
{
public FileTrustStoreFactory()
{
- super(FileTrustStore.class);
+ super(FileTrustStoreImpl.class);
}
protected final Broker getBroker(ConfiguredObject<?>... parents)
@@ -45,12 +45,12 @@ public class FileTrustStoreFactory extends AbstractConfiguredObjectTypeFactory<F
}
@Override
- public FileTrustStore createInstance(final Map<String, Object> attributes, final ConfiguredObject<?>... parents)
+ public FileTrustStoreImpl createInstance(final Map<String, Object> attributes, final ConfiguredObject<?>... parents)
{
HashMap<String, Object> attributesWithoutId = new HashMap<String, Object>(attributes);
Object idObj = attributesWithoutId.remove(ConfiguredObject.ID);
UUID id = idObj == null ? UUID.randomUUID() : idObj instanceof UUID ? (UUID) idObj : UUID.fromString(idObj.toString());
- return new FileTrustStore(id, getParent(Broker.class, parents), attributesWithoutId);
+ return new FileTrustStoreImpl(id, getParent(Broker.class, parents), attributesWithoutId);
}
}
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/FileTrustStoreImpl.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/FileTrustStoreImpl.java
new file mode 100644
index 0000000000..efaf565364
--- /dev/null
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/FileTrustStoreImpl.java
@@ -0,0 +1,369 @@
+/*
+ *
+ * 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;
+
+import java.io.IOException;
+import java.lang.reflect.Type;
+import java.security.AccessControlException;
+import java.security.GeneralSecurityException;
+import java.security.KeyStore;
+import java.security.NoSuchAlgorithmException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.TrustManagerFactory;
+import javax.net.ssl.X509TrustManager;
+
+import org.apache.qpid.server.configuration.IllegalConfigurationException;
+import org.apache.qpid.server.model.AbstractConfiguredObject;
+import org.apache.qpid.server.model.AuthenticationProvider;
+import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.model.ConfiguredObject;
+import org.apache.qpid.server.model.IntegrityViolationException;
+import org.apache.qpid.server.model.LifetimePolicy;
+import org.apache.qpid.server.model.ManagedAttributeField;
+import org.apache.qpid.server.model.Port;
+import org.apache.qpid.server.model.State;
+import org.apache.qpid.server.model.TrustStore;
+import org.apache.qpid.server.security.access.Operation;
+import org.apache.qpid.server.security.auth.manager.SimpleLDAPAuthenticationManagerFactory;
+import org.apache.qpid.server.util.MapValueConverter;
+import org.apache.qpid.transport.network.security.ssl.QpidMultipleTrustManager;
+import org.apache.qpid.transport.network.security.ssl.QpidPeersOnlyTrustManager;
+import org.apache.qpid.transport.network.security.ssl.SSLUtil;
+
+public class FileTrustStoreImpl extends AbstractConfiguredObject<FileTrustStoreImpl> implements FileTrustStore<FileTrustStoreImpl>
+{
+
+
+ @SuppressWarnings("serial")
+ public static final Map<String, Type> ATTRIBUTE_TYPES = Collections.unmodifiableMap(new HashMap<String, Type>(){{
+ put(NAME, String.class);
+ put(PATH, String.class);
+ put(PASSWORD, String.class);
+ put(TRUST_STORE_TYPE, String.class);
+ put(PEERS_ONLY, Boolean.class);
+ put(TRUST_MANAGER_FACTORY_ALGORITHM, String.class);
+ }});
+
+ @ManagedAttributeField
+ private String _trustStoreType;
+ @ManagedAttributeField
+ private String _trustManagerFactoryAlgorithm;
+ @ManagedAttributeField
+ private String _path;
+ @ManagedAttributeField
+ private boolean _peersOnly;
+ @ManagedAttributeField
+ private String _password;
+
+ private Broker<?> _broker;
+
+ public FileTrustStoreImpl(UUID id, Broker<?> broker, Map<String, Object> attributes)
+ {
+ super(parentsMap(broker),
+ combineIdWithAttributes(id, attributes),
+ broker.getTaskExecutor());
+ _broker = broker;
+ }
+
+ @Override
+ public void validate()
+ {
+ super.validate();
+ validateTrustStoreAttributes(_trustStoreType, _path, getPassword(), _trustManagerFactoryAlgorithm);
+ }
+
+ @Override
+ public Collection<String> getAttributeNames()
+ {
+ return getAttributeNames(getClass());
+ }
+ @Override
+ public String setName(String currentName, String desiredName) throws IllegalStateException, AccessControlException
+ {
+ throw new IllegalStateException();
+ }
+
+ @Override
+ public State getState()
+ {
+ return State.ACTIVE;
+ }
+
+ @Override
+ public boolean isDurable()
+ {
+ return true;
+ }
+
+ @Override
+ public void setDurable(boolean durable) throws IllegalStateException, AccessControlException, IllegalArgumentException
+ {
+ throw new IllegalStateException();
+ }
+
+ @Override
+ public LifetimePolicy getLifetimePolicy()
+ {
+ return LifetimePolicy.PERMANENT;
+ }
+
+ @Override
+ public LifetimePolicy setLifetimePolicy(LifetimePolicy expected, LifetimePolicy desired) throws IllegalStateException, AccessControlException,
+ IllegalArgumentException
+ {
+ throw new IllegalStateException();
+ }
+
+ @Override
+ protected boolean setState(State currentState, State desiredState)
+ {
+ if(desiredState == State.DELETED)
+ {
+ // verify that it is not in use
+ String storeName = getName();
+
+ Collection<Port<?>> ports = new ArrayList<Port<?>>(_broker.getPorts());
+ for (Port port : ports)
+ {
+ Collection<TrustStore> trustStores = port.getTrustStores();
+ if(trustStores != null)
+ {
+ for (TrustStore store : trustStores)
+ {
+ if (storeName.equals(store.getAttribute(TrustStore.NAME)))
+ {
+ throw new IntegrityViolationException("Trust store '"
+ + storeName
+ + "' can't be deleted as it is in use by a port: "
+ + port.getName());
+ }
+ }
+ }
+ }
+
+ Collection<AuthenticationProvider> authenticationProviders = new ArrayList<AuthenticationProvider>(_broker.getAuthenticationProviders());
+ for (AuthenticationProvider authProvider : authenticationProviders)
+ {
+ Object attributeType = authProvider.getAttribute(AuthenticationProvider.TYPE);
+ Object attributeValue = authProvider.getAttribute(SimpleLDAPAuthenticationManagerFactory.ATTRIBUTE_TRUST_STORE);
+ if (SimpleLDAPAuthenticationManagerFactory.PROVIDER_TYPE.equals(attributeType)
+ && storeName.equals(attributeValue))
+ {
+ throw new IntegrityViolationException("Trust store '" + storeName + "' can't be deleted as it is in use by an authentication manager: " + authProvider.getName());
+ }
+ }
+ deleted();
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ protected void authoriseSetDesiredState(State currentState, State desiredState) throws AccessControlException
+ {
+ if(desiredState == State.DELETED)
+ {
+ if (!_broker.getSecurityManager().authoriseConfiguringBroker(getName(), TrustStore.class, Operation.DELETE))
+ {
+ throw new AccessControlException("Deletion of key store is denied");
+ }
+ }
+ }
+
+ @Override
+ protected void authoriseSetAttributes(ConfiguredObject<?> modified, Set<String> attributes) throws AccessControlException
+ {
+ if (!_broker.getSecurityManager().authoriseConfiguringBroker(getName(), TrustStore.class, Operation.UPDATE))
+ {
+ throw new AccessControlException("Setting key store attributes is denied");
+ }
+ }
+
+ @Override
+ protected void changeAttributes(Map<String, Object> attributes)
+ {
+ Map<String, Object> changedValues = MapValueConverter.convert(attributes, ATTRIBUTE_TYPES);
+ if(changedValues.containsKey(TrustStore.NAME))
+ {
+ String newName = (String) changedValues.get(TrustStore.NAME);
+ if(!getName().equals(newName))
+ {
+ throw new IllegalConfigurationException("Changing the trust store name is not allowed");
+ }
+ }
+
+ Map<String, Object> merged = generateEffectiveAttributes(changedValues);
+
+ String trustStorePath = changedValues.containsKey(PATH) ? (String) changedValues.get(PATH) : getPath();
+ String trustStorePassword =
+ changedValues.containsKey(PASSWORD) ? (String) changedValues.get(PASSWORD) : getPassword();
+ String trustStoreType = changedValues.containsKey(TRUST_STORE_TYPE)
+ ? (String) changedValues.get(TRUST_STORE_TYPE)
+ : getTrustStoreType();
+ String trustManagerFactoryAlgorithm =
+ changedValues.containsKey(TRUST_MANAGER_FACTORY_ALGORITHM)
+ ? (String) changedValues.get(TRUST_MANAGER_FACTORY_ALGORITHM)
+ : getTrustManagerFactoryAlgorithm();
+
+ validateTrustStoreAttributes(trustStoreType, trustStorePath,
+ trustStorePassword, trustManagerFactoryAlgorithm);
+
+ super.changeAttributes(changedValues);
+ }
+
+ private void validateTrustStoreAttributes(String type, String trustStorePath,
+ String password, String trustManagerFactoryAlgorithm)
+ {
+ try
+ {
+ SSLUtil.getInitializedKeyStore(trustStorePath, password, type);
+ }
+ catch (Exception e)
+ {
+ throw new IllegalConfigurationException("Cannot instantiate trust store at " + trustStorePath, e);
+ }
+
+ try
+ {
+ TrustManagerFactory.getInstance(trustManagerFactoryAlgorithm);
+ }
+ catch (NoSuchAlgorithmException e)
+ {
+ throw new IllegalConfigurationException("Unknown trustManagerFactoryAlgorithm: " + trustManagerFactoryAlgorithm);
+ }
+ }
+
+ @Override
+ public Object getAttribute(String name)
+ {
+ if(STATE.equals(name))
+ {
+ return getState();
+ }
+ else if(DURABLE.equals(name))
+ {
+ return isDurable();
+ }
+ else if(org.apache.qpid.server.model.KeyStore.LIFETIME_POLICY.equals(name))
+ {
+ return getLifetimePolicy();
+ }
+
+ return super.getAttribute(name);
+ }
+ @Override
+ public String getPath()
+ {
+ return _path;
+ }
+
+ @Override
+ public String getTrustManagerFactoryAlgorithm()
+ {
+ return _trustManagerFactoryAlgorithm;
+ }
+
+ @Override
+ public String getTrustStoreType()
+ {
+ return _trustStoreType;
+ }
+
+ @Override
+ public boolean isPeersOnly()
+ {
+ return _peersOnly;
+ }
+
+ @Override
+ public String getPassword()
+ {
+ return _password;
+ }
+
+ public void setPassword(String password)
+ {
+ _password = password;
+ }
+ public TrustManager[] getTrustManagers() throws GeneralSecurityException
+ {
+ String trustStorePath = _path;
+ String trustStorePassword = getPassword();
+ String trustStoreType = _trustStoreType;
+ String trustManagerFactoryAlgorithm = _trustManagerFactoryAlgorithm;
+
+ try
+ {
+ KeyStore ts = SSLUtil.getInitializedKeyStore(trustStorePath, trustStorePassword, trustStoreType);
+ final TrustManagerFactory tmf = TrustManagerFactory
+ .getInstance(trustManagerFactoryAlgorithm);
+ tmf.init(ts);
+ final Collection<TrustManager> trustManagersCol = new ArrayList<TrustManager>();
+ final QpidMultipleTrustManager mulTrustManager = new QpidMultipleTrustManager();
+ TrustManager[] delegateManagers = tmf.getTrustManagers();
+ for (TrustManager tm : delegateManagers)
+ {
+ if (tm instanceof X509TrustManager)
+ {
+ if (_peersOnly)
+ {
+ // truststore is supposed to trust only clients which peers certificates
+ // are directly in the store. CA signing will not be considered.
+ mulTrustManager.addTrustManager(new QpidPeersOnlyTrustManager(ts, (X509TrustManager) tm));
+ }
+ else
+ {
+ mulTrustManager.addTrustManager((X509TrustManager) tm);
+ }
+ }
+ else
+ {
+ trustManagersCol.add(tm);
+ }
+ }
+ if (! mulTrustManager.isEmpty())
+ {
+ trustManagersCol.add(mulTrustManager);
+ }
+
+ if (trustManagersCol.isEmpty())
+ {
+ return null;
+ }
+ else
+ {
+ return trustManagersCol.toArray(new TrustManager[trustManagersCol.size()]);
+ }
+ }
+ catch (IOException e)
+ {
+ throw new GeneralSecurityException(e);
+ }
+ }
+}
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/AbstractAuthenticationManager.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/AbstractAuthenticationManager.java
index 52e4168cdd..cacb08ab5c 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/AbstractAuthenticationManager.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/AbstractAuthenticationManager.java
@@ -25,6 +25,7 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
+import java.util.Set;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicReference;
@@ -45,7 +46,7 @@ import org.apache.qpid.server.model.PreferencesProvider;
import org.apache.qpid.server.model.State;
import org.apache.qpid.server.model.User;
import org.apache.qpid.server.model.VirtualHostAlias;
-import org.apache.qpid.server.model.port.PortWithAuthProvider;
+import org.apache.qpid.server.model.port.AbstractPortWithAuthProvider;
import org.apache.qpid.server.plugin.ConfiguredObjectTypeFactory;
import org.apache.qpid.server.security.SubjectCreator;
import org.apache.qpid.server.security.access.Operation;
@@ -203,16 +204,7 @@ public abstract class AbstractAuthenticationManager<T extends AbstractAuthentica
}
@Override
- protected void authoriseSetAttribute(String name, Object expected, Object desired) throws AccessControlException
- {
- if (!_broker.getSecurityManager().authoriseConfiguringBroker(getName(), AuthenticationProvider.class, Operation.UPDATE))
- {
- throw new AccessControlException("Setting of authentication provider attributes is denied");
- }
- }
-
- @Override
- protected void authoriseSetAttributes(Map<String, Object> attributes) throws AccessControlException
+ protected void authoriseSetAttributes(ConfiguredObject<?> modified, Set<String> attributes) throws AccessControlException
{
if (!_broker.getSecurityManager().authoriseConfiguringBroker(getName(), AuthenticationProvider.class, Operation.UPDATE))
{
@@ -233,7 +225,8 @@ public abstract class AbstractAuthenticationManager<T extends AbstractAuthentica
Collection<Port> ports = new ArrayList<Port>(_broker.getPorts());
for (Port port : ports)
{
- if(port instanceof PortWithAuthProvider && ((PortWithAuthProvider<?>)port).getAuthenticationProvider() == this)
+ if(port instanceof AbstractPortWithAuthProvider
+ && ((AbstractPortWithAuthProvider<?>)port).getAuthenticationProvider() == this)
{
throw new IntegrityViolationException("Authentication provider '" + providerName + "' is set on port " + port.getName());
}
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationManager.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationManager.java
index e7d64d77f8..ceb6424c3d 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationManager.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationManager.java
@@ -1,4 +1,5 @@
/*
+ *
* 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
@@ -15,109 +16,17 @@
* 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.auth.manager;
-import java.security.Principal;
-import java.util.Map;
-
-import javax.security.sasl.SaslException;
-import javax.security.sasl.SaslServer;
-
-import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.model.AuthenticationProvider;
import org.apache.qpid.server.model.ManagedAttribute;
-import org.apache.qpid.server.model.ManagedAttributeField;
import org.apache.qpid.server.model.ManagedObject;
-import org.apache.qpid.server.security.auth.AuthenticationResult;
-import org.apache.qpid.server.security.auth.UsernamePrincipal;
-import org.apache.qpid.server.security.auth.sasl.external.ExternalSaslServer;
@ManagedObject( category = false, type = "External" )
-public class ExternalAuthenticationManager extends AbstractAuthenticationManager<ExternalAuthenticationManager>
+public interface ExternalAuthenticationManager<T extends ExternalAuthenticationManager<T>> extends AuthenticationProvider<T>
{
- private static final String EXTERNAL = "EXTERNAL";
-
- @ManagedAttributeField
- private boolean _useFullDN;
-
- protected ExternalAuthenticationManager(final Broker broker,
- final Map<String, Object> attributes)
- {
- super(broker, attributes);
- }
-
-
- @Override
- public void initialise()
- {
-
- }
-
@ManagedAttribute( automate = true )
- public boolean getUseFullDN()
- {
- return _useFullDN;
- }
-
- @Override
- public String getMechanisms()
- {
- return EXTERNAL;
- }
-
- @Override
- public SaslServer createSaslServer(String mechanism, String localFQDN, Principal externalPrincipal) throws SaslException
- {
- if(EXTERNAL.equals(mechanism))
- {
- return new ExternalSaslServer(externalPrincipal, _useFullDN);
- }
- else
- {
- throw new SaslException("Unknown mechanism: " + mechanism);
- }
- }
-
- @Override
- public AuthenticationResult authenticate(SaslServer server, byte[] response)
- {
- // Process response from the client
- try
- {
- server.evaluateResponse(response != null ? response : new byte[0]);
-
- Principal principal = ((ExternalSaslServer)server).getAuthenticatedPrincipal();
-
- if(principal != null)
- {
- return new AuthenticationResult(principal);
- }
- else
- {
- return new AuthenticationResult(AuthenticationResult.AuthenticationStatus.ERROR);
- }
- }
- catch (SaslException e)
- {
- return new AuthenticationResult(AuthenticationResult.AuthenticationStatus.ERROR,e);
- }
-
- }
-
- @Override
- public AuthenticationResult authenticate(String username, String password)
- {
- return new AuthenticationResult(new UsernamePrincipal(username));
- }
-
- @Override
- public void close()
- {
- }
-
- @Override
- public void delete()
- {
- // nothing to do, no external resource is used
- }
+ boolean getUseFullDN();
}
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationManagerFactory.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationManagerFactory.java
index 1285a79211..0191b4206d 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationManagerFactory.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationManagerFactory.java
@@ -19,17 +19,17 @@
*/
package org.apache.qpid.server.security.auth.manager;
-import org.apache.qpid.server.model.AuthenticationProvider;
-import org.apache.qpid.server.model.Broker;
-import org.apache.qpid.server.model.ConfiguredObject;
-import org.apache.qpid.server.util.ResourceBundleLoader;
-
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
-public class ExternalAuthenticationManagerFactory extends AbstractAuthenticationManagerFactory<ExternalAuthenticationManager>
+import org.apache.qpid.server.model.AuthenticationProvider;
+import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.model.ConfiguredObject;
+import org.apache.qpid.server.util.ResourceBundleLoader;
+
+public class ExternalAuthenticationManagerFactory extends AbstractAuthenticationManagerFactory<ExternalAuthenticationManagerImpl>
{
public static final String RESOURCE_BUNDLE = "org.apache.qpid.server.security.auth.manager.ExternalAuthenticationProviderAttributeDescriptions";
public static final String PROVIDER_TYPE = "External";
@@ -41,7 +41,7 @@ public class ExternalAuthenticationManagerFactory extends AbstractAuthentication
public ExternalAuthenticationManagerFactory()
{
- super(ExternalAuthenticationManager.class);
+ super(ExternalAuthenticationManagerImpl.class);
}
@Override
@@ -57,10 +57,10 @@ public class ExternalAuthenticationManagerFactory extends AbstractAuthentication
}
@Override
- public ExternalAuthenticationManager createInstance(final Map<String, Object> attributes,
+ public ExternalAuthenticationManagerImpl createInstance(final Map<String, Object> attributes,
final ConfiguredObject<?>... parents)
{
- return new ExternalAuthenticationManager(getParent(Broker.class, parents), attributes);
+ return new ExternalAuthenticationManagerImpl(getParent(Broker.class, parents), attributes);
}
}
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationManagerImpl.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationManagerImpl.java
new file mode 100644
index 0000000000..f5b65092b2
--- /dev/null
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationManagerImpl.java
@@ -0,0 +1,121 @@
+/*
+ * 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.auth.manager;
+
+import java.security.Principal;
+import java.util.Map;
+
+import javax.security.sasl.SaslException;
+import javax.security.sasl.SaslServer;
+
+import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.model.ManagedAttributeField;
+import org.apache.qpid.server.security.auth.AuthenticationResult;
+import org.apache.qpid.server.security.auth.UsernamePrincipal;
+import org.apache.qpid.server.security.auth.sasl.external.ExternalSaslServer;
+
+public class ExternalAuthenticationManagerImpl extends AbstractAuthenticationManager<ExternalAuthenticationManagerImpl>
+ implements ExternalAuthenticationManager<ExternalAuthenticationManagerImpl>
+{
+ private static final String EXTERNAL = "EXTERNAL";
+
+ @ManagedAttributeField
+ private boolean _useFullDN;
+
+ protected ExternalAuthenticationManagerImpl(final Broker broker,
+ final Map<String, Object> attributes)
+ {
+ super(broker, attributes);
+ }
+
+
+ @Override
+ public void initialise()
+ {
+
+ }
+
+ @Override
+ public boolean getUseFullDN()
+ {
+ return _useFullDN;
+ }
+
+ @Override
+ public String getMechanisms()
+ {
+ return EXTERNAL;
+ }
+
+ @Override
+ public SaslServer createSaslServer(String mechanism, String localFQDN, Principal externalPrincipal) throws SaslException
+ {
+ if(EXTERNAL.equals(mechanism))
+ {
+ return new ExternalSaslServer(externalPrincipal, _useFullDN);
+ }
+ else
+ {
+ throw new SaslException("Unknown mechanism: " + mechanism);
+ }
+ }
+
+ @Override
+ public AuthenticationResult authenticate(SaslServer server, byte[] response)
+ {
+ // Process response from the client
+ try
+ {
+ server.evaluateResponse(response != null ? response : new byte[0]);
+
+ Principal principal = ((ExternalSaslServer)server).getAuthenticatedPrincipal();
+
+ if(principal != null)
+ {
+ return new AuthenticationResult(principal);
+ }
+ else
+ {
+ return new AuthenticationResult(AuthenticationResult.AuthenticationStatus.ERROR);
+ }
+ }
+ catch (SaslException e)
+ {
+ return new AuthenticationResult(AuthenticationResult.AuthenticationStatus.ERROR,e);
+ }
+
+ }
+
+ @Override
+ public AuthenticationResult authenticate(String username, String password)
+ {
+ return new AuthenticationResult(new UsernamePrincipal(username));
+ }
+
+ @Override
+ public void close()
+ {
+ }
+
+ @Override
+ public void delete()
+ {
+ // nothing to do, no external resource is used
+ }
+}
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManager.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManager.java
index c51ab38328..e454b1b50a 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManager.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManager.java
@@ -31,6 +31,7 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import javax.security.auth.login.AccountNotFoundException;
import javax.security.sasl.SaslException;
@@ -48,7 +49,7 @@ import org.apache.qpid.server.security.auth.database.PrincipalDatabase;
public abstract class PrincipalDatabaseAuthenticationManager<T extends PrincipalDatabaseAuthenticationManager<T>>
extends AbstractAuthenticationManager<T>
- implements PasswordCredentialManagingAuthenticationProvider<T>
+ implements ExternalFileBasedAuthenticationManager<T>
{
private static final Logger LOGGER = Logger.getLogger(PrincipalDatabaseAuthenticationManager.class);
@@ -96,7 +97,7 @@ public abstract class PrincipalDatabaseAuthenticationManager<T extends Principal
protected abstract PrincipalDatabase createDatabase();
- @ManagedAttribute( automate = true , mandatory = true )
+ @Override
public String getPath()
{
return _path;
@@ -316,30 +317,25 @@ public abstract class PrincipalDatabaseAuthenticationManager<T extends Principal
super.childRemoved(child);
}
- protected void validateAttributes(Map<String, Object> attributes)
+ @Override
+ protected void validateChange(final ConfiguredObject<?> updatedObject, final Set<String> changedAttributes)
{
- super.validateChangeAttributes(attributes);
+ super.validateChange(updatedObject, changedAttributes);
- String newName = (String)attributes.get(NAME);
- String currentName = getName();
- if (!currentName.equals(newName))
+ ExternalFileBasedAuthenticationManager<?> updated = (ExternalFileBasedAuthenticationManager<?>) updatedObject;
+ if (changedAttributes.contains(NAME) && !getName().equals(updated.getName()))
{
throw new IllegalConfigurationException("Changing the name of authentication provider is not supported");
}
- String newType = (String)attributes.get(TYPE);
- String currentType = (String)getAttribute(TYPE);
- if (!currentType.equals(newType))
+ if (changedAttributes.contains(TYPE) && !getType().equals(updated.getType()))
{
throw new IllegalConfigurationException("Changing the type of authentication provider is not supported");
}
-
}
@Override
protected void changeAttributes(Map<String, Object> attributes)
{
- Map<String, Object> effectiveAttributes = super.generateEffectiveAttributes(attributes);
- validateAttributes(effectiveAttributes);
super.changeAttributes(attributes);
initialise();
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationManager.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationManager.java
index 259780f4ee..2e3568ff57 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationManager.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationManager.java
@@ -1,4 +1,5 @@
/*
+ *
* 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
@@ -15,456 +16,33 @@
* 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.auth.manager;
-import java.io.IOException;
-import java.security.GeneralSecurityException;
-import java.security.KeyManagementException;
-import java.security.NoSuchAlgorithmException;
-import java.security.Principal;
-import java.util.Hashtable;
-import java.util.Map;
-
-import javax.naming.AuthenticationException;
-import javax.naming.Context;
-import javax.naming.NamingEnumeration;
-import javax.naming.NamingException;
-import javax.naming.directory.InitialDirContext;
-import javax.naming.directory.SearchControls;
-import javax.naming.directory.SearchResult;
-import javax.net.SocketFactory;
-import javax.net.ssl.SSLContext;
-import javax.security.auth.callback.Callback;
-import javax.security.auth.callback.CallbackHandler;
-import javax.security.auth.callback.NameCallback;
-import javax.security.auth.callback.UnsupportedCallbackException;
-import javax.security.sasl.AuthorizeCallback;
-import javax.security.sasl.SaslException;
-import javax.security.sasl.SaslServer;
-
-import org.apache.log4j.Logger;
-
-import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.model.AuthenticationProvider;
import org.apache.qpid.server.model.ManagedAttribute;
-import org.apache.qpid.server.model.ManagedAttributeField;
import org.apache.qpid.server.model.ManagedObject;
import org.apache.qpid.server.model.TrustStore;
-import org.apache.qpid.server.security.auth.AuthenticationResult;
-import org.apache.qpid.server.security.auth.AuthenticationResult.AuthenticationStatus;
-import org.apache.qpid.server.security.auth.UsernamePrincipal;
-import org.apache.qpid.server.security.auth.manager.ldap.AbstractLDAPSSLSocketFactory;
-import org.apache.qpid.server.security.auth.manager.ldap.LDAPSSLSocketFactoryGenerator;
-import org.apache.qpid.server.security.auth.sasl.plain.PlainPasswordCallback;
-import org.apache.qpid.server.security.auth.sasl.plain.PlainSaslServer;
-import org.apache.qpid.server.util.ServerScopedRuntimeException;
-import org.apache.qpid.server.util.StringUtil;
-import org.apache.qpid.ssl.SSLContextFactory;
@ManagedObject( category = false, type = "SimpleLDAP" )
-public class SimpleLDAPAuthenticationManager extends AbstractAuthenticationManager<SimpleLDAPAuthenticationManager>
+public interface SimpleLDAPAuthenticationManager<X extends SimpleLDAPAuthenticationManager<X>> extends AuthenticationProvider<X>
{
- private static final Logger _logger = Logger.getLogger(SimpleLDAPAuthenticationManager.class);
-
- /**
- * Environment key to instruct {@link InitialDirContext} to override the socket factory.
- */
- private static final String JAVA_NAMING_LDAP_FACTORY_SOCKET = "java.naming.ldap.factory.socket";
-
- @ManagedAttributeField
- private String _providerUrl;
- @ManagedAttributeField
- private String _providerAuthUrl;
- @ManagedAttributeField
- private String _searchContext;
- @ManagedAttributeField
- private String _searchFilter;
- @ManagedAttributeField
- private String _ldapContextFactory;
-
-
- /**
- * Trust store - typically used when the Directory has been secured with a certificate signed by a
- * private CA (or self-signed certificate).
- */
- @ManagedAttributeField
- private TrustStore _trustStore;
-
- /**
- * Dynamically created SSL Socket Factory implementation used in the case where user has specified a trust store.
- */
- private Class<? extends SocketFactory> _sslSocketFactoryOverrideClass;
-
- protected SimpleLDAPAuthenticationManager(final Broker broker,
- final Map<String, Object> attributes)
- {
- super(broker, attributes);
- }
-
-
- @Override
- public void initialise()
- {
- _sslSocketFactoryOverrideClass = createSslSocketFactoryOverrideClass();
-
- validateInitialDirContext();
- }
-
@ManagedAttribute( automate = true )
- public String getProviderUrl()
- {
- return _providerUrl;
- }
+ String getProviderUrl();
@ManagedAttribute( automate = true )
- public String getProviderAuthUrl()
- {
- return _providerAuthUrl;
- }
+ String getProviderAuthUrl();
@ManagedAttribute( automate = true )
- public String getSearchContext()
- {
- return _searchContext;
- }
+ String getSearchContext();
@ManagedAttribute( automate = true )
- public String getSearchFilter()
- {
- return _searchFilter;
- }
+ String getSearchFilter();
@ManagedAttribute( automate = true )
- public String getLdapContextFactory()
- {
- return _ldapContextFactory;
- }
+ String getLdapContextFactory();
@ManagedAttribute( automate = true )
- public TrustStore getTrustStore()
- {
- return _trustStore;
- }
-
-
- @Override
- public String getMechanisms()
- {
- return PlainSaslServer.MECHANISM;
- }
-
- @Override
- public SaslServer createSaslServer(String mechanism, String localFQDN, Principal externalPrincipal) throws SaslException
- {
- if(PlainSaslServer.MECHANISM.equals(mechanism))
- {
- return new PlainSaslServer(new SimpleLDAPPlainCallbackHandler());
- }
- else
- {
- throw new SaslException("Unknown mechanism: " + mechanism);
- }
- }
-
- @Override
- public AuthenticationResult authenticate(SaslServer server, byte[] response)
- {
- try
- {
- // Process response from the client
- byte[] challenge = server.evaluateResponse(response != null ? response : new byte[0]);
-
- if (server.isComplete())
- {
- String authorizationID = server.getAuthorizationID();
- if (_logger.isDebugEnabled())
- {
- _logger.debug("Authenticated as " + authorizationID);
- }
-
- return new AuthenticationResult(new UsernamePrincipal(authorizationID));
- }
- else
- {
- return new AuthenticationResult(challenge, AuthenticationResult.AuthenticationStatus.CONTINUE);
- }
- }
- catch (SaslException e)
- {
- return new AuthenticationResult(AuthenticationResult.AuthenticationStatus.ERROR, e);
- }
- }
-
- @Override
- public AuthenticationResult authenticate(String username, String password)
- {
- try
- {
- AuthenticationResult result = doLDAPNameAuthentication(getNameFromId(username), password);
- if(result.getStatus() == AuthenticationStatus.SUCCESS)
- {
- //Return a result based on the supplied username rather than the search name
- return new AuthenticationResult(new UsernamePrincipal(username));
- }
- else
- {
- return result;
- }
- }
- catch (NamingException e)
- {
- return new AuthenticationResult(AuthenticationResult.AuthenticationStatus.ERROR, e);
- }
- }
-
- private AuthenticationResult doLDAPNameAuthentication(String name, String password)
- {
- if(name == null)
- {
- //The search didn't return anything, class as not-authenticated before it NPEs below
- return new AuthenticationResult(AuthenticationStatus.CONTINUE);
- }
-
- String providerAuthUrl = _providerAuthUrl == null ? _providerUrl : _providerAuthUrl;
- Hashtable<String, Object> env = createInitialDirContextEnvironment(providerAuthUrl);
-
- env.put(Context.SECURITY_AUTHENTICATION, "simple");
- env.put(Context.SECURITY_PRINCIPAL, name);
- env.put(Context.SECURITY_CREDENTIALS, password);
-
- InitialDirContext ctx = null;
- try
- {
- ctx = createInitialDirContext(env);
-
- //Authentication succeeded
- return new AuthenticationResult(new UsernamePrincipal(name));
- }
- catch(AuthenticationException ae)
- {
- //Authentication failed
- return new AuthenticationResult(AuthenticationStatus.CONTINUE);
- }
- catch (NamingException e)
- {
- //Some other failure
- return new AuthenticationResult(AuthenticationResult.AuthenticationStatus.ERROR, e);
- }
- finally
- {
- if(ctx != null)
- {
- closeSafely(ctx);
- }
- }
- }
-
- @Override
- public void close()
- {
- }
-
- private Hashtable<String, Object> createInitialDirContextEnvironment(String providerUrl)
- {
- Hashtable<String,Object> env = new Hashtable<String,Object>();
- env.put(Context.INITIAL_CONTEXT_FACTORY, _ldapContextFactory);
- env.put(Context.PROVIDER_URL, providerUrl);
- return env;
- }
-
- private InitialDirContext createInitialDirContext(Hashtable<String, Object> env) throws NamingException
- {
- ClassLoader existingContextClassLoader = null;
-
- boolean isLdaps = String.valueOf(env.get(Context.PROVIDER_URL)).trim().toLowerCase().startsWith("ldaps:");
-
- boolean revertContentClassLoader = false;
- try
- {
- if (isLdaps && _sslSocketFactoryOverrideClass != null)
- {
- existingContextClassLoader = Thread.currentThread().getContextClassLoader();
- env.put(JAVA_NAMING_LDAP_FACTORY_SOCKET, _sslSocketFactoryOverrideClass.getName());
- Thread.currentThread().setContextClassLoader(_sslSocketFactoryOverrideClass.getClassLoader());
- revertContentClassLoader = true;
- }
- return new InitialDirContext(env);
- }
- finally
- {
- if (revertContentClassLoader)
- {
- Thread.currentThread().setContextClassLoader(existingContextClassLoader);
- }
- }
- }
-
- /**
- * If a trust store has been specified, create a {@link SSLContextFactory} class that is
- * associated with the {@link SSLContext} generated from that trust store.
- *
- * @return generated socket factory class
- */
- private Class<? extends SocketFactory> createSslSocketFactoryOverrideClass()
- {
- if (_trustStore != null)
- {
- String clazzName = new StringUtil().createUniqueJavaName(getName());
- SSLContext sslContext = null;
- try
- {
- sslContext = SSLContext.getInstance("TLS");
- sslContext.init(null, _trustStore.getTrustManagers(), null);
- }
- catch (NoSuchAlgorithmException e)
- {
- _logger.error("Exception creating SSLContext", e);
- throw new ServerScopedRuntimeException("Error creating SSLContext for trust store : " + _trustStore.getName() , e);
- }
- catch (KeyManagementException e)
- {
- _logger.error("Exception creating SSLContext", e);
- throw new ServerScopedRuntimeException("Error creating SSLContext for trust store : " + _trustStore.getName() , e);
- }
- catch (GeneralSecurityException e)
- {
- _logger.error("Exception creating SSLContext", e);
- throw new ServerScopedRuntimeException("Error creating SSLContext for trust store : " + _trustStore.getName() , e);
- }
-
- Class<? extends AbstractLDAPSSLSocketFactory> clazz = LDAPSSLSocketFactoryGenerator.createSubClass(clazzName, sslContext.getSocketFactory());
- if (_logger.isDebugEnabled())
- {
- _logger.debug("Connection to Directory will use custom SSL socket factory : " + clazz);
- }
- return clazz;
- }
-
- return null;
- }
-
- private void validateInitialDirContext()
- {
- Hashtable<String,Object> env = createInitialDirContextEnvironment(_providerUrl);
- env.put(Context.SECURITY_AUTHENTICATION, "none");
-
- InitialDirContext ctx = null;
- try
- {
- ctx = createInitialDirContext(env);
- }
- catch (NamingException e)
- {
- throw new ServerScopedRuntimeException("Unable to establish anonymous connection to the ldap server at " + _providerUrl, e);
- }
- finally
- {
- closeSafely(ctx);
- }
- }
-
-
- private class SimpleLDAPPlainCallbackHandler implements CallbackHandler
- {
- @Override
- public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException
- {
- String name = null;
- String password = null;
- AuthenticationResult authenticated = null;
- for(Callback callback : callbacks)
- {
- if (callback instanceof NameCallback)
- {
- String id = ((NameCallback) callback).getDefaultName();
- try
- {
- name = getNameFromId(id);
- }
- catch (NamingException e)
- {
- _logger.warn("SASL Authentication Exception", e);
- }
- if(password != null)
- {
- authenticated = doLDAPNameAuthentication(name, password);
- }
- }
- else if (callback instanceof PlainPasswordCallback)
- {
- password = ((PlainPasswordCallback)callback).getPlainPassword();
- if(name != null)
- {
- authenticated = doLDAPNameAuthentication(name, password);
- if(authenticated.getStatus()== AuthenticationResult.AuthenticationStatus.SUCCESS)
- {
- ((PlainPasswordCallback)callback).setAuthenticated(true);
- }
- }
- }
- else if (callback instanceof AuthorizeCallback)
- {
- ((AuthorizeCallback) callback).setAuthorized(authenticated != null && authenticated.getStatus() == AuthenticationResult.AuthenticationStatus.SUCCESS);
- }
- else
- {
- throw new UnsupportedCallbackException(callback);
- }
- }
- }
- }
-
- private String getNameFromId(String id) throws NamingException
- {
- Hashtable<String,Object> env = createInitialDirContextEnvironment(_providerUrl);
-
- env.put(Context.SECURITY_AUTHENTICATION, "none");
- InitialDirContext ctx = createInitialDirContext(env);
-
- try
- {
- SearchControls searchControls = new SearchControls();
- searchControls.setReturningAttributes(new String[] {});
- searchControls.setCountLimit(1l);
- searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
- NamingEnumeration<?> namingEnum = null;
- String name = null;
-
- namingEnum = ctx.search(_searchContext, _searchFilter, new String[] { id }, searchControls);
- if(namingEnum.hasMore())
- {
- SearchResult result = (SearchResult) namingEnum.next();
- name = result.getNameInNamespace();
- }
- return name;
- }
- finally
- {
- closeSafely(ctx);
- }
-
- }
-
- private void closeSafely(InitialDirContext ctx)
- {
- try
- {
- if (ctx != null)
- {
- ctx.close();
- ctx = null;
- }
- }
- catch (Exception e)
- {
- _logger.warn("Exception closing InitialDirContext", e);
- }
- }
-
- @Override
- public void delete()
- {
- // nothing to do, no external resource is used
- }
+ TrustStore getTrustStore();
}
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationManagerFactory.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationManagerFactory.java
index 79c7e71255..28163b8800 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationManagerFactory.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationManagerFactory.java
@@ -19,17 +19,17 @@
*/
package org.apache.qpid.server.security.auth.manager;
-import org.apache.qpid.server.model.AuthenticationProvider;
-import org.apache.qpid.server.model.Broker;
-import org.apache.qpid.server.model.ConfiguredObject;
-import org.apache.qpid.server.util.ResourceBundleLoader;
-
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
-public class SimpleLDAPAuthenticationManagerFactory extends AbstractAuthenticationManagerFactory<SimpleLDAPAuthenticationManager>
+import org.apache.qpid.server.model.AuthenticationProvider;
+import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.model.ConfiguredObject;
+import org.apache.qpid.server.util.ResourceBundleLoader;
+
+public class SimpleLDAPAuthenticationManagerFactory extends AbstractAuthenticationManagerFactory<SimpleLDAPAuthenticationManagerImpl>
{
public static final String RESOURCE_BUNDLE = "org.apache.qpid.server.security.auth.manager.SimpleLDAPAuthenticationProviderAttributeDescriptions";
@@ -55,7 +55,7 @@ public class SimpleLDAPAuthenticationManagerFactory extends AbstractAuthenticati
public SimpleLDAPAuthenticationManagerFactory()
{
- super(SimpleLDAPAuthenticationManager.class);
+ super(SimpleLDAPAuthenticationManagerImpl.class);
}
@Override
@@ -71,10 +71,10 @@ public class SimpleLDAPAuthenticationManagerFactory extends AbstractAuthenticati
}
@Override
- public SimpleLDAPAuthenticationManager createInstance(final Map<String, Object> attributes,
+ public SimpleLDAPAuthenticationManagerImpl createInstance(final Map<String, Object> attributes,
final ConfiguredObject<?>... parents)
{
- return new SimpleLDAPAuthenticationManager(getParent(Broker.class, parents), attributes);
+ return new SimpleLDAPAuthenticationManagerImpl(getParent(Broker.class, parents), attributes);
}
}
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationManagerImpl.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationManagerImpl.java
new file mode 100644
index 0000000000..3756931c64
--- /dev/null
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationManagerImpl.java
@@ -0,0 +1,468 @@
+/*
+ * 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.auth.manager;
+
+import java.io.IOException;
+import java.security.GeneralSecurityException;
+import java.security.KeyManagementException;
+import java.security.NoSuchAlgorithmException;
+import java.security.Principal;
+import java.util.Hashtable;
+import java.util.Map;
+
+import javax.naming.AuthenticationException;
+import javax.naming.Context;
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+import javax.naming.directory.InitialDirContext;
+import javax.naming.directory.SearchControls;
+import javax.naming.directory.SearchResult;
+import javax.net.SocketFactory;
+import javax.net.ssl.SSLContext;
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.NameCallback;
+import javax.security.auth.callback.UnsupportedCallbackException;
+import javax.security.sasl.AuthorizeCallback;
+import javax.security.sasl.SaslException;
+import javax.security.sasl.SaslServer;
+
+import org.apache.log4j.Logger;
+
+import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.model.ManagedAttributeField;
+import org.apache.qpid.server.model.TrustStore;
+import org.apache.qpid.server.security.auth.AuthenticationResult;
+import org.apache.qpid.server.security.auth.AuthenticationResult.AuthenticationStatus;
+import org.apache.qpid.server.security.auth.UsernamePrincipal;
+import org.apache.qpid.server.security.auth.manager.ldap.AbstractLDAPSSLSocketFactory;
+import org.apache.qpid.server.security.auth.manager.ldap.LDAPSSLSocketFactoryGenerator;
+import org.apache.qpid.server.security.auth.sasl.plain.PlainPasswordCallback;
+import org.apache.qpid.server.security.auth.sasl.plain.PlainSaslServer;
+import org.apache.qpid.server.util.ServerScopedRuntimeException;
+import org.apache.qpid.server.util.StringUtil;
+import org.apache.qpid.ssl.SSLContextFactory;
+
+public class SimpleLDAPAuthenticationManagerImpl extends AbstractAuthenticationManager<SimpleLDAPAuthenticationManagerImpl>
+ implements SimpleLDAPAuthenticationManager<SimpleLDAPAuthenticationManagerImpl>
+{
+ private static final Logger _logger = Logger.getLogger(SimpleLDAPAuthenticationManagerImpl.class);
+
+ /**
+ * Environment key to instruct {@link InitialDirContext} to override the socket factory.
+ */
+ private static final String JAVA_NAMING_LDAP_FACTORY_SOCKET = "java.naming.ldap.factory.socket";
+
+ @ManagedAttributeField
+ private String _providerUrl;
+ @ManagedAttributeField
+ private String _providerAuthUrl;
+ @ManagedAttributeField
+ private String _searchContext;
+ @ManagedAttributeField
+ private String _searchFilter;
+ @ManagedAttributeField
+ private String _ldapContextFactory;
+
+
+ /**
+ * Trust store - typically used when the Directory has been secured with a certificate signed by a
+ * private CA (or self-signed certificate).
+ */
+ @ManagedAttributeField
+ private TrustStore _trustStore;
+
+ /**
+ * Dynamically created SSL Socket Factory implementation used in the case where user has specified a trust store.
+ */
+ private Class<? extends SocketFactory> _sslSocketFactoryOverrideClass;
+
+ protected SimpleLDAPAuthenticationManagerImpl(final Broker broker,
+ final Map<String, Object> attributes)
+ {
+ super(broker, attributes);
+ }
+
+
+ @Override
+ public void initialise()
+ {
+ _sslSocketFactoryOverrideClass = createSslSocketFactoryOverrideClass();
+
+ validateInitialDirContext();
+ }
+
+ @Override
+ public String getProviderUrl()
+ {
+ return _providerUrl;
+ }
+
+ @Override
+ public String getProviderAuthUrl()
+ {
+ return _providerAuthUrl;
+ }
+
+ @Override
+ public String getSearchContext()
+ {
+ return _searchContext;
+ }
+
+ @Override
+ public String getSearchFilter()
+ {
+ return _searchFilter;
+ }
+
+ @Override
+ public String getLdapContextFactory()
+ {
+ return _ldapContextFactory;
+ }
+
+ @Override
+ public TrustStore getTrustStore()
+ {
+ return _trustStore;
+ }
+
+
+ @Override
+ public String getMechanisms()
+ {
+ return PlainSaslServer.MECHANISM;
+ }
+
+ @Override
+ public SaslServer createSaslServer(String mechanism, String localFQDN, Principal externalPrincipal) throws SaslException
+ {
+ if(PlainSaslServer.MECHANISM.equals(mechanism))
+ {
+ return new PlainSaslServer(new SimpleLDAPPlainCallbackHandler());
+ }
+ else
+ {
+ throw new SaslException("Unknown mechanism: " + mechanism);
+ }
+ }
+
+ @Override
+ public AuthenticationResult authenticate(SaslServer server, byte[] response)
+ {
+ try
+ {
+ // Process response from the client
+ byte[] challenge = server.evaluateResponse(response != null ? response : new byte[0]);
+
+ if (server.isComplete())
+ {
+ String authorizationID = server.getAuthorizationID();
+ if (_logger.isDebugEnabled())
+ {
+ _logger.debug("Authenticated as " + authorizationID);
+ }
+
+ return new AuthenticationResult(new UsernamePrincipal(authorizationID));
+ }
+ else
+ {
+ return new AuthenticationResult(challenge, AuthenticationResult.AuthenticationStatus.CONTINUE);
+ }
+ }
+ catch (SaslException e)
+ {
+ return new AuthenticationResult(AuthenticationResult.AuthenticationStatus.ERROR, e);
+ }
+ }
+
+ @Override
+ public AuthenticationResult authenticate(String username, String password)
+ {
+ try
+ {
+ AuthenticationResult result = doLDAPNameAuthentication(getNameFromId(username), password);
+ if(result.getStatus() == AuthenticationStatus.SUCCESS)
+ {
+ //Return a result based on the supplied username rather than the search name
+ return new AuthenticationResult(new UsernamePrincipal(username));
+ }
+ else
+ {
+ return result;
+ }
+ }
+ catch (NamingException e)
+ {
+ return new AuthenticationResult(AuthenticationResult.AuthenticationStatus.ERROR, e);
+ }
+ }
+
+ private AuthenticationResult doLDAPNameAuthentication(String name, String password)
+ {
+ if(name == null)
+ {
+ //The search didn't return anything, class as not-authenticated before it NPEs below
+ return new AuthenticationResult(AuthenticationStatus.CONTINUE);
+ }
+
+ String providerAuthUrl = _providerAuthUrl == null ? _providerUrl : _providerAuthUrl;
+ Hashtable<String, Object> env = createInitialDirContextEnvironment(providerAuthUrl);
+
+ env.put(Context.SECURITY_AUTHENTICATION, "simple");
+ env.put(Context.SECURITY_PRINCIPAL, name);
+ env.put(Context.SECURITY_CREDENTIALS, password);
+
+ InitialDirContext ctx = null;
+ try
+ {
+ ctx = createInitialDirContext(env);
+
+ //Authentication succeeded
+ return new AuthenticationResult(new UsernamePrincipal(name));
+ }
+ catch(AuthenticationException ae)
+ {
+ //Authentication failed
+ return new AuthenticationResult(AuthenticationStatus.CONTINUE);
+ }
+ catch (NamingException e)
+ {
+ //Some other failure
+ return new AuthenticationResult(AuthenticationResult.AuthenticationStatus.ERROR, e);
+ }
+ finally
+ {
+ if(ctx != null)
+ {
+ closeSafely(ctx);
+ }
+ }
+ }
+
+ @Override
+ public void close()
+ {
+ }
+
+ private Hashtable<String, Object> createInitialDirContextEnvironment(String providerUrl)
+ {
+ Hashtable<String,Object> env = new Hashtable<String,Object>();
+ env.put(Context.INITIAL_CONTEXT_FACTORY, _ldapContextFactory);
+ env.put(Context.PROVIDER_URL, providerUrl);
+ return env;
+ }
+
+ private InitialDirContext createInitialDirContext(Hashtable<String, Object> env) throws NamingException
+ {
+ ClassLoader existingContextClassLoader = null;
+
+ boolean isLdaps = String.valueOf(env.get(Context.PROVIDER_URL)).trim().toLowerCase().startsWith("ldaps:");
+
+ boolean revertContentClassLoader = false;
+ try
+ {
+ if (isLdaps && _sslSocketFactoryOverrideClass != null)
+ {
+ existingContextClassLoader = Thread.currentThread().getContextClassLoader();
+ env.put(JAVA_NAMING_LDAP_FACTORY_SOCKET, _sslSocketFactoryOverrideClass.getName());
+ Thread.currentThread().setContextClassLoader(_sslSocketFactoryOverrideClass.getClassLoader());
+ revertContentClassLoader = true;
+ }
+ return new InitialDirContext(env);
+ }
+ finally
+ {
+ if (revertContentClassLoader)
+ {
+ Thread.currentThread().setContextClassLoader(existingContextClassLoader);
+ }
+ }
+ }
+
+ /**
+ * If a trust store has been specified, create a {@link SSLContextFactory} class that is
+ * associated with the {@link SSLContext} generated from that trust store.
+ *
+ * @return generated socket factory class
+ */
+ private Class<? extends SocketFactory> createSslSocketFactoryOverrideClass()
+ {
+ if (_trustStore != null)
+ {
+ String clazzName = new StringUtil().createUniqueJavaName(getName());
+ SSLContext sslContext = null;
+ try
+ {
+ sslContext = SSLContext.getInstance("TLS");
+ sslContext.init(null, _trustStore.getTrustManagers(), null);
+ }
+ catch (NoSuchAlgorithmException e)
+ {
+ _logger.error("Exception creating SSLContext", e);
+ throw new ServerScopedRuntimeException("Error creating SSLContext for trust store : " + _trustStore.getName() , e);
+ }
+ catch (KeyManagementException e)
+ {
+ _logger.error("Exception creating SSLContext", e);
+ throw new ServerScopedRuntimeException("Error creating SSLContext for trust store : " + _trustStore.getName() , e);
+ }
+ catch (GeneralSecurityException e)
+ {
+ _logger.error("Exception creating SSLContext", e);
+ throw new ServerScopedRuntimeException("Error creating SSLContext for trust store : " + _trustStore.getName() , e);
+ }
+
+ Class<? extends AbstractLDAPSSLSocketFactory> clazz = LDAPSSLSocketFactoryGenerator.createSubClass(clazzName, sslContext.getSocketFactory());
+ if (_logger.isDebugEnabled())
+ {
+ _logger.debug("Connection to Directory will use custom SSL socket factory : " + clazz);
+ }
+ return clazz;
+ }
+
+ return null;
+ }
+
+ private void validateInitialDirContext()
+ {
+ Hashtable<String,Object> env = createInitialDirContextEnvironment(_providerUrl);
+ env.put(Context.SECURITY_AUTHENTICATION, "none");
+
+ InitialDirContext ctx = null;
+ try
+ {
+ ctx = createInitialDirContext(env);
+ }
+ catch (NamingException e)
+ {
+ throw new ServerScopedRuntimeException("Unable to establish anonymous connection to the ldap server at " + _providerUrl, e);
+ }
+ finally
+ {
+ closeSafely(ctx);
+ }
+ }
+
+
+ private class SimpleLDAPPlainCallbackHandler implements CallbackHandler
+ {
+ @Override
+ public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException
+ {
+ String name = null;
+ String password = null;
+ AuthenticationResult authenticated = null;
+ for(Callback callback : callbacks)
+ {
+ if (callback instanceof NameCallback)
+ {
+ String id = ((NameCallback) callback).getDefaultName();
+ try
+ {
+ name = getNameFromId(id);
+ }
+ catch (NamingException e)
+ {
+ _logger.warn("SASL Authentication Exception", e);
+ }
+ if(password != null)
+ {
+ authenticated = doLDAPNameAuthentication(name, password);
+ }
+ }
+ else if (callback instanceof PlainPasswordCallback)
+ {
+ password = ((PlainPasswordCallback)callback).getPlainPassword();
+ if(name != null)
+ {
+ authenticated = doLDAPNameAuthentication(name, password);
+ if(authenticated.getStatus()== AuthenticationResult.AuthenticationStatus.SUCCESS)
+ {
+ ((PlainPasswordCallback)callback).setAuthenticated(true);
+ }
+ }
+ }
+ else if (callback instanceof AuthorizeCallback)
+ {
+ ((AuthorizeCallback) callback).setAuthorized(authenticated != null && authenticated.getStatus() == AuthenticationResult.AuthenticationStatus.SUCCESS);
+ }
+ else
+ {
+ throw new UnsupportedCallbackException(callback);
+ }
+ }
+ }
+ }
+
+ private String getNameFromId(String id) throws NamingException
+ {
+ Hashtable<String,Object> env = createInitialDirContextEnvironment(_providerUrl);
+
+ env.put(Context.SECURITY_AUTHENTICATION, "none");
+ InitialDirContext ctx = createInitialDirContext(env);
+
+ try
+ {
+ SearchControls searchControls = new SearchControls();
+ searchControls.setReturningAttributes(new String[] {});
+ searchControls.setCountLimit(1l);
+ searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
+ NamingEnumeration<?> namingEnum = null;
+ String name = null;
+
+ namingEnum = ctx.search(_searchContext, _searchFilter, new String[] { id }, searchControls);
+ if(namingEnum.hasMore())
+ {
+ SearchResult result = (SearchResult) namingEnum.next();
+ name = result.getNameInNamespace();
+ }
+ return name;
+ }
+ finally
+ {
+ closeSafely(ctx);
+ }
+
+ }
+
+ private void closeSafely(InitialDirContext ctx)
+ {
+ try
+ {
+ if (ctx != null)
+ {
+ ctx.close();
+ ctx = null;
+ }
+ }
+ catch (Exception e)
+ {
+ _logger.warn("Exception closing InitialDirContext", e);
+ }
+ }
+
+ @Override
+ public void delete()
+ {
+ // nothing to do, no external resource is used
+ }
+}
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 340b3ff08c..007baf3422 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
@@ -30,6 +30,7 @@ import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import java.util.UUID;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ScheduledFuture;
@@ -302,16 +303,7 @@ public abstract class AbstractVirtualHost<X extends AbstractVirtualHost<X>> exte
}
@Override
- protected void authoriseSetAttribute(String name, Object expected, Object desired) throws AccessControlException
- {
- if (!_broker.getSecurityManager().authoriseConfiguringBroker(getName(), org.apache.qpid.server.model.VirtualHost.class, Operation.UPDATE))
- {
- throw new AccessControlException("Setting of virtual host attributes is denied");
- }
- }
-
- @Override
- protected void authoriseSetAttributes(Map<String, Object> attributes) throws AccessControlException
+ protected void authoriseSetAttributes(ConfiguredObject<?> modified, Set<String> attributes) throws AccessControlException
{
if (!_broker.getSecurityManager().authoriseConfiguringBroker(getName(), org.apache.qpid.server.model.VirtualHost.class, Operation.UPDATE))
{
diff --git a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/configuration/BrokerConfigurationStoreCreatorTest.java b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/configuration/BrokerConfigurationStoreCreatorTest.java
index b1c60351ee..8df5576715 100644
--- a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/configuration/BrokerConfigurationStoreCreatorTest.java
+++ b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/configuration/BrokerConfigurationStoreCreatorTest.java
@@ -43,6 +43,7 @@ import org.apache.qpid.server.model.Broker;
import org.apache.qpid.server.model.ConfiguredObjectFactory;
import org.apache.qpid.server.model.Model;
import org.apache.qpid.server.model.SystemContext;
+import org.apache.qpid.server.model.SystemContextImpl;
import org.apache.qpid.test.utils.QpidTestCase;
import org.apache.qpid.test.utils.TestFileUtils;
import org.apache.qpid.util.FileUtils;
@@ -68,7 +69,7 @@ public class BrokerConfigurationStoreCreatorTest extends QpidTestCase
_userStoreLocation = new File(TMP_FOLDER, "_store_" + System.currentTimeMillis() + "_" + getTestName());
final BrokerOptions brokerOptions = mock(BrokerOptions.class);
when(brokerOptions.getConfigurationStoreLocation()).thenReturn(_userStoreLocation.getAbsolutePath());
- _systemContext = new SystemContext(new TaskExecutor(),
+ _systemContext = new SystemContextImpl(new TaskExecutor(),
new ConfiguredObjectFactory(Model.getInstance()),
mock(EventLogger.class),
mock(LogRecorder.class),
diff --git a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/configuration/startup/BrokerRecovererTest.java b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/configuration/startup/BrokerRecovererTest.java
index edd6b647d6..04e41aa584 100644
--- a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/configuration/startup/BrokerRecovererTest.java
+++ b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/configuration/startup/BrokerRecovererTest.java
@@ -47,11 +47,13 @@ import org.apache.qpid.server.model.GroupProvider;
import org.apache.qpid.server.model.Model;
import org.apache.qpid.server.model.Port;
import org.apache.qpid.server.model.SystemContext;
+import org.apache.qpid.server.model.SystemContextImpl;
import org.apache.qpid.server.model.VirtualHost;
import org.apache.qpid.server.store.ConfiguredObjectRecord;
import org.apache.qpid.server.store.ConfiguredObjectRecordImpl;
import org.apache.qpid.server.store.MessageStore;
import org.apache.qpid.server.store.TestMemoryMessageStore;
+import org.apache.qpid.server.store.UnresolvedConfiguredObject;
public class BrokerRecovererTest extends TestCase
{
@@ -71,7 +73,7 @@ public class BrokerRecovererTest extends TestCase
super.setUp();
_configuredObjectFactory = new ConfiguredObjectFactory(Model.getInstance());
- _systemContext = new SystemContext(mock(TaskExecutor.class),
+ _systemContext = new SystemContextImpl(mock(TaskExecutor.class),
_configuredObjectFactory, mock(EventLogger.class), mock(LogRecorder.class), mock(BrokerOptions.class));
when(_brokerEntry.getId()).thenReturn(_brokerId);
@@ -305,7 +307,10 @@ public class BrokerRecovererTest extends TestCase
try
{
- Broker broker = (Broker) _configuredObjectFactory.recover(_brokerEntry, _systemContext).resolve();
+ UnresolvedConfiguredObject<? extends ConfiguredObject> recover =
+ _configuredObjectFactory.recover(_brokerEntry, _systemContext);
+
+ Broker<?> broker = (Broker<?>) recover.resolve();
broker.open();
fail("The broker creation should fail due to unsupported model version");
}
@@ -329,7 +334,9 @@ public class BrokerRecovererTest extends TestCase
try
{
- Broker broker = (Broker) _configuredObjectFactory.recover(_brokerEntry, _systemContext).resolve();
+ UnresolvedConfiguredObject<? extends ConfiguredObject> recover =
+ _configuredObjectFactory.recover(_brokerEntry, _systemContext);
+ Broker<?> broker = (Broker<?>) recover.resolve();
broker.open();
fail("The broker creation should fail due to unsupported model version");
}
diff --git a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/configuration/startup/FileTrustStoreCreationTest.java b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/configuration/startup/FileTrustStoreCreationTest.java
index 66f31a4e3d..f5e6772572 100644
--- a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/configuration/startup/FileTrustStoreCreationTest.java
+++ b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/configuration/startup/FileTrustStoreCreationTest.java
@@ -34,6 +34,7 @@ import org.apache.qpid.server.model.AbstractConfiguredObject;
import org.apache.qpid.server.model.Broker;
import org.apache.qpid.server.model.TrustStore;
import org.apache.qpid.server.security.FileTrustStore;
+import org.apache.qpid.server.security.FileTrustStoreImpl;
import org.apache.qpid.server.security.SecurityManager;
import org.apache.qpid.test.utils.QpidTestCase;
import org.apache.qpid.test.utils.TestSSLConstants;
@@ -48,7 +49,7 @@ public class FileTrustStoreCreationTest extends QpidTestCase
UUID id = UUID.randomUUID();
Broker broker = mock(Broker.class);
- final FileTrustStore trustStore = new FileTrustStore(id, broker, attributes);
+ final FileTrustStore trustStore = new FileTrustStoreImpl(id, broker, attributes);
trustStore.open();
assertNotNull("Trust store configured object is not created", trustStore);
assertEquals(id, trustStore.getId());
@@ -92,7 +93,7 @@ public class FileTrustStoreCreationTest extends QpidTestCase
properties.remove(mandatoryProperties[i]);
try
{
- TrustStore trustStore = new FileTrustStore(id, broker, properties);
+ TrustStore trustStore = new FileTrustStoreImpl(id, broker, properties);
trustStore.open();
fail("Cannot create key store without a " + mandatoryProperties[i]);
}
diff --git a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/configuration/startup/PreferencesProviderCreationTest.java b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/configuration/startup/PreferencesProviderCreationTest.java
index 9c224aead3..62b258e72e 100644
--- a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/configuration/startup/PreferencesProviderCreationTest.java
+++ b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/configuration/startup/PreferencesProviderCreationTest.java
@@ -25,6 +25,7 @@ import org.apache.qpid.server.model.AuthenticationProvider;
import org.apache.qpid.server.model.Broker;
import org.apache.qpid.server.model.PreferencesProvider;
import org.apache.qpid.server.model.adapter.FileSystemPreferencesProvider;
+import org.apache.qpid.server.model.adapter.FileSystemPreferencesProviderImpl;
import org.apache.qpid.server.util.BrokerTestHelper;
import org.apache.qpid.test.utils.QpidTestCase;
import org.apache.qpid.test.utils.TestFileUtils;
@@ -96,11 +97,12 @@ public class PreferencesProviderCreationTest extends QpidTestCase
try
{
attributes.put(FileSystemPreferencesProvider.PATH, file.getAbsolutePath());
- PreferencesProvider provider = new FileSystemPreferencesProvider(id,attributes,_authenticationProvider);
+ PreferencesProvider provider = new FileSystemPreferencesProviderImpl(id,attributes,_authenticationProvider);
assertNotNull("Preferences provider was not recovered", provider);
assertEquals("Unexpected name", "test-provider", provider.getName());
assertEquals("Unexpected id", id, provider.getId());
- assertEquals("Unexpected path", file.getAbsolutePath(), provider.getAttribute(FileSystemPreferencesProvider.PATH));
+ assertEquals("Unexpected path", file.getAbsolutePath(), provider.getAttribute(
+ FileSystemPreferencesProvider.PATH));
}
finally
{
diff --git a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/configuration/store/JsonConfigurationEntryStoreTest.java b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/configuration/store/JsonConfigurationEntryStoreTest.java
index 9f15953b3b..e6d47e6966 100644
--- a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/configuration/store/JsonConfigurationEntryStoreTest.java
+++ b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/configuration/store/JsonConfigurationEntryStoreTest.java
@@ -50,6 +50,7 @@ import org.apache.qpid.server.model.ConfiguredObjectFactory;
import org.apache.qpid.server.model.Model;
import org.apache.qpid.server.model.PreferencesProvider;
import org.apache.qpid.server.model.SystemContext;
+import org.apache.qpid.server.model.SystemContextImpl;
import org.apache.qpid.server.model.adapter.FileSystemPreferencesProvider;
import org.apache.qpid.server.store.DurableConfigurationStore;
import org.apache.qpid.test.utils.TestFileUtils;
@@ -99,7 +100,7 @@ public class JsonConfigurationEntryStoreTest extends ConfigurationEntryStoreTest
{
final BrokerOptions brokerOptions = mock(BrokerOptions.class);
when(brokerOptions.getConfigurationStoreLocation()).thenReturn(absolutePath);
- SystemContext context = new SystemContext(new TaskExecutor(),
+ SystemContext context = new SystemContextImpl(new TaskExecutor(),
new ConfiguredObjectFactory(Model.getInstance()),
mock(EventLogger.class),
mock(LogRecorder.class),
diff --git a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/configuration/store/ManagementModeStoreHandlerTest.java b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/configuration/store/ManagementModeStoreHandlerTest.java
index 43335cdea3..0fe116570a 100644
--- a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/configuration/store/ManagementModeStoreHandlerTest.java
+++ b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/configuration/store/ManagementModeStoreHandlerTest.java
@@ -50,6 +50,7 @@ import org.apache.qpid.server.model.Port;
import org.apache.qpid.server.model.Protocol;
import org.apache.qpid.server.model.State;
import org.apache.qpid.server.model.SystemContext;
+import org.apache.qpid.server.model.SystemContextImpl;
import org.apache.qpid.server.model.VirtualHost;
import org.apache.qpid.server.store.ConfiguredObjectRecord;
import org.apache.qpid.server.store.ConfiguredObjectRecordImpl;
@@ -75,7 +76,7 @@ public class ManagementModeStoreHandlerTest extends QpidTestCase
_store = mock(DurableConfigurationStore.class);
- _systemContext = new SystemContext(new TaskExecutor(), new ConfiguredObjectFactory(Model.getInstance()), mock(
+ _systemContext = new SystemContextImpl(new TaskExecutor(), new ConfiguredObjectFactory(Model.getInstance()), mock(
EventLogger.class), mock(LogRecorder.class), new BrokerOptions());
diff --git a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/configuration/store/MemoryConfigurationEntryStoreTest.java b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/configuration/store/MemoryConfigurationEntryStoreTest.java
index bdc43e6a99..bf8da6f364 100644
--- a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/configuration/store/MemoryConfigurationEntryStoreTest.java
+++ b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/configuration/store/MemoryConfigurationEntryStoreTest.java
@@ -43,6 +43,7 @@ import org.apache.qpid.server.model.Broker;
import org.apache.qpid.server.model.ConfiguredObjectFactory;
import org.apache.qpid.server.model.Model;
import org.apache.qpid.server.model.SystemContext;
+import org.apache.qpid.server.model.SystemContextImpl;
public class MemoryConfigurationEntryStoreTest extends ConfigurationEntryStoreTestCase
{
@@ -52,7 +53,7 @@ public class MemoryConfigurationEntryStoreTest extends ConfigurationEntryStoreTe
public void setUp() throws Exception
{
super.setUp();
- _systemContext = new SystemContext(new TaskExecutor(), new ConfiguredObjectFactory(Model.getInstance()),
+ _systemContext = new SystemContextImpl(new TaskExecutor(), new ConfiguredObjectFactory(Model.getInstance()),
mock(EventLogger.class), mock(LogRecorder.class),
new BrokerOptions());
diff --git a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/model/adapter/FileSystemPreferencesProviderFactoryTest.java b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/model/adapter/FileSystemPreferencesProviderFactoryTest.java
index 27ad46dcfc..db9d3db2d8 100644
--- a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/model/adapter/FileSystemPreferencesProviderFactoryTest.java
+++ b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/model/adapter/FileSystemPreferencesProviderFactoryTest.java
@@ -131,7 +131,8 @@ public class FileSystemPreferencesProviderFactoryTest extends QpidTestCase
assertNotNull("Preferences provider was not recovered", provider);
assertEquals("Unexpected name", "test-provider", provider.getName());
assertEquals("Unexpected id", id, provider.getId());
- assertEquals("Unexpected path", file.getAbsolutePath(), provider.getAttribute(FileSystemPreferencesProvider.PATH));
+ assertEquals("Unexpected path", file.getAbsolutePath(), provider.getAttribute(
+ FileSystemPreferencesProvider.PATH));
assertTrue("Preferences store file should exist", file.exists());
}
finally
diff --git a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/model/adapter/FileSystemPreferencesProviderTest.java b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/model/adapter/FileSystemPreferencesProviderTest.java
index 70cbfae9d4..30a12fbb19 100644
--- a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/model/adapter/FileSystemPreferencesProviderTest.java
+++ b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/model/adapter/FileSystemPreferencesProviderTest.java
@@ -34,6 +34,7 @@ import java.util.UUID;
import org.apache.qpid.server.configuration.updater.TaskExecutor;
import org.apache.qpid.server.model.AuthenticationProvider;
import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.model.ConfiguredObject;
import org.apache.qpid.server.model.State;
import org.apache.qpid.server.util.BrokerTestHelper;
import org.apache.qpid.test.utils.QpidTestCase;
@@ -43,7 +44,7 @@ public class FileSystemPreferencesProviderTest extends QpidTestCase
{
private static final String TEST_PREFERENCES = "{\"user1\":{\"pref1\":\"pref1User1Value\", \"pref2\": true, \"pref3\": 1.0, \"pref4\": 2},"
+ "\"user2\":{\"pref1\":\"pref1User2Value\", \"pref2\": false, \"pref3\": 2.0, \"pref4\": 3}}";
- private FileSystemPreferencesProvider _preferencesProvider;
+ private FileSystemPreferencesProviderImpl _preferencesProvider;
private AuthenticationProvider _authenticationProvider;
private Broker _broker;
private String _user1, _user2;
@@ -96,8 +97,8 @@ public class FileSystemPreferencesProviderTest extends QpidTestCase
{
Map<String, Object> attributes = new HashMap<String, Object>();
attributes.put(FileSystemPreferencesProvider.PATH, nonExistingFile.getAbsolutePath());
- attributes.put(FileSystemPreferencesProvider.NAME, getTestName());
- _preferencesProvider = new FileSystemPreferencesProvider(UUID.randomUUID(), attributes, _authenticationProvider);
+ attributes.put(ConfiguredObject.NAME, getTestName());
+ _preferencesProvider = new FileSystemPreferencesProviderImpl(UUID.randomUUID(), attributes, _authenticationProvider);
_preferencesProvider.createStoreIfNotExist();
assertEquals(State.INITIALISING, _preferencesProvider.getState());
assertTrue("Preferences file was not created", nonExistingFile.exists());
@@ -116,9 +117,9 @@ public class FileSystemPreferencesProviderTest extends QpidTestCase
try
{
Map<String, Object> attributes = new HashMap<String, Object>();
- attributes.put(FileSystemPreferencesProvider.NAME, getTestName());
+ attributes.put(ConfiguredObject.NAME, getTestName());
attributes.put(FileSystemPreferencesProvider.PATH, emptyPrefsFile.getAbsolutePath());
- _preferencesProvider = new FileSystemPreferencesProvider(UUID.randomUUID(), attributes, _authenticationProvider);
+ _preferencesProvider = new FileSystemPreferencesProviderImpl(UUID.randomUUID(), attributes, _authenticationProvider);
assertEquals(State.INITIALISING, _preferencesProvider.getState());
}
finally
@@ -273,12 +274,12 @@ public class FileSystemPreferencesProviderTest extends QpidTestCase
assertEquals("Unexpected user names", new HashSet<String>(Arrays.asList("user1", "user2")), userNames);
}
- private FileSystemPreferencesProvider createPreferencesProvider()
+ private FileSystemPreferencesProviderImpl createPreferencesProvider()
{
Map<String, Object> attributes = new HashMap<String, Object>();
attributes.put(FileSystemPreferencesProvider.PATH, _preferencesFile.getAbsolutePath());
- attributes.put(FileSystemPreferencesProvider.NAME, "test");
- return _preferencesProvider = new FileSystemPreferencesProvider(UUID.randomUUID(), attributes, _authenticationProvider);
+ attributes.put(ConfiguredObject.NAME, "test");
+ return _preferencesProvider = new FileSystemPreferencesProviderImpl(UUID.randomUUID(), attributes, _authenticationProvider);
}
private void assertUser1Preferences(Map<String, Object> preferences1)
diff --git a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/model/adapter/PortFactoryTest.java b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/model/adapter/PortFactoryTest.java
index 7d83d81d4e..80b29ac6b2 100644
--- a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/model/adapter/PortFactoryTest.java
+++ b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/model/adapter/PortFactoryTest.java
@@ -320,7 +320,7 @@ public class PortFactoryTest extends QpidTestCase
Port port = _portFactory.createPort(_portId, _broker, _attributes);
assertNotNull(port);
- assertFalse("Port should be a PortAdapter, not its AMQP-specific subclass", port instanceof AmqpPort);
+ assertFalse("Port should not be an AMQP-specific subclass", port instanceof AmqpPort);
assertEquals(_portId, port.getId());
assertEquals(_portNumber, port.getPort());
assertEquals(_tcpTransports, port.getTransports());
@@ -345,7 +345,7 @@ public class PortFactoryTest extends QpidTestCase
Port port = _portFactory.createPort(_portId, _broker, _attributes);
assertNotNull(port);
- assertFalse("Port should be a PortAdapter, not its AMQP-specific subclass", port instanceof AmqpPort);
+ assertFalse("Port not be an AMQP-specific port subclass", port instanceof AmqpPort);
assertEquals(_portId, port.getId());
assertEquals(_portNumber, port.getPort());
assertEquals(Collections.singleton(PortFactory.DEFAULT_TRANSPORT), port.getTransports());
diff --git a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationManagerTest.java b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationManagerTest.java
index c450d4970b..68adf2c5b6 100644
--- a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationManagerTest.java
+++ b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationManagerTest.java
@@ -48,13 +48,13 @@ public class ExternalAuthenticationManagerTest extends QpidTestCase
attrs.put(AuthenticationProvider.ID, UUID.randomUUID());
attrs.put(AuthenticationProvider.NAME, getTestName());
attrs.put("useFullDN",false);
- _manager = new ExternalAuthenticationManager(mock(Broker.class), attrs);
+ _manager = new ExternalAuthenticationManagerImpl(mock(Broker.class), attrs);
_manager.open();
HashMap<String, Object> attrsFullDN = new HashMap<String, Object>();
attrsFullDN.put(AuthenticationProvider.ID, UUID.randomUUID());
attrsFullDN.put(AuthenticationProvider.NAME, getTestName()+"FullDN");
attrsFullDN.put("useFullDN",true);
- _managerUsingFullDN = new ExternalAuthenticationManager(mock(Broker.class), attrsFullDN);
+ _managerUsingFullDN = new ExternalAuthenticationManagerImpl(mock(Broker.class), attrsFullDN);
_managerUsingFullDN.open();
}
@@ -198,7 +198,7 @@ public class ExternalAuthenticationManagerTest extends QpidTestCase
assertNull(saslServer.getAuthorizationID());
}
- private void createSaslServerTestImpl(AuthenticationManager manager) throws Exception
+ private void createSaslServerTestImpl(AuthenticationProvider<?> manager) throws Exception
{
SaslServer server = manager.createSaslServer("EXTERNAL", "example.example.com", null);
diff --git a/qpid/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/ACLFileAccessControlProvider.java b/qpid/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/ACLFileAccessControlProvider.java
index 55de9fc902..961eb25236 100644
--- a/qpid/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/ACLFileAccessControlProvider.java
+++ b/qpid/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/ACLFileAccessControlProvider.java
@@ -20,224 +20,13 @@
*/
package org.apache.qpid.server.security.access.plugins;
-import java.security.AccessControlException;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Map;
-import java.util.concurrent.atomic.AtomicReference;
-
-import org.apache.log4j.Logger;
-import org.apache.qpid.server.model.*;
-import org.apache.qpid.server.model.AbstractConfiguredObject;
-import org.apache.qpid.server.plugin.AccessControlProviderFactory;
-import org.apache.qpid.server.security.AccessControl;
-import org.apache.qpid.server.security.access.Operation;
-import org.apache.qpid.server.util.MapValueConverter;
+import org.apache.qpid.server.model.AccessControlProvider;
+import org.apache.qpid.server.model.ManagedAttribute;
+import org.apache.qpid.server.model.ManagedObject;
@ManagedObject( category = false, type="AclFile" )
-public class ACLFileAccessControlProvider
- extends AbstractConfiguredObject<ACLFileAccessControlProvider>
- implements AccessControlProvider<ACLFileAccessControlProvider>
+public interface ACLFileAccessControlProvider<X extends ACLFileAccessControlProvider<X>> extends AccessControlProvider<X>
{
- private static final Logger LOGGER = Logger.getLogger(ACLFileAccessControlProvider.class);
-
- protected DefaultAccessControl _accessControl;
- protected final Broker _broker;
-
- protected Map<String, AccessControlProviderFactory> _factories;
- private AtomicReference<State> _state;
-
- @ManagedAttributeField
- private String _path;
-
- public ACLFileAccessControlProvider(Broker broker,
- Map<String, Object> attributes)
- {
- super(parentsMap(broker),
- attributes, broker.getTaskExecutor());
-
-
- _broker = broker;
-
- State state = MapValueConverter.getEnumAttribute(State.class, STATE, attributes, State.INITIALISING);
- _state = new AtomicReference<State>(state);
-
- }
-
- @Override
- protected void onOpen()
- {
- super.onOpen();
- _accessControl = new DefaultAccessControl(getPath(), _broker);
- }
-
@ManagedAttribute( automate = true, mandatory = true )
- public String getPath()
- {
- return _path;
- }
-
- @Override
- public String setName(String currentName, String desiredName) throws IllegalStateException, AccessControlException
- {
- return null;
- }
-
- @Override
- public State getState()
- {
- return _state.get();
- }
-
- @Override
- public boolean isDurable()
- {
- return true;
- }
-
- @Override
- public void setDurable(boolean durable)
- throws IllegalStateException, AccessControlException, IllegalArgumentException
- {
- }
-
- @Override
- public LifetimePolicy getLifetimePolicy()
- {
- return LifetimePolicy.PERMANENT;
- }
-
- @Override
- public LifetimePolicy setLifetimePolicy(LifetimePolicy expected, LifetimePolicy desired)
- throws IllegalStateException, AccessControlException, IllegalArgumentException
- {
- return null;
- }
-
- @Override
- public Collection<String> getAttributeNames()
- {
- return getAttributeNames(getClass());
- }
-
- @Override
- public Object getAttribute(String name)
- {
- if(DURABLE.equals(name))
- {
- return true;
- }
- else if(LIFETIME_POLICY.equals(name))
- {
- return LifetimePolicy.PERMANENT;
- }
- else if(STATE.equals(name))
- {
- return getState();
- }
- return super.getAttribute(name);
- }
-
- @Override
- public <C extends ConfiguredObject> Collection<C> getChildren(Class<C> clazz)
- {
- return Collections.emptySet();
- }
-
- @Override
- public boolean setState(State currentState, State desiredState)
- throws IllegalStateTransitionException, AccessControlException
- {
- State state = _state.get();
-
- if(desiredState == State.DELETED)
- {
- deleted();
- return _state.compareAndSet(state, State.DELETED);
- }
- else if (desiredState == State.QUIESCED)
- {
- return _state.compareAndSet(state, State.QUIESCED);
- }
- else if(desiredState == State.ACTIVE)
- {
- if ((state == State.INITIALISING || state == State.QUIESCED) && _state.compareAndSet(state, State.ACTIVE))
- {
- try
- {
- _accessControl.open();
- return true;
- }
- catch(RuntimeException e)
- {
- _state.compareAndSet(State.ACTIVE, State.ERRORED);
- if (_broker.isManagementMode())
- {
- LOGGER.warn("Failed to activate ACL provider: " + getName(), e);
- }
- else
- {
- throw e;
- }
- }
- }
- else
- {
- throw new IllegalStateException("Can't activate access control provider in " + state + " state");
- }
- }
- else if(desiredState == State.STOPPED)
- {
- if(_state.compareAndSet(state, State.STOPPED))
- {
- _accessControl.close();
- return true;
- }
-
- return false;
- }
- return false;
- }
-
-
- @Override
- protected void changeAttributes(Map<String, Object> attributes)
- {
- throw new UnsupportedOperationException("Changing attributes on AccessControlProvider is not supported");
- }
-
- @Override
- protected void authoriseSetDesiredState(State currentState, State desiredState) throws AccessControlException
- {
- if(desiredState == State.DELETED)
- {
- if (!_broker.getSecurityManager().authoriseConfiguringBroker(getName(), AccessControlProvider.class, Operation.DELETE))
- {
- throw new AccessControlException("Deletion of AccessControlProvider is denied");
- }
- }
- }
-
- @Override
- protected void authoriseSetAttribute(String name, Object expected, Object desired) throws AccessControlException
- {
- if (!_broker.getSecurityManager().authoriseConfiguringBroker(getName(), AccessControlProvider.class, Operation.UPDATE))
- {
- throw new AccessControlException("Setting of AccessControlProvider attributes is denied");
- }
- }
-
- @Override
- protected void authoriseSetAttributes(Map<String, Object> attributes) throws AccessControlException
- {
- if (!_broker.getSecurityManager().authoriseConfiguringBroker(getName(), AccessControlProvider.class, Operation.UPDATE))
- {
- throw new AccessControlException("Setting of AccessControlProvider attributes is denied");
- }
- }
-
- public AccessControl getAccessControl()
- {
- return _accessControl;
- }
+ String getPath();
}
diff --git a/qpid/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/ACLFileAccessControlProviderFactory.java b/qpid/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/ACLFileAccessControlProviderFactory.java
index e9de449804..f20d468a14 100644
--- a/qpid/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/ACLFileAccessControlProviderFactory.java
+++ b/qpid/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/ACLFileAccessControlProviderFactory.java
@@ -20,21 +20,21 @@
*/
package org.apache.qpid.server.security.access.plugins;
+import java.util.Map;
+
import org.apache.qpid.server.model.AbstractConfiguredObjectTypeFactory;
import org.apache.qpid.server.model.Broker;
import org.apache.qpid.server.model.ConfiguredObject;
import org.apache.qpid.server.plugin.AccessControlProviderFactory;
import org.apache.qpid.server.util.ResourceBundleLoader;
-import java.util.Map;
-
-public class ACLFileAccessControlProviderFactory extends AbstractConfiguredObjectTypeFactory<ACLFileAccessControlProvider> implements AccessControlProviderFactory<ACLFileAccessControlProvider>
+public class ACLFileAccessControlProviderFactory extends AbstractConfiguredObjectTypeFactory<ACLFileAccessControlProviderImpl> implements AccessControlProviderFactory<ACLFileAccessControlProviderImpl>
{
public static final String RESOURCE_BUNDLE = "org.apache.qpid.server.security.access.plugins.FileAccessControlProviderAttributeDescriptions";
public ACLFileAccessControlProviderFactory()
{
- super(ACLFileAccessControlProvider.class);
+ super(ACLFileAccessControlProviderImpl.class);
}
@Override
@@ -44,10 +44,10 @@ public class ACLFileAccessControlProviderFactory extends AbstractConfiguredObjec
}
@Override
- public ACLFileAccessControlProvider createInstance(final Map<String, Object> attributes,
+ public ACLFileAccessControlProviderImpl createInstance(final Map<String, Object> attributes,
final ConfiguredObject<?>... parents)
{
- return new ACLFileAccessControlProvider(getParent(Broker.class,parents), attributes);
+ return new ACLFileAccessControlProviderImpl(getParent(Broker.class,parents), attributes);
}
}
diff --git a/qpid/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/ACLFileAccessControlProviderImpl.java b/qpid/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/ACLFileAccessControlProviderImpl.java
new file mode 100644
index 0000000000..db2b44c5e6
--- /dev/null
+++ b/qpid/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/ACLFileAccessControlProviderImpl.java
@@ -0,0 +1,241 @@
+/*
+ *
+ * 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.access.plugins;
+
+import java.security.AccessControlException;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicReference;
+
+import org.apache.log4j.Logger;
+
+import org.apache.qpid.server.model.AbstractConfiguredObject;
+import org.apache.qpid.server.model.AccessControlProvider;
+import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.model.ConfiguredObject;
+import org.apache.qpid.server.model.IllegalStateTransitionException;
+import org.apache.qpid.server.model.LifetimePolicy;
+import org.apache.qpid.server.model.ManagedAttributeField;
+import org.apache.qpid.server.model.State;
+import org.apache.qpid.server.plugin.AccessControlProviderFactory;
+import org.apache.qpid.server.security.AccessControl;
+import org.apache.qpid.server.security.access.Operation;
+import org.apache.qpid.server.util.MapValueConverter;
+
+public class ACLFileAccessControlProviderImpl
+ extends AbstractConfiguredObject<ACLFileAccessControlProviderImpl>
+ implements ACLFileAccessControlProvider<ACLFileAccessControlProviderImpl>
+{
+ private static final Logger LOGGER = Logger.getLogger(ACLFileAccessControlProviderImpl.class);
+
+ protected DefaultAccessControl _accessControl;
+ protected final Broker _broker;
+
+ protected Map<String, AccessControlProviderFactory> _factories;
+ private AtomicReference<State> _state;
+
+ @ManagedAttributeField
+ private String _path;
+
+ public ACLFileAccessControlProviderImpl(Broker broker,
+ Map<String, Object> attributes)
+ {
+ super(parentsMap(broker),
+ attributes, broker.getTaskExecutor());
+
+
+ _broker = broker;
+
+ State state = MapValueConverter.getEnumAttribute(State.class, STATE, attributes, State.INITIALISING);
+ _state = new AtomicReference<State>(state);
+
+ }
+
+ @Override
+ protected void onOpen()
+ {
+ super.onOpen();
+ _accessControl = new DefaultAccessControl(getPath(), _broker);
+ }
+
+ @Override
+ public String getPath()
+ {
+ return _path;
+ }
+
+ @Override
+ public String setName(String currentName, String desiredName) throws IllegalStateException, AccessControlException
+ {
+ return null;
+ }
+
+ @Override
+ public State getState()
+ {
+ return _state.get();
+ }
+
+ @Override
+ public boolean isDurable()
+ {
+ return true;
+ }
+
+ @Override
+ public void setDurable(boolean durable)
+ throws IllegalStateException, AccessControlException, IllegalArgumentException
+ {
+ }
+
+ @Override
+ public LifetimePolicy getLifetimePolicy()
+ {
+ return LifetimePolicy.PERMANENT;
+ }
+
+ @Override
+ public LifetimePolicy setLifetimePolicy(LifetimePolicy expected, LifetimePolicy desired)
+ throws IllegalStateException, AccessControlException, IllegalArgumentException
+ {
+ return null;
+ }
+
+ @Override
+ public Collection<String> getAttributeNames()
+ {
+ return getAttributeNames(getClass());
+ }
+
+ @Override
+ public Object getAttribute(String name)
+ {
+ if(DURABLE.equals(name))
+ {
+ return true;
+ }
+ else if(LIFETIME_POLICY.equals(name))
+ {
+ return LifetimePolicy.PERMANENT;
+ }
+ else if(STATE.equals(name))
+ {
+ return getState();
+ }
+ return super.getAttribute(name);
+ }
+
+ @Override
+ public <C extends ConfiguredObject> Collection<C> getChildren(Class<C> clazz)
+ {
+ return Collections.emptySet();
+ }
+
+ @Override
+ public boolean setState(State currentState, State desiredState)
+ throws IllegalStateTransitionException, AccessControlException
+ {
+ State state = _state.get();
+
+ if(desiredState == State.DELETED)
+ {
+ deleted();
+ return _state.compareAndSet(state, State.DELETED);
+ }
+ else if (desiredState == State.QUIESCED)
+ {
+ return _state.compareAndSet(state, State.QUIESCED);
+ }
+ else if(desiredState == State.ACTIVE)
+ {
+ if ((state == State.INITIALISING || state == State.QUIESCED) && _state.compareAndSet(state, State.ACTIVE))
+ {
+ try
+ {
+ _accessControl.open();
+ return true;
+ }
+ catch(RuntimeException e)
+ {
+ _state.compareAndSet(State.ACTIVE, State.ERRORED);
+ if (_broker.isManagementMode())
+ {
+ LOGGER.warn("Failed to activate ACL provider: " + getName(), e);
+ }
+ else
+ {
+ throw e;
+ }
+ }
+ }
+ else
+ {
+ throw new IllegalStateException("Can't activate access control provider in " + state + " state");
+ }
+ }
+ else if(desiredState == State.STOPPED)
+ {
+ if(_state.compareAndSet(state, State.STOPPED))
+ {
+ _accessControl.close();
+ return true;
+ }
+
+ return false;
+ }
+ return false;
+ }
+
+
+ @Override
+ protected void changeAttributes(Map<String, Object> attributes)
+ {
+ throw new UnsupportedOperationException("Changing attributes on AccessControlProvider is not supported");
+ }
+
+ @Override
+ protected void authoriseSetDesiredState(State currentState, State desiredState) throws AccessControlException
+ {
+ if(desiredState == State.DELETED)
+ {
+ if (!_broker.getSecurityManager().authoriseConfiguringBroker(getName(), AccessControlProvider.class, Operation.DELETE))
+ {
+ throw new AccessControlException("Deletion of AccessControlProvider is denied");
+ }
+ }
+ }
+
+ @Override
+ protected void authoriseSetAttributes(ConfiguredObject<?> modified, Set<String> attributes) throws AccessControlException
+ {
+ if (!_broker.getSecurityManager().authoriseConfiguringBroker(getName(), AccessControlProvider.class, Operation.UPDATE))
+ {
+ throw new AccessControlException("Setting of AccessControlProvider attributes is denied");
+ }
+ }
+
+ public AccessControl getAccessControl()
+ {
+ return _accessControl;
+ }
+}
diff --git a/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagement.java b/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagement.java
index 555c12037d..5427d81bd5 100644
--- a/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagement.java
+++ b/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagement.java
@@ -69,7 +69,7 @@ import org.apache.qpid.server.management.plugin.servlet.rest.StructureServlet;
import org.apache.qpid.server.management.plugin.servlet.rest.UserPreferencesServlet;
import org.apache.qpid.server.model.*;
import org.apache.qpid.server.model.adapter.AbstractPluginAdapter;
-import org.apache.qpid.server.model.port.PortWithAuthProvider;
+import org.apache.qpid.server.model.port.AbstractPortWithAuthProvider;
import org.apache.qpid.server.util.MapValueConverter;
import org.apache.qpid.server.util.ServerScopedRuntimeException;
import org.apache.qpid.transport.network.security.ssl.QpidMultipleTrustManager;
@@ -218,8 +218,10 @@ public class HttpManagement extends AbstractPluginAdapter<HttpManagement> implem
throw new IllegalConfigurationException("Key store is not configured. Cannot start management on HTTPS port without keystore");
}
SslContextFactory factory = new SslContextFactory();
- final boolean needClientAuth = port instanceof PortWithAuthProvider && ((PortWithAuthProvider)port).getNeedClientAuth();
- final boolean wantClientAuth = port instanceof PortWithAuthProvider && ((PortWithAuthProvider)port).getWantClientAuth();
+ final boolean needClientAuth = port instanceof AbstractPortWithAuthProvider
+ && ((AbstractPortWithAuthProvider)port).getNeedClientAuth();
+ final boolean wantClientAuth = port instanceof AbstractPortWithAuthProvider
+ && ((AbstractPortWithAuthProvider)port).getWantClientAuth();
boolean needClientCert = needClientAuth || wantClientAuth;
if (needClientCert && trustStores.isEmpty())
{
diff --git a/qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagedObjectRegistry.java b/qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagedObjectRegistry.java
index f359cec694..79465dbf39 100644
--- a/qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagedObjectRegistry.java
+++ b/qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagedObjectRegistry.java
@@ -81,13 +81,13 @@ public class JMXManagedObjectRegistry implements ManagedObjectRegistry
public JMXManagedObjectRegistry(
Broker broker,
Port connectorPort, Port registryPort,
- JMXManagement jmxManagement)
+ JMXManagementPlugin jmxManagement)
{
_broker = broker;
_registryPort = registryPort;
_connectorPort = connectorPort;
- boolean usePlatformServer = (Boolean)jmxManagement.getAttribute(JMXManagement.USE_PLATFORM_MBEAN_SERVER);
+ boolean usePlatformServer = (Boolean)jmxManagement.getAttribute(JMXManagementPlugin.USE_PLATFORM_MBEAN_SERVER);
_mbeanServer =
usePlatformServer ? ManagementFactory.getPlatformMBeanServer()
diff --git a/qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagementFactory.java b/qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagementFactory.java
index dd21225099..0d8b36cdd9 100644
--- a/qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagementFactory.java
+++ b/qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagementFactory.java
@@ -18,27 +18,27 @@
*/
package org.apache.qpid.server.jmx;
-import org.apache.qpid.server.model.AbstractConfiguredObjectTypeFactory;
-import org.apache.qpid.server.model.Broker;
-import org.apache.qpid.server.model.ConfiguredObject;
-
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
-public class JMXManagementFactory extends AbstractConfiguredObjectTypeFactory<JMXManagement>
+import org.apache.qpid.server.model.AbstractConfiguredObjectTypeFactory;
+import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.model.ConfiguredObject;
+
+public class JMXManagementFactory extends AbstractConfiguredObjectTypeFactory<JMXManagementPluginImpl>
{
public JMXManagementFactory()
{
- super(JMXManagement.class);
+ super(JMXManagementPluginImpl.class);
}
@Override
- public JMXManagement createInstance(final Map<String, Object> attributes, final ConfiguredObject<?>... parents)
+ public JMXManagementPluginImpl createInstance(final Map<String, Object> attributes, final ConfiguredObject<?>... parents)
{
Map<String,Object> attributesWithoutId = new HashMap<String, Object>(attributes);
Object idObj = attributesWithoutId.remove(ConfiguredObject.ID);
UUID id = idObj == null ? UUID.randomUUID() : idObj instanceof UUID ? (UUID) idObj : UUID.fromString(idObj.toString());
- return new JMXManagement(id, getParent(Broker.class,parents),attributes);
+ return new JMXManagementPluginImpl(id, getParent(Broker.class,parents),attributes);
}
}
diff --git a/qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagementPlugin.java b/qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagementPlugin.java
new file mode 100644
index 0000000000..472be5a1a1
--- /dev/null
+++ b/qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagementPlugin.java
@@ -0,0 +1,35 @@
+/*
+ *
+ * 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.jmx;
+
+import org.apache.qpid.server.model.*;
+
+@org.apache.qpid.server.model.ManagedObject( category = false , type = "MANAGEMENT-JMX" )
+public interface JMXManagementPlugin<X extends JMXManagementPlugin<X>> extends Plugin<X>
+{
+ String PLUGIN_TYPE = "MANAGEMENT-JMX";
+ // attributes
+ String USE_PLATFORM_MBEAN_SERVER = "usePlatformMBeanServer";
+ String DEFAULT_USE_PLATFORM_MBEAN_SERVER = "true";
+
+ @ManagedAttribute( automate = true, defaultValue = DEFAULT_USE_PLATFORM_MBEAN_SERVER )
+ boolean getUsePlatformMBeanServer();
+}
diff --git a/qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagement.java b/qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagementPluginImpl.java
index e03633f026..61bd7ab1a0 100644
--- a/qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagement.java
+++ b/qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagementPluginImpl.java
@@ -43,9 +43,7 @@ import org.apache.qpid.server.model.AuthenticationProvider;
import org.apache.qpid.server.model.Broker;
import org.apache.qpid.server.model.ConfigurationChangeListener;
import org.apache.qpid.server.model.ConfiguredObject;
-import org.apache.qpid.server.model.ManagedAttribute;
import org.apache.qpid.server.model.ManagedAttributeField;
-import org.apache.qpid.server.model.ManagedObject;
import org.apache.qpid.server.model.PasswordCredentialManagingAuthenticationProvider;
import org.apache.qpid.server.model.Port;
import org.apache.qpid.server.model.Protocol;
@@ -56,20 +54,16 @@ import org.apache.qpid.server.plugin.QpidServiceLoader;
import org.apache.qpid.server.util.MapValueConverter;
import org.apache.qpid.server.util.ServerScopedRuntimeException;
-@ManagedObject( category = false , type = "MANAGEMENT-JMX" )
-public class JMXManagement extends AbstractPluginAdapter<JMXManagement> implements ConfigurationChangeListener
+public class JMXManagementPluginImpl
+ extends AbstractPluginAdapter<JMXManagementPluginImpl> implements ConfigurationChangeListener,
+ JMXManagementPlugin<JMXManagementPluginImpl>
{
- private static final Logger LOGGER = Logger.getLogger(JMXManagement.class);
+ private static final Logger LOGGER = Logger.getLogger(JMXManagementPluginImpl.class);
- public static final String PLUGIN_TYPE = "MANAGEMENT-JMX";
-
- // attributes
- public static final String USE_PLATFORM_MBEAN_SERVER = "usePlatformMBeanServer";
public static final String NAME = "name";
// default values
public static final String DEFAULT_NAME = "JMXManagement";
- public static final boolean DEFAULT_USE_PLATFORM_MBEAN_SERVER = true;
@SuppressWarnings("serial")
private static final Map<String, Type> ATTRIBUTE_TYPES = new HashMap<String, Type>(){{
@@ -86,7 +80,7 @@ public class JMXManagement extends AbstractPluginAdapter<JMXManagement> implemen
@ManagedAttributeField
private boolean _usePlatformMBeanServer;
- public JMXManagement(UUID id, Broker broker, Map<String, Object> attributes)
+ public JMXManagementPluginImpl(UUID id, Broker broker, Map<String, Object> attributes)
{
super(id, attributes, broker);
}
@@ -321,7 +315,7 @@ public class JMXManagement extends AbstractPluginAdapter<JMXManagement> implemen
@Override
public Collection<String> getAttributeNames()
{
- return getAttributeNames(JMXManagement.class);
+ return getAttributeNames(JMXManagementPluginImpl.class);
}
@Override
@@ -335,9 +329,9 @@ public class JMXManagement extends AbstractPluginAdapter<JMXManagement> implemen
private void validateAttributes(Map<String, Object> convertedAttributes)
{
- if(convertedAttributes.containsKey(JMXManagement.NAME))
+ if(convertedAttributes.containsKey(JMXManagementPluginImpl.NAME))
{
- String newName = (String) convertedAttributes.get(JMXManagement.NAME);
+ String newName = (String) convertedAttributes.get(JMXManagementPluginImpl.NAME);
if(!getName().equals(newName))
{
throw new IllegalConfigurationException("Changing the name of jmx management plugin is not allowed");
@@ -360,7 +354,7 @@ public class JMXManagement extends AbstractPluginAdapter<JMXManagement> implemen
}
}
- @ManagedAttribute( automate = true, defaultValue = "true" )
+ @Override
public boolean getUsePlatformMBeanServer()
{
return _usePlatformMBeanServer;
diff --git a/qpid/java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/server/jmx/JMXManagementFactoryTest.java b/qpid/java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/server/jmx/JMXManagementFactoryTest.java
index e1e3db763c..de5b056d9d 100644
--- a/qpid/java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/server/jmx/JMXManagementFactoryTest.java
+++ b/qpid/java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/server/jmx/JMXManagementFactoryTest.java
@@ -38,14 +38,14 @@ public class JMXManagementFactoryTest extends QpidTestCase
public void testJMXConfigured() throws Exception
{
_attributes.put(ConfiguredObject.ID,UUID.randomUUID());
- _attributes.put(ConfiguredObject.TYPE, JMXManagement.PLUGIN_TYPE);
+ _attributes.put(ConfiguredObject.TYPE, JMXManagementPlugin.PLUGIN_TYPE);
_attributes.put(ConfiguredObject.NAME, getName());
- JMXManagement jmxManagement = _jmxManagementFactory.createInstance( _attributes, _broker);
+ JMXManagementPlugin jmxManagement = _jmxManagementFactory.createInstance( _attributes, _broker);
jmxManagement.open();
assertNotNull(jmxManagement);
- assertEquals("Unexpected plugin type", JMXManagement.PLUGIN_TYPE, jmxManagement.getType());
- assertEquals("Unexpected default mbean platform", JMXManagement.DEFAULT_USE_PLATFORM_MBEAN_SERVER, jmxManagement.getAttribute(JMXManagement.USE_PLATFORM_MBEAN_SERVER));
+ assertEquals("Unexpected plugin type", JMXManagementPlugin.PLUGIN_TYPE, jmxManagement.getType());
+ assertEquals("Unexpected default mbean platform", Boolean.parseBoolean(JMXManagementPlugin.DEFAULT_USE_PLATFORM_MBEAN_SERVER), jmxManagement.getUsePlatformMBeanServer());
}
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/systest/rest/QueueRestTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/systest/rest/QueueRestTest.java
index 3063f9182c..8c8db3b358 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/systest/rest/QueueRestTest.java
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/systest/rest/QueueRestTest.java
@@ -147,7 +147,7 @@ public class QueueRestTest extends QpidRestTestCase
attributes.put(Queue.MAXIMUM_DELIVERY_ATTEMPTS, 10);
responseCode = getRestTestHelper().submitRequest("/rest/queue/test/" + queueName, "PUT", attributes);
- assertEquals("Setting of queue attribites should be allowed", 200, responseCode);
+ assertEquals("Setting of queue attributes should be allowed", 200, responseCode);
Map<String, Object> queueData = getRestTestHelper().getJsonAsSingletonList("/rest/queue/test/" + queueName);
assertEquals("Unexpected " + Queue.QUEUE_FLOW_CONTROL_SIZE_BYTES, 100000, queueData.get(Queue.QUEUE_FLOW_CONTROL_SIZE_BYTES) );
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/test/utils/TestBrokerConfiguration.java b/qpid/java/systests/src/main/java/org/apache/qpid/test/utils/TestBrokerConfiguration.java
index 645fc57677..99c0e351d4 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/test/utils/TestBrokerConfiguration.java
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/test/utils/TestBrokerConfiguration.java
@@ -42,7 +42,7 @@ import org.apache.qpid.server.model.GroupProvider;
import org.apache.qpid.server.model.Model;
import org.apache.qpid.server.model.Plugin;
import org.apache.qpid.server.model.PreferencesProvider;
-import org.apache.qpid.server.model.SystemContext;
+import org.apache.qpid.server.model.SystemContextImpl;
import org.apache.qpid.server.model.UUIDGenerator;
import org.apache.qpid.server.security.access.FileAccessControlProviderConstants;
import org.apache.qpid.server.security.group.FileGroupManagerFactory;
@@ -75,7 +75,7 @@ public class TestBrokerConfiguration
public TestBrokerConfiguration(String storeType, String intialStoreLocation)
{
- _store = new MemoryConfigurationEntryStore(new SystemContext(new TaskExecutor(), new ConfiguredObjectFactory(
+ _store = new MemoryConfigurationEntryStore(new SystemContextImpl(new TaskExecutor(), new ConfiguredObjectFactory(
Model.getInstance()),
mock(EventLogger.class), mock(LogRecorder.class),
mock(BrokerOptions.class)),