diff options
| author | Alex Rudyy <orudyy@apache.org> | 2013-09-14 11:25:57 +0000 |
|---|---|---|
| committer | Alex Rudyy <orudyy@apache.org> | 2013-09-14 11:25:57 +0000 |
| commit | fffdab69bb44b9b9e8361a9d0ad250f48129a117 (patch) | |
| tree | 4103d8393d3cb93181f849142fcbe83d7b305c0e /qpid/java/broker | |
| parent | 2af29db3885316bbb42c99f423cbc9f50619c925 (diff) | |
| download | qpid-python-fffdab69bb44b9b9e8361a9d0ad250f48129a117.tar.gz | |
QPID-5138: Integrate preferences provider into Broker model, create association between preferences provider and authentication provider, add preferences provider recoverer and factory
git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@1523218 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'qpid/java/broker')
26 files changed, 788 insertions, 63 deletions
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/AuthenticationProviderRecoverer.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/AuthenticationProviderRecoverer.java index 2bf0cdbab3..8eec88d556 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/AuthenticationProviderRecoverer.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/AuthenticationProviderRecoverer.java @@ -20,23 +20,29 @@ */ package org.apache.qpid.server.configuration.startup; +import java.util.Collection; import java.util.Map; import org.apache.qpid.server.configuration.ConfigurationEntry; import org.apache.qpid.server.configuration.ConfiguredObjectRecoverer; +import org.apache.qpid.server.configuration.IllegalConfigurationException; import org.apache.qpid.server.configuration.RecovererProvider; +import org.apache.qpid.server.configuration.store.StoreConfigurationChangeListener; 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.PreferencesProvider; import org.apache.qpid.server.model.adapter.AuthenticationProviderFactory; public class AuthenticationProviderRecoverer implements ConfiguredObjectRecoverer<AuthenticationProvider> { private final AuthenticationProviderFactory _authenticationProviderFactory; + private final StoreConfigurationChangeListener _storeChangeListener; - public AuthenticationProviderRecoverer(AuthenticationProviderFactory authenticationProviderFactory) + public AuthenticationProviderRecoverer(AuthenticationProviderFactory authenticationProviderFactory, StoreConfigurationChangeListener storeChangeListener) { _authenticationProviderFactory = authenticationProviderFactory; + _storeChangeListener = storeChangeListener; } @Override @@ -46,6 +52,44 @@ public class AuthenticationProviderRecoverer implements ConfiguredObjectRecovere Map<String, Object> attributes = configurationEntry.getAttributes(); AuthenticationProvider authenticationProvider = _authenticationProviderFactory.recover(configurationEntry.getId(), attributes, broker); + Map<String, Collection<ConfigurationEntry>> childEntries = configurationEntry.getChildren(); + + for (String type : childEntries.keySet()) + { + recoverType(recovererProvider, _storeChangeListener, authenticationProvider, childEntries, type); + } + return authenticationProvider; } + + private void recoverType(RecovererProvider recovererProvider, + StoreConfigurationChangeListener storeChangeListener, + AuthenticationProvider authenticationProvider, + Map<String, Collection<ConfigurationEntry>> childEntries, + String type) + { + ConfiguredObjectRecoverer<?> recoverer = recovererProvider.getRecoverer(type); + if (recoverer == null) + { + throw new IllegalConfigurationException("Cannot recover entry for the type '" + type + "' from broker"); + } + Collection<ConfigurationEntry> entries = childEntries.get(type); + for (ConfigurationEntry childEntry : entries) + { + ConfiguredObject object = recoverer.create(recovererProvider, childEntry, authenticationProvider); + if (object == null) + { + throw new IllegalConfigurationException("Cannot create configured object for the entry " + childEntry); + } + if (object instanceof PreferencesProvider) + { + authenticationProvider.setPreferencesProvider((PreferencesProvider)object); + } + else + { + throw new IllegalConfigurationException("Cannot associate " + object + " with authentication provider " + authenticationProvider); + } + object.addChangeListener(storeChangeListener); + } + } } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/BrokerRecoverer.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/BrokerRecoverer.java index ae7e699264..4923565e26 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/BrokerRecoverer.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/BrokerRecoverer.java @@ -47,6 +47,7 @@ import org.apache.qpid.server.model.adapter.AuthenticationProviderFactory; import org.apache.qpid.server.model.adapter.BrokerAdapter; import org.apache.qpid.server.model.adapter.GroupProviderFactory; import org.apache.qpid.server.model.adapter.PortFactory; +import org.apache.qpid.server.model.adapter.PreferencesProviderCreator; import org.apache.qpid.server.stats.StatisticsGatherer; import org.apache.qpid.server.util.MapValueConverter; import org.apache.qpid.server.virtualhost.VirtualHostRegistry; @@ -65,10 +66,13 @@ public class BrokerRecoverer implements ConfiguredObjectRecoverer<Broker> private final TaskExecutor _taskExecutor; private final BrokerOptions _brokerOptions; private final GroupProviderFactory _groupProviderFactory; + private final StoreConfigurationChangeListener _storeChangeListener; + private final PreferencesProviderCreator _preferencesProviderCreator; public BrokerRecoverer(AuthenticationProviderFactory authenticationProviderFactory, GroupProviderFactory groupProviderFactory, - AccessControlProviderFactory accessControlProviderFactory, PortFactory portFactory, StatisticsGatherer statisticsGatherer, - VirtualHostRegistry virtualHostRegistry, LogRecorder logRecorder, RootMessageLogger rootMessageLogger, TaskExecutor taskExecutor, BrokerOptions brokerOptions) + AccessControlProviderFactory accessControlProviderFactory, PortFactory portFactory, PreferencesProviderCreator preferencesProviderFactory, StatisticsGatherer statisticsGatherer, + VirtualHostRegistry virtualHostRegistry, LogRecorder logRecorder, RootMessageLogger rootMessageLogger, TaskExecutor taskExecutor, + BrokerOptions brokerOptions, StoreConfigurationChangeListener storeChangeListener) { _groupProviderFactory = groupProviderFactory; _portFactory = portFactory; @@ -80,6 +84,8 @@ public class BrokerRecoverer implements ConfiguredObjectRecoverer<Broker> _rootMessageLogger = rootMessageLogger; _taskExecutor = taskExecutor; _brokerOptions = brokerOptions; + _storeChangeListener = storeChangeListener; + _preferencesProviderCreator = preferencesProviderFactory; } @Override @@ -90,12 +96,11 @@ public class BrokerRecoverer implements ConfiguredObjectRecoverer<Broker> attributesCopy.put(Broker.MODEL_VERSION, Model.MODEL_VERSION); - StoreConfigurationChangeListener storeChangeListener = new StoreConfigurationChangeListener(entry.getStore()); BrokerAdapter broker = new BrokerAdapter(entry.getId(), attributesCopy, _statisticsGatherer, _virtualHostRegistry, - _logRecorder, _rootMessageLogger, _authenticationProviderFactory, _groupProviderFactory, _accessControlProviderFactory, - _portFactory, _taskExecutor, entry.getStore(), _brokerOptions); + _logRecorder, _rootMessageLogger, _authenticationProviderFactory,_groupProviderFactory, _accessControlProviderFactory, + _portFactory , _preferencesProviderCreator, _taskExecutor, entry.getStore(), _brokerOptions); - broker.addChangeListener(storeChangeListener); + broker.addChangeListener(_storeChangeListener); //Recover the SSL keystores / truststores first, then others that depend on them Map<String, Collection<ConfigurationEntry>> childEntries = new HashMap<String, Collection<ConfigurationEntry>>(entry.getChildren()); @@ -117,11 +122,11 @@ public class BrokerRecoverer implements ConfiguredObjectRecoverer<Broker> for (String type : priorityChildEntries.keySet()) { - recoverType(recovererProvider, storeChangeListener, broker, priorityChildEntries, type); + recoverType(recovererProvider, _storeChangeListener, broker, priorityChildEntries, type); } for (String type : childEntries.keySet()) { - recoverType(recovererProvider, storeChangeListener, broker, childEntries, type); + recoverType(recovererProvider, _storeChangeListener, broker, childEntries, type); } return broker; diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/DefaultRecovererProvider.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/DefaultRecovererProvider.java index 2de454c34f..67268c9854 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/DefaultRecovererProvider.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/DefaultRecovererProvider.java @@ -32,12 +32,15 @@ import org.apache.qpid.server.model.GroupProvider; import org.apache.qpid.server.model.KeyStore; import org.apache.qpid.server.model.Plugin; import org.apache.qpid.server.model.Port; +import org.apache.qpid.server.model.PreferencesProvider; import org.apache.qpid.server.model.TrustStore; import org.apache.qpid.server.model.VirtualHost; import org.apache.qpid.server.model.adapter.AccessControlProviderFactory; import org.apache.qpid.server.model.adapter.AuthenticationProviderFactory; import org.apache.qpid.server.model.adapter.GroupProviderFactory; import org.apache.qpid.server.model.adapter.PortFactory; +import org.apache.qpid.server.model.adapter.PreferencesProviderCreator; +import org.apache.qpid.server.configuration.store.StoreConfigurationChangeListener; import org.apache.qpid.server.configuration.updater.TaskExecutor; import org.apache.qpid.server.plugin.AccessControlFactory; import org.apache.qpid.server.plugin.AuthenticationManagerFactory; @@ -61,11 +64,14 @@ public class DefaultRecovererProvider implements RecovererProvider private final QpidServiceLoader<PluginFactory> _pluginFactoryServiceLoader; private final TaskExecutor _taskExecutor; private final BrokerOptions _brokerOptions; + private final StoreConfigurationChangeListener _storeChangeListener; + private final PreferencesProviderCreator _preferencesProviderCreator; public DefaultRecovererProvider(StatisticsGatherer brokerStatisticsGatherer, VirtualHostRegistry virtualHostRegistry, - LogRecorder logRecorder, RootMessageLogger rootMessageLogger, TaskExecutor taskExecutor, BrokerOptions brokerOptions) + LogRecorder logRecorder, RootMessageLogger rootMessageLogger, TaskExecutor taskExecutor, BrokerOptions brokerOptions, StoreConfigurationChangeListener storeChangeListener) { - _authenticationProviderFactory = new AuthenticationProviderFactory(new QpidServiceLoader<AuthenticationManagerFactory>()); + _preferencesProviderCreator = new PreferencesProviderCreator(); + _authenticationProviderFactory = new AuthenticationProviderFactory(new QpidServiceLoader<AuthenticationManagerFactory>(), _preferencesProviderCreator); _accessControlProviderFactory = new AccessControlProviderFactory(new QpidServiceLoader<AccessControlFactory>()); _groupProviderFactory = new GroupProviderFactory(new QpidServiceLoader<GroupManagerFactory>()); _portFactory = new PortFactory(); @@ -76,6 +82,7 @@ public class DefaultRecovererProvider implements RecovererProvider _pluginFactoryServiceLoader = new QpidServiceLoader<PluginFactory>(); _taskExecutor = taskExecutor; _brokerOptions = brokerOptions; + _storeChangeListener = storeChangeListener; } @Override @@ -83,8 +90,8 @@ public class DefaultRecovererProvider implements RecovererProvider { if (Broker.class.getSimpleName().equals(type)) { - return new BrokerRecoverer(_authenticationProviderFactory, _groupProviderFactory, _accessControlProviderFactory, _portFactory, _brokerStatisticsGatherer, - _virtualHostRegistry, _logRecorder, _rootMessageLogger, _taskExecutor, _brokerOptions); + return new BrokerRecoverer(_authenticationProviderFactory, _groupProviderFactory, _accessControlProviderFactory, _portFactory, _preferencesProviderCreator, + _brokerStatisticsGatherer, _virtualHostRegistry, _logRecorder, _rootMessageLogger, _taskExecutor, _brokerOptions, _storeChangeListener); } else if(VirtualHost.class.getSimpleName().equals(type)) { @@ -96,7 +103,7 @@ public class DefaultRecovererProvider implements RecovererProvider } else if(AuthenticationProvider.class.getSimpleName().equals(type)) { - return new AuthenticationProviderRecoverer(_authenticationProviderFactory); + return new AuthenticationProviderRecoverer(_authenticationProviderFactory, _storeChangeListener); } else if(Port.class.getSimpleName().equals(type)) { @@ -114,6 +121,10 @@ public class DefaultRecovererProvider implements RecovererProvider { return new TrustStoreRecoverer(); } + else if(PreferencesProvider.class.getSimpleName().equals(type)) + { + return new PreferencesProviderRecoverer(_preferencesProviderCreator); + } else if(Plugin.class.getSimpleName().equals(type)) { return new PluginRecoverer(_pluginFactoryServiceLoader); diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/PreferencesProviderRecoverer.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/PreferencesProviderRecoverer.java new file mode 100644 index 0000000000..a455a61fee --- /dev/null +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/PreferencesProviderRecoverer.java @@ -0,0 +1,41 @@ +package org.apache.qpid.server.configuration.startup; + +import org.apache.qpid.server.configuration.ConfigurationEntry; +import org.apache.qpid.server.configuration.ConfiguredObjectRecoverer; +import org.apache.qpid.server.configuration.RecovererProvider; +import org.apache.qpid.server.model.AuthenticationProvider; +import org.apache.qpid.server.model.ConfiguredObject; +import org.apache.qpid.server.model.PreferencesProvider; +import org.apache.qpid.server.model.adapter.PreferencesProviderCreator; + +public class PreferencesProviderRecoverer implements ConfiguredObjectRecoverer<PreferencesProvider> +{ + + private PreferencesProviderCreator _preferencesProviderCreator; + + public PreferencesProviderRecoverer(PreferencesProviderCreator preferencesProviderCreator) + { + _preferencesProviderCreator = preferencesProviderCreator; + } + + @Override + public PreferencesProvider create(RecovererProvider recovererProvider, ConfigurationEntry entry, + ConfiguredObject... parents) + { + if (parents == null || parents.length == 0) + { + throw new IllegalArgumentException("AuthenticationProvider parent is not passed!"); + } + if (parents.length != 1) + { + throw new IllegalArgumentException("Only one parent is expected!"); + } + if (!(parents[0] instanceof AuthenticationProvider)) + { + throw new IllegalArgumentException("Parent is not a AuthenticationProvider"); + } + AuthenticationProvider authenticationProvider = (AuthenticationProvider)parents[0]; + return _preferencesProviderCreator.recover(entry.getId(), entry.getAttributes(), authenticationProvider); + } + +} diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/store/MemoryConfigurationEntryStore.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/store/MemoryConfigurationEntryStore.java index ece4e2275e..92d170fad9 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/store/MemoryConfigurationEntryStore.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/store/MemoryConfigurationEntryStore.java @@ -291,7 +291,7 @@ public class MemoryConfigurationEntryStore implements ConfigurationEntryStore + " can not be loaded by store of version " + STORE_VERSION); } - ConfigurationEntry brokerEntry = toEntry(node, Broker.class, _entries); + ConfigurationEntry brokerEntry = toEntry(node, Broker.class, _entries, null); _rootId = brokerEntry.getId(); } catch (IOException e) @@ -370,7 +370,7 @@ public class MemoryConfigurationEntryStore implements ConfigurationEntryStore byte[] bytes = json.getBytes("UTF-8"); bais = new ByteArrayInputStream(bytes); JsonNode node = loadJsonNodes(bais, _objectMapper); - ConfigurationEntry brokerEntry = toEntry(node, Broker.class, _entries); + ConfigurationEntry brokerEntry = toEntry(node, Broker.class, _entries, null); _rootId = brokerEntry.getId(); } catch(Exception e) @@ -490,7 +490,7 @@ public class MemoryConfigurationEntryStore implements ConfigurationEntryStore return root; } - private ConfigurationEntry toEntry(JsonNode parent, Class<? extends ConfiguredObject> expectedConfiguredObjectClass, Map<UUID, ConfigurationEntry> entries) + private ConfigurationEntry toEntry(JsonNode parent, Class<? extends ConfiguredObject> expectedConfiguredObjectClass, Map<UUID, ConfigurationEntry> entries, Class<? extends ConfiguredObject> parentClass) { Map<String, Object> attributes = null; Set<UUID> childrenIds = new TreeSet<UUID>(); @@ -520,8 +520,22 @@ public class MemoryConfigurationEntryStore implements ConfigurationEntryStore if (element.isObject()) { Class<? extends ConfiguredObject> expectedChildConfiguredObjectClass = _relationshipClasses.get(fieldName); + if (expectedChildConfiguredObjectClass == null && expectedConfiguredObjectClass != null) + { + Collection<Class<? extends ConfiguredObject>> childTypes = Model.getInstance().getChildTypes(expectedConfiguredObjectClass); + for (Class<? extends ConfiguredObject> childType : childTypes) + { + String relationship = childType.getSimpleName().toLowerCase(); + relationship += relationship.endsWith("s") ? "es": "s"; + if (fieldName.equals(relationship)) + { + expectedChildConfiguredObjectClass = childType; + break; + } + } + } // assuming it is a child node - ConfigurationEntry entry = toEntry(element, expectedChildConfiguredObjectClass, entries); + ConfigurationEntry entry = toEntry(element, expectedChildConfiguredObjectClass, entries, expectedConfiguredObjectClass); childrenIds.add(entry.getId()); } else diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/AuthenticationProvider.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/AuthenticationProvider.java index 61ceae9cf0..f75d0211cb 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/AuthenticationProvider.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/AuthenticationProvider.java @@ -66,4 +66,15 @@ public interface AuthenticationProvider extends ConfiguredObject */ SubjectCreator getSubjectCreator(); + /** + * Returns the preferences provider associated with this authentication provider + * @return PreferencesProvider + */ + PreferencesProvider getPreferencesProvider(); + + /** + * Sets the preferences provider + * @param preferencesProvider + */ + void setPreferencesProvider(PreferencesProvider preferencesProvider); } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/Broker.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/Broker.java index 8f565362b4..0c1a6de58b 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/Broker.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/Broker.java @@ -45,6 +45,7 @@ public interface Broker extends ConfiguredObject String SUPPORTED_VIRTUALHOST_TYPES = "supportedVirtualHostTypes"; String SUPPORTED_VIRTUALHOST_STORE_TYPES = "supportedVirtualHostStoreTypes"; String SUPPORTED_AUTHENTICATION_PROVIDERS = "supportedAuthenticationProviders"; + String SUPPORTED_PREFERENCES_PROVIDERS_TYPES = "supportedPreferencesProviderTypes"; String CREATED = "created"; String DURABLE = "durable"; String ID = "id"; @@ -93,6 +94,7 @@ public interface Broker extends ConfiguredObject SUPPORTED_BROKER_STORE_TYPES, SUPPORTED_VIRTUALHOST_STORE_TYPES, SUPPORTED_AUTHENTICATION_PROVIDERS, + SUPPORTED_PREFERENCES_PROVIDERS_TYPES, CREATED, DURABLE, ID, @@ -183,4 +185,6 @@ public interface Broker extends ConfiguredObject TaskExecutor getTaskExecutor(); boolean isManagementMode(); + + AuthenticationProvider getAuthenticationProvider(SocketAddress localAddress); } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/Model.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/Model.java index f652dcec67..45fadbdbcb 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/Model.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/Model.java @@ -70,6 +70,7 @@ public class Model addRelationship(VirtualHost.class, VirtualHostAlias.class); addRelationship(AuthenticationProvider.class, User.class); + addRelationship(AuthenticationProvider.class, PreferencesProvider.class); addRelationship(User.class, GroupMember.class); addRelationship(GroupProvider.class, Group.class); diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/UUIDGenerator.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/UUIDGenerator.java index bcedd91596..7def89025d 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/UUIDGenerator.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/UUIDGenerator.java @@ -92,4 +92,9 @@ public class UUIDGenerator { return createUUID(type, childName); } + + public static UUID generatePreferencesProviderUUID(String preferencesProviderName, String authenticationProviderName) + { + return createUUID(PreferencesProvider.class.getName(), authenticationProviderName, preferencesProviderName); + } } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/User.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/User.java index 675dc8f0d3..f9d6f17ffd 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/User.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/User.java @@ -24,6 +24,7 @@ package org.apache.qpid.server.model; import java.util.Arrays; import java.util.Collection; import java.util.Collections; +import java.util.Map; public interface User extends ConfiguredObject { @@ -54,4 +55,11 @@ public interface User extends ConfiguredObject public void setPassword(String password); + public Map<String, Object> getPreferences(); + + public Object getPreference(String name); + + public Map<String, Object> setPreferences(Map<String, Object> preferences); + + public Map<String, Object> replacePreferences(Map<String, Object> newPreferences); } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AuthenticationProviderAdapter.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AuthenticationProviderAdapter.java index 5c4c8a53cd..f0076bd983 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AuthenticationProviderAdapter.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AuthenticationProviderAdapter.java @@ -43,6 +43,7 @@ import org.apache.qpid.server.model.IntegrityViolationException; import org.apache.qpid.server.model.LifetimePolicy; import org.apache.qpid.server.model.PasswordCredentialManagingAuthenticationProvider; import org.apache.qpid.server.model.Port; +import org.apache.qpid.server.model.PreferencesProvider; import org.apache.qpid.server.model.State; import org.apache.qpid.server.model.Statistics; import org.apache.qpid.server.model.UUIDGenerator; @@ -51,7 +52,6 @@ import org.apache.qpid.server.model.VirtualHostAlias; import org.apache.qpid.server.plugin.AuthenticationManagerFactory; import org.apache.qpid.server.plugin.QpidServiceLoader; import org.apache.qpid.server.configuration.IllegalConfigurationException; -import org.apache.qpid.server.configuration.updater.TaskExecutor; import org.apache.qpid.server.security.SubjectCreator; import org.apache.qpid.server.security.access.Operation; import org.apache.qpid.server.security.auth.UsernamePrincipal; @@ -70,9 +70,11 @@ public abstract class AuthenticationProviderAdapter<T extends AuthenticationMana protected Collection<String> _supportedAttributes; protected Map<String, AuthenticationManagerFactory> _factories; - private AtomicReference<State> _state; + private final AtomicReference<State> _state; + private PreferencesProviderCreator _preferencesProviderCreator; + private PreferencesProvider _preferencesProvider; - private AuthenticationProviderAdapter(UUID id, Broker broker, final T authManager, Map<String, Object> attributes, Collection<String> attributeNames) + private AuthenticationProviderAdapter(UUID id, Broker broker, final T authManager, Map<String, Object> attributes, Collection<String> attributeNames, PreferencesProviderCreator preferencesProviderCreator) { super(id, null, null, broker.getTaskExecutor()); _authManager = authManager; @@ -84,6 +86,8 @@ public abstract class AuthenticationProviderAdapter<T extends AuthenticationMana _state = new AtomicReference<State>(state); addParent(Broker.class, broker); + _preferencesProviderCreator = preferencesProviderCreator; + // set attributes now after all attribute names are known if (attributes != null) { @@ -210,9 +214,14 @@ public abstract class AuthenticationProviderAdapter<T extends AuthenticationMana return super.getAttribute(name); } + @SuppressWarnings("unchecked") @Override public <C extends ConfiguredObject> Collection<C> getChildren(Class<C> clazz) { + if (clazz == PreferencesProvider.class && _preferencesProvider != null) + { + return (Collection<C>)Collections.<PreferencesProvider>singleton(_preferencesProvider); + } return Collections.emptySet(); } @@ -240,6 +249,10 @@ public abstract class AuthenticationProviderAdapter<T extends AuthenticationMana { _authManager.close(); _authManager.onDelete(); + if (_preferencesProvider != null) + { + _preferencesProvider.setDesiredState(_preferencesProvider.getActualState(), State.DELETED); + } return true; } else @@ -254,6 +267,10 @@ public abstract class AuthenticationProviderAdapter<T extends AuthenticationMana try { _authManager.initialise(); + if (_preferencesProvider != null) + { + _preferencesProvider.setDesiredState(_preferencesProvider.getActualState(), State.ACTIVE); + } return true; } catch(RuntimeException e) @@ -397,24 +414,39 @@ public abstract class AuthenticationProviderAdapter<T extends AuthenticationMana } } - public static class SimpleAuthenticationProviderAdapter extends AuthenticationProviderAdapter<AuthenticationManager> + public PreferencesProvider getPreferencesProvider() { + return _preferencesProvider; + } - public SimpleAuthenticationProviderAdapter( - UUID id, Broker broker, AuthenticationManager authManager, Map<String, Object> attributes, Collection<String> attributeNames) - { - super(id, broker,authManager, attributes, attributeNames); - } + public void setPreferencesProvider(PreferencesProvider provider) + { + _preferencesProvider = provider; + } - @Override - public <C extends ConfiguredObject> C createChild(Class<C> childClass, - Map<String, Object> attributes, - ConfiguredObject... otherParents) + @SuppressWarnings("unchecked") + @Override + public <C extends ConfiguredObject> C addChild(Class<C> childClass, Map<String, Object> attributes, ConfiguredObject... otherParents) + { + if(childClass == PreferencesProvider.class) { - throw new UnsupportedOperationException(); + String name = MapValueConverter.getStringAttribute(PreferencesProvider.NAME, attributes); + PreferencesProvider pp = _preferencesProviderCreator.create(UUIDGenerator.generatePreferencesProviderUUID(name, getName()), attributes, this); + pp.setDesiredState(State.INITIALISING, State.ACTIVE); + _preferencesProvider = pp; + return (C)pp; } + throw new IllegalArgumentException("Cannot create child of class " + childClass.getSimpleName()); + } + public static class SimpleAuthenticationProviderAdapter extends AuthenticationProviderAdapter<AuthenticationManager> + { + public SimpleAuthenticationProviderAdapter( + UUID id, Broker broker, AuthenticationManager authManager, Map<String, Object> attributes, Collection<String> attributeNames, PreferencesProviderCreator preferencesProviderCreator) + { + super(id, broker,authManager, attributes, attributeNames, preferencesProviderCreator); + } } public static class PrincipalDatabaseAuthenticationManagerAdapter @@ -422,9 +454,9 @@ public abstract class AuthenticationProviderAdapter<T extends AuthenticationMana implements PasswordCredentialManagingAuthenticationProvider { public PrincipalDatabaseAuthenticationManagerAdapter( - UUID id, Broker broker, PrincipalDatabaseAuthenticationManager authManager, Map<String, Object> attributes, Collection<String> attributeNames) + UUID id, Broker broker, PrincipalDatabaseAuthenticationManager authManager, Map<String, Object> attributes, Collection<String> attributeNames, PreferencesProviderCreator preferencesProviderCreator) { - super(id, broker, authManager, attributes, attributeNames); + super(id, broker, authManager, attributes, attributeNames, preferencesProviderCreator); } @Override @@ -507,7 +539,7 @@ public abstract class AuthenticationProviderAdapter<T extends AuthenticationMana if(createUser(username, password,null)) { @SuppressWarnings("unchecked") - C pricipalAdapter = (C) new PrincipalAdapter(p, getTaskExecutor()); + C pricipalAdapter = (C) new PrincipalAdapter(p); return pricipalAdapter; } else @@ -529,7 +561,7 @@ public abstract class AuthenticationProviderAdapter<T extends AuthenticationMana Collection<User> principals = new ArrayList<User>(users.size()); for(Principal user : users) { - principals.add(new PrincipalAdapter(user, getTaskExecutor())); + principals.add(new PrincipalAdapter(user)); } @SuppressWarnings("unchecked") Collection<C> unmodifiablePrincipals = (Collection<C>) Collections.unmodifiableCollection(principals); @@ -544,22 +576,33 @@ public abstract class AuthenticationProviderAdapter<T extends AuthenticationMana @Override protected void childAdded(ConfiguredObject child) { - // no-op, prevent storing users in the broker store + if (child instanceof User) + { + // no-op, prevent storing users in the broker store + return; + } + super.childAdded(child); } @Override protected void childRemoved(ConfiguredObject child) { - // no-op, as per above, users are not in the store + if (child instanceof User) + { + // no-op, as per above, users are not in the store + return; + } + super.childRemoved(child); } private class PrincipalAdapter extends AbstractAdapter implements User { private final Principal _user; - public PrincipalAdapter(Principal user, TaskExecutor taskExecutor) + public PrincipalAdapter(Principal user) { - super(UUIDGenerator.generateUserUUID(PrincipalDatabaseAuthenticationManagerAdapter.this.getName(), user.getName()), taskExecutor); + super(UUIDGenerator.generateUserUUID(PrincipalDatabaseAuthenticationManagerAdapter.this.getName(), user.getName()), + PrincipalDatabaseAuthenticationManagerAdapter.this.getTaskExecutor()); _user = user; } @@ -699,7 +742,13 @@ public abstract class AuthenticationProviderAdapter<T extends AuthenticationMana { try { - deleteUser(_user.getName()); + String userName = _user.getName(); + deleteUser(userName); + PreferencesProvider preferencesProvider = getPreferencesProvider(); + if (preferencesProvider != null) + { + preferencesProvider.deletePreferences(userName); + } } catch (AccountNotFoundException e) { @@ -709,6 +758,60 @@ public abstract class AuthenticationProviderAdapter<T extends AuthenticationMana } return false; } + + @Override + public Map<String, Object> getPreferences() + { + PreferencesProvider preferencesProvider = getPreferencesProvider(); + if (preferencesProvider == null) + { + return null; + } + return preferencesProvider.getPreferences(this.getName()); + } + + @Override + public Object getPreference(String name) + { + Map<String, Object> preferences = getPreferences(); + if (preferences == null) + { + return null; + } + return preferences.get(name); + } + + @Override + public Map<String, Object> setPreferences(Map<String, Object> preferences) + { + PreferencesProvider preferencesProvider = getPreferencesProvider(); + if (preferencesProvider == null) + { + return null; + } + return preferencesProvider.setPreferences(this.getName(), preferences); + } + + @Override + public Map<String, Object> replacePreferences(Map<String, Object> newPreferences) + { + PreferencesProvider preferencesProvider = getPreferencesProvider(); + if (preferencesProvider == null) + { + return null; + } + Map<String, Object> preferences = preferencesProvider.deletePreferences(this.getName()); + preferencesProvider.setPreferences(this.getName(), newPreferences); + return preferences; + } + + private PreferencesProvider getPreferencesProvider() + { + return PrincipalDatabaseAuthenticationManagerAdapter.this.getPreferencesProvider(); + } + } + } + } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AuthenticationProviderFactory.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AuthenticationProviderFactory.java index 7efb71d78b..71bc3c631d 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AuthenticationProviderFactory.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AuthenticationProviderFactory.java @@ -42,9 +42,11 @@ public class AuthenticationProviderFactory { private final Iterable<AuthenticationManagerFactory> _factories; private Collection<String> _supportedAuthenticationProviders; + private final PreferencesProviderCreator _preferencesProviderCreator; - public AuthenticationProviderFactory(QpidServiceLoader<AuthenticationManagerFactory> authManagerFactoryServiceLoader) + public AuthenticationProviderFactory(QpidServiceLoader<AuthenticationManagerFactory> authManagerFactoryServiceLoader, PreferencesProviderCreator preferencesProviderCreator) { + _preferencesProviderCreator = preferencesProviderCreator; _factories = authManagerFactoryServiceLoader.atLeastOneInstanceOf(AuthenticationManagerFactory.class); List<String> supportedAuthenticationProviders = new ArrayList<String>(); for (AuthenticationManagerFactory factory : _factories) @@ -89,11 +91,11 @@ public class AuthenticationProviderFactory if (manager instanceof PrincipalDatabaseAuthenticationManager) { authenticationProvider = new PrincipalDatabaseAuthenticationManagerAdapter(id, broker, - (PrincipalDatabaseAuthenticationManager) manager, attributes, factory.getAttributeNames()); + (PrincipalDatabaseAuthenticationManager) manager, attributes, factory.getAttributeNames(), _preferencesProviderCreator); } else { - authenticationProvider = new SimpleAuthenticationProviderAdapter(id, broker, manager, attributes, factory.getAttributeNames()); + authenticationProvider = new SimpleAuthenticationProviderAdapter(id, broker, manager, attributes, factory.getAttributeNames(), _preferencesProviderCreator); } return authenticationProvider; } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java index ff9cac9a21..aec78ba414 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java @@ -178,7 +178,7 @@ public class BrokerAdapter extends AbstractAdapter implements Broker, Configurat private final GroupProviderFactory _groupProviderFactory; private final AuthenticationProviderFactory _authenticationProviderFactory; private final AccessControlProviderFactory _accessControlProviderFactory; - + private final PreferencesProviderCreator _preferencesProviderCreator; private final PortFactory _portFactory; private final SecurityManager _securityManager; @@ -191,8 +191,8 @@ public class BrokerAdapter extends AbstractAdapter implements Broker, Configurat public BrokerAdapter(UUID id, Map<String, Object> attributes, StatisticsGatherer statisticsGatherer, VirtualHostRegistry virtualHostRegistry, LogRecorder logRecorder, RootMessageLogger rootMessageLogger, AuthenticationProviderFactory authenticationProviderFactory, - GroupProviderFactory groupProviderFactory, AccessControlProviderFactory accessControlProviderFactory, PortFactory portFactory, TaskExecutor taskExecutor, - ConfigurationEntryStore brokerStore, BrokerOptions brokerOptions) + GroupProviderFactory groupProviderFactory, AccessControlProviderFactory accessControlProviderFactory, PortFactory portFactory, + PreferencesProviderCreator preferencesProviderCreatory, TaskExecutor taskExecutor, ConfigurationEntryStore brokerStore, BrokerOptions brokerOptions) { super(id, DEFAULTS, MapValueConverter.convert(attributes, ATTRIBUTE_TYPES), taskExecutor); _statisticsGatherer = statisticsGatherer; @@ -201,6 +201,7 @@ public class BrokerAdapter extends AbstractAdapter implements Broker, Configurat _rootMessageLogger = rootMessageLogger; _statistics = new StatisticsAdapter(statisticsGatherer); _authenticationProviderFactory = authenticationProviderFactory; + _preferencesProviderCreator = preferencesProviderCreatory; _groupProviderFactory = groupProviderFactory; _accessControlProviderFactory = accessControlProviderFactory; _portFactory = portFactory; @@ -213,7 +214,7 @@ public class BrokerAdapter extends AbstractAdapter implements Broker, Configurat { AuthenticationManager authManager = new SimpleAuthenticationManager(BrokerOptions.MANAGEMENT_MODE_USER_NAME, _brokerOptions.getManagementModePassword()); AuthenticationProvider authenticationProvider = new SimpleAuthenticationProviderAdapter(UUID.randomUUID(), this, - authManager, Collections.<String, Object> emptyMap(), Collections.<String> emptySet()); + authManager, Collections.<String, Object> emptyMap(), Collections.<String> emptySet(), _preferencesProviderCreator); _managementAuthenticationProvider = authenticationProvider; } } @@ -783,6 +784,10 @@ public class BrokerAdapter extends AbstractAdapter implements Broker, Configurat { return _authenticationProviderFactory.getSupportedAuthenticationProviders(); } + else if (SUPPORTED_PREFERENCES_PROVIDERS_TYPES.equals(name)) + { + return _preferencesProviderCreator.getSupportedPreferencesProviders(); + } else if (MODEL_VERSION.equals(name)) { return Model.MODEL_VERSION; @@ -1086,6 +1091,19 @@ public class BrokerAdapter extends AbstractAdapter implements Broker, Configurat @Override public SubjectCreator getSubjectCreator(SocketAddress localAddress) { + AuthenticationProvider provider = getAuthenticationProvider(localAddress); + + if(provider == null) + { + throw new IllegalConfigurationException("Unable to determine authentication provider for address: " + localAddress); + } + + return provider.getSubjectCreator(); + } + + @Override + public AuthenticationProvider getAuthenticationProvider(SocketAddress localAddress) + { InetSocketAddress inetSocketAddress = (InetSocketAddress)localAddress; AuthenticationProvider provider = null; Collection<Port> ports = getPorts(); @@ -1097,13 +1115,7 @@ public class BrokerAdapter extends AbstractAdapter implements Broker, Configurat break; } } - - if(provider == null) - { - throw new IllegalConfigurationException("Unable to determine authentication provider for address: " + localAddress); - } - - return provider.getSubjectCreator(); + return provider; } @Override diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/FileSystemPreferencesProviderFactory.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/FileSystemPreferencesProviderFactory.java new file mode 100644 index 0000000000..218ecc1c53 --- /dev/null +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/FileSystemPreferencesProviderFactory.java @@ -0,0 +1,32 @@ +package org.apache.qpid.server.model.adapter; + +import java.util.Map; +import java.util.UUID; + +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.plugin.PreferencesProviderFactory; + +public class FileSystemPreferencesProviderFactory implements PreferencesProviderFactory +{ + + @Override + public String getType() + { + return FileSystemPreferencesProvider.PROVIDER_TYPE; + } + + @Override + public PreferencesProvider createInstance(UUID id, Map<String, Object> attributes, + AuthenticationProvider authenticationProvider) + { + Broker broker = authenticationProvider.getParent(Broker.class); + FileSystemPreferencesProvider provider = new FileSystemPreferencesProvider(id, attributes, authenticationProvider, broker.getTaskExecutor()); + + // create store if such does not exist + provider.createStoreIfNotExist(); + return provider; + } + +} diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/PreferencesProviderCreator.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/PreferencesProviderCreator.java new file mode 100644 index 0000000000..4bcca0e300 --- /dev/null +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/PreferencesProviderCreator.java @@ -0,0 +1,66 @@ +package org.apache.qpid.server.model.adapter; + +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +import org.apache.qpid.server.configuration.IllegalConfigurationException; +import org.apache.qpid.server.model.AuthenticationProvider; +import org.apache.qpid.server.model.PreferencesProvider; +import org.apache.qpid.server.plugin.PreferencesProviderFactory; +import org.apache.qpid.server.plugin.QpidServiceLoader; + +public class PreferencesProviderCreator +{ + private final Map<String, PreferencesProviderFactory> _factories; + private Collection<String> _supportedPreferencesProviders; + + public PreferencesProviderCreator() + { + QpidServiceLoader<PreferencesProviderFactory> preferencesProviderFactoriess = new QpidServiceLoader<PreferencesProviderFactory>(); + + Iterable<PreferencesProviderFactory> factories = preferencesProviderFactoriess + .instancesOf(PreferencesProviderFactory.class); + + Map<String, PreferencesProviderFactory> registeredPreferencesProviderFactories = new HashMap<String, PreferencesProviderFactory>(); + for (PreferencesProviderFactory factory : factories) + { + PreferencesProviderFactory existingFactory = registeredPreferencesProviderFactories.put(factory.getType(), + factory); + if (existingFactory != null) + { + throw new IllegalConfigurationException("Preferences provider factory of the same type '" + + factory.getType() + "' is already registered using class '" + existingFactory.getClass().getName() + + "', can not register class '" + factory.getClass().getName() + "'"); + } + } + _factories = registeredPreferencesProviderFactories; + _supportedPreferencesProviders = Collections.unmodifiableCollection(registeredPreferencesProviderFactories.keySet()); + } + + public Collection<String> getSupportedPreferencesProviders() + { + return _supportedPreferencesProviders; + } + + public PreferencesProvider create(UUID id, Map<String, Object> attributes, AuthenticationProvider authenticationProvider) + { + return createPreferencesProvider(id, attributes, authenticationProvider); + } + + public PreferencesProvider recover(UUID id, Map<String, Object> attributes, AuthenticationProvider authenticationProviderr) + { + return createPreferencesProvider(id, attributes, authenticationProviderr); + } + + private PreferencesProvider createPreferencesProvider(UUID id, Map<String, Object> attributes, AuthenticationProvider authenticationProvider) + { + for (PreferencesProviderFactory factory : _factories.values()) + { + return factory.createInstance(id, attributes, authenticationProvider); + } + throw new IllegalConfigurationException("No group provider factory found for configuration attributes " + attributes); + } +} diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/plugin/PreferencesProviderFactory.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/plugin/PreferencesProviderFactory.java new file mode 100644 index 0000000000..5a95b88591 --- /dev/null +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/plugin/PreferencesProviderFactory.java @@ -0,0 +1,12 @@ +package org.apache.qpid.server.plugin; + +import java.util.Map; +import java.util.UUID; + +import org.apache.qpid.server.model.AuthenticationProvider; +import org.apache.qpid.server.model.PreferencesProvider; + +public interface PreferencesProviderFactory extends Pluggable +{ + PreferencesProvider createInstance(UUID id, Map<String, Object> attributes, AuthenticationProvider authenticationProvider); +} diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/ApplicationRegistry.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/ApplicationRegistry.java index fa5024c1fe..9d16f4b927 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/ApplicationRegistry.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/ApplicationRegistry.java @@ -33,6 +33,7 @@ import org.apache.qpid.server.configuration.ConfigurationEntryStore; import org.apache.qpid.server.configuration.ConfiguredObjectRecoverer; import org.apache.qpid.server.configuration.RecovererProvider; import org.apache.qpid.server.configuration.startup.DefaultRecovererProvider; +import org.apache.qpid.server.configuration.store.StoreConfigurationChangeListener; import org.apache.qpid.server.logging.CompositeStartupMessageLogger; import org.apache.qpid.server.logging.Log4jMessageLogger; import org.apache.qpid.server.logging.LogActor; @@ -113,7 +114,8 @@ public class ApplicationRegistry implements IApplicationRegistry _taskExecutor = new TaskExecutor(); _taskExecutor.start(); - RecovererProvider provider = new DefaultRecovererProvider((StatisticsGatherer)this, _virtualHostRegistry, _logRecorder, _rootMessageLogger, _taskExecutor, brokerOptions); + StoreConfigurationChangeListener storeChangeListener = new StoreConfigurationChangeListener(_store); + RecovererProvider provider = new DefaultRecovererProvider((StatisticsGatherer)this, _virtualHostRegistry, _logRecorder, _rootMessageLogger, _taskExecutor, brokerOptions, storeChangeListener); ConfiguredObjectRecoverer<? extends ConfiguredObject> brokerRecoverer = provider.getRecoverer(Broker.class.getSimpleName()); _broker = (Broker) brokerRecoverer.create(provider, _store.getRootEntry()); diff --git a/qpid/java/broker/src/main/resources/META-INF/services/org.apache.qpid.server.plugin.PreferencesProviderFactory b/qpid/java/broker/src/main/resources/META-INF/services/org.apache.qpid.server.plugin.PreferencesProviderFactory new file mode 100644 index 0000000000..9fe8379120 --- /dev/null +++ b/qpid/java/broker/src/main/resources/META-INF/services/org.apache.qpid.server.plugin.PreferencesProviderFactory @@ -0,0 +1,19 @@ +# +# 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. +# +org.apache.qpid.server.model.adapter.FileSystemPreferencesProviderFactory
\ No newline at end of file diff --git a/qpid/java/broker/src/main/resources/initial-config.json b/qpid/java/broker/src/main/resources/initial-config.json index 9bf7d71e8a..a203190c4b 100644 --- a/qpid/java/broker/src/main/resources/initial-config.json +++ b/qpid/java/broker/src/main/resources/initial-config.json @@ -26,7 +26,12 @@ "authenticationproviders" : [ { "name" : "passwordFile", "type" : "PlainPasswordFile", - "path" : "${qpid.home_dir}/etc/passwd" + "path" : "${qpid.home_dir}/etc/passwd", + "preferencesproviders" : [{ + "name": "fileSystemPreferences", + "type": "FileSystemPreferences", + "path" : "${qpid.work_dir}/preferences/passwordFile" + }] } ], "ports" : [ { "name" : "AMQP", diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/startup/AuthenticationProviderRecovererTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/startup/AuthenticationProviderRecovererTest.java new file mode 100644 index 0000000000..36e485844f --- /dev/null +++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/startup/AuthenticationProviderRecovererTest.java @@ -0,0 +1,126 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.configuration.startup; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.io.File; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +import org.apache.qpid.server.configuration.ConfigurationEntry; +import org.apache.qpid.server.configuration.ConfigurationEntryStore; +import org.apache.qpid.server.configuration.ConfiguredObjectRecoverer; +import org.apache.qpid.server.configuration.RecovererProvider; +import org.apache.qpid.server.configuration.store.StoreConfigurationChangeListener; +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.PreferencesProvider; +import org.apache.qpid.server.model.adapter.AuthenticationProviderFactory; +import org.apache.qpid.server.model.adapter.FileSystemPreferencesProvider; +import org.apache.qpid.server.model.adapter.PreferencesProviderCreator; +import org.apache.qpid.server.plugin.AuthenticationManagerFactory; +import org.apache.qpid.server.plugin.QpidServiceLoader; +import org.apache.qpid.server.security.auth.manager.AnonymousAuthenticationManagerFactory; +import org.apache.qpid.server.util.BrokerTestHelper; +import org.apache.qpid.test.utils.QpidTestCase; +import org.apache.qpid.test.utils.TestFileUtils; + +public class AuthenticationProviderRecovererTest extends QpidTestCase +{ + private Broker _broker; + private AuthenticationProviderRecoverer _recoverer; + private ConfigurationEntryStore _configurationStore; + private PreferencesProviderCreator _preferencesProviderCreator; + + public void setUp() throws Exception + { + super.setUp(); + BrokerTestHelper.setUp(); + _broker = BrokerTestHelper.createBrokerMock(); + _preferencesProviderCreator = new PreferencesProviderCreator(); + QpidServiceLoader<AuthenticationManagerFactory> serviceLoader = new QpidServiceLoader<AuthenticationManagerFactory>(); + AuthenticationProviderFactory authenticationProviderFactory = new AuthenticationProviderFactory(serviceLoader, _preferencesProviderCreator); + StoreConfigurationChangeListener storeChangeListener = mock(StoreConfigurationChangeListener.class); + _recoverer = new AuthenticationProviderRecoverer(authenticationProviderFactory, storeChangeListener); + _configurationStore = mock(ConfigurationEntryStore.class); + } + + public void tearDown() throws Exception + { + try + { + BrokerTestHelper.tearDown(); + } + finally + { + super.tearDown(); + } + } + + public void testRecoverAuthenticationProviderWithPreferencesProvider() + { + Map<String, Object> authenticationAttributes = new HashMap<String, Object>(); + authenticationAttributes.put(AuthenticationManagerFactory.ATTRIBUTE_TYPE, AnonymousAuthenticationManagerFactory.PROVIDER_TYPE); + authenticationAttributes.put(AuthenticationProvider.NAME, "test-authenticator"); + UUID authenticationId = UUID.randomUUID(); + + final PreferencesProviderRecoverer preferencesRecoverer = new PreferencesProviderRecoverer(_preferencesProviderCreator); + RecovererProvider recovererProvider = new RecovererProvider() + { + @Override + public ConfiguredObjectRecoverer<? extends ConfiguredObject> getRecoverer(String type) + { + return preferencesRecoverer; + } + }; + + Map<String, Object> preferencesAttributes = new HashMap<String, Object>(); + UUID preferencesId = UUID.randomUUID(); + preferencesAttributes.put(PreferencesProvider.TYPE, FileSystemPreferencesProvider.class); + preferencesAttributes.put(PreferencesProvider.NAME, "test-provider"); + File file = TestFileUtils.createTempFile(this, ".prefs.json", "{\"test_user\":{\"pref1\": \"pref1Value\", \"pref2\": 1.0} }"); + preferencesAttributes.put(FileSystemPreferencesProvider.PATH, file.getAbsolutePath()); + ConfigurationEntry preferencesEntry = new ConfigurationEntry(preferencesId, PreferencesProvider.class.getSimpleName(), preferencesAttributes, Collections.<UUID>emptySet(), _configurationStore); + when(_configurationStore.getEntry(preferencesId)).thenReturn(preferencesEntry); + + ConfigurationEntry authenticationProviderEntry = new ConfigurationEntry(authenticationId, AuthenticationProvider.class.getSimpleName(), authenticationAttributes, Collections.singleton(preferencesId), _configurationStore); + try + { + AuthenticationProvider authenticationProvider = _recoverer.create(recovererProvider, authenticationProviderEntry, _broker); + assertNotNull("Authentication provider was not recovered", authenticationProvider); + assertEquals("Unexpected name", "test-authenticator", authenticationProvider.getName()); + assertEquals("Unexpected id", authenticationId, authenticationProvider.getId()); + PreferencesProvider preferencesProvider = authenticationProvider.getPreferencesProvider(); + assertNotNull("Preferences provider was not recovered", preferencesProvider); + assertEquals("Unexpected path", file.getAbsolutePath(), preferencesProvider.getAttribute(FileSystemPreferencesProvider.PATH)); + } + finally + { + file.delete(); + } + } + +} diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/startup/BrokerRecovererTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/startup/BrokerRecovererTest.java index 589f0fc5af..e6db5af222 100644 --- a/qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/startup/BrokerRecovererTest.java +++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/startup/BrokerRecovererTest.java @@ -55,6 +55,8 @@ import org.apache.qpid.server.model.adapter.AccessControlProviderFactory; import org.apache.qpid.server.model.adapter.AuthenticationProviderFactory; import org.apache.qpid.server.model.adapter.GroupProviderFactory; import org.apache.qpid.server.model.adapter.PortFactory; +import org.apache.qpid.server.model.adapter.PreferencesProviderCreator; +import org.apache.qpid.server.configuration.store.StoreConfigurationChangeListener; import org.apache.qpid.server.configuration.updater.TaskExecutor; import org.apache.qpid.server.stats.StatisticsGatherer; import org.apache.qpid.server.virtualhost.VirtualHostRegistry; @@ -76,7 +78,9 @@ public class BrokerRecovererTest extends TestCase super.setUp(); _brokerRecoverer = new BrokerRecoverer(mock(AuthenticationProviderFactory.class), mock(GroupProviderFactory.class), mock(AccessControlProviderFactory.class), mock(PortFactory.class), - mock(StatisticsGatherer.class), mock(VirtualHostRegistry.class), mock(LogRecorder.class), mock(RootMessageLogger.class), mock(TaskExecutor.class), mock(BrokerOptions.class)); + mock(PreferencesProviderCreator.class), + mock(StatisticsGatherer.class), mock(VirtualHostRegistry.class), mock(LogRecorder.class), mock(RootMessageLogger.class), mock(TaskExecutor.class), mock(BrokerOptions.class), + mock(StoreConfigurationChangeListener.class)); when(_brokerEntry.getId()).thenReturn(_brokerId); when(_brokerEntry.getChildren()).thenReturn(_brokerEntryChildren); when(_brokerEntry.getAttributes()).thenReturn(Collections.<String, Object>singletonMap(Broker.MODEL_VERSION, Model.MODEL_VERSION)); diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/startup/DefaultRecovererProviderTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/startup/DefaultRecovererProviderTest.java index b958ba1f56..9e2f2fcf32 100644 --- a/qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/startup/DefaultRecovererProviderTest.java +++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/startup/DefaultRecovererProviderTest.java @@ -35,6 +35,7 @@ import org.apache.qpid.server.model.Plugin; import org.apache.qpid.server.model.Port; import org.apache.qpid.server.model.TrustStore; import org.apache.qpid.server.model.VirtualHost; +import org.apache.qpid.server.configuration.store.StoreConfigurationChangeListener; import org.apache.qpid.server.configuration.updater.TaskExecutor; import org.apache.qpid.server.stats.StatisticsGatherer; import org.apache.qpid.server.virtualhost.VirtualHostRegistry; @@ -55,7 +56,9 @@ public class DefaultRecovererProviderTest extends TestCase RootMessageLogger rootMessageLogger = mock(RootMessageLogger.class); TaskExecutor taskExecutor = mock(TaskExecutor.class); - DefaultRecovererProvider provider = new DefaultRecovererProvider(statisticsGatherer, virtualHostRegistry, logRecorder, rootMessageLogger, taskExecutor, mock(BrokerOptions.class)); + DefaultRecovererProvider provider = new DefaultRecovererProvider(statisticsGatherer, virtualHostRegistry, + logRecorder, rootMessageLogger, taskExecutor, mock(BrokerOptions.class), + mock(StoreConfigurationChangeListener.class)); for (String configuredObjectType : supportedTypes) { ConfiguredObjectRecoverer<?> recovever = provider.getRecoverer(configuredObjectType); diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/startup/PreferencesProviderRecovererTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/startup/PreferencesProviderRecovererTest.java new file mode 100644 index 0000000000..aba9e1e5fa --- /dev/null +++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/startup/PreferencesProviderRecovererTest.java @@ -0,0 +1,75 @@ +package org.apache.qpid.server.configuration.startup; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.io.File; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +import org.apache.qpid.server.configuration.ConfigurationEntry; +import org.apache.qpid.server.configuration.ConfigurationEntryStore; +import org.apache.qpid.server.configuration.RecovererProvider; +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.PreferencesProviderCreator; +import org.apache.qpid.server.util.BrokerTestHelper; +import org.apache.qpid.test.utils.QpidTestCase; +import org.apache.qpid.test.utils.TestFileUtils; + +public class PreferencesProviderRecovererTest extends QpidTestCase +{ + private AuthenticationProvider _authenticationProvider; + private Broker _broker; + + public void setUp() throws Exception + { + super.setUp(); + BrokerTestHelper.setUp(); + _authenticationProvider = mock(AuthenticationProvider.class); + _broker = BrokerTestHelper.createBrokerMock(); + when(_authenticationProvider.getParent(Broker.class)).thenReturn(_broker); + } + + public void tearDown() throws Exception + { + try + { + BrokerTestHelper.tearDown(); + } + finally + { + super.tearDown(); + } + } + + public void testRecoverFileSystemPreferencesProvider() + { + PreferencesProviderRecoverer recoverer = new PreferencesProviderRecoverer(new PreferencesProviderCreator()); + + Map<String, Object> attributes = new HashMap<String, Object>(); + UUID id = UUID.randomUUID(); + attributes.put(PreferencesProvider.TYPE, FileSystemPreferencesProvider.class); + attributes.put(PreferencesProvider.NAME, "test-provider"); + File file = TestFileUtils.createTempFile(this, ".prefs.json", "{\"test_user\":{\"pref1\": \"pref1Value\", \"pref2\": 1.0} }"); + try + { + attributes.put(FileSystemPreferencesProvider.PATH, file.getAbsolutePath()); + ConfigurationEntry entry = new ConfigurationEntry(id, PreferencesProvider.class.getSimpleName(), attributes, Collections.<UUID>emptySet(), mock(ConfigurationEntryStore.class)); + PreferencesProvider provider = recoverer.create(mock(RecovererProvider.class), entry, _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)); + } + finally + { + file.delete(); + } + } + +} diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/model/ConfiguredObjectStateTransitionTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/model/ConfiguredObjectStateTransitionTest.java index 46a81e6454..72cf09585c 100644 --- a/qpid/java/broker/src/test/java/org/apache/qpid/server/model/ConfiguredObjectStateTransitionTest.java +++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/model/ConfiguredObjectStateTransitionTest.java @@ -35,6 +35,7 @@ import org.apache.qpid.server.configuration.ConfigurationEntryStore; import org.apache.qpid.server.configuration.ConfiguredObjectRecoverer; import org.apache.qpid.server.configuration.RecovererProvider; import org.apache.qpid.server.configuration.startup.DefaultRecovererProvider; +import org.apache.qpid.server.configuration.store.StoreConfigurationChangeListener; import org.apache.qpid.server.configuration.updater.TaskExecutor; import org.apache.qpid.server.security.auth.manager.AnonymousAuthenticationManagerFactory; import org.apache.qpid.server.security.group.FileGroupManagerFactory; @@ -62,7 +63,7 @@ public class ConfiguredObjectStateTransitionTest extends QpidTestCase when(_broker.getTaskExecutor()).thenReturn(executor); _recovererProvider = new DefaultRecovererProvider(statisticsGatherer, _broker.getVirtualHostRegistry(), - _broker.getLogRecorder(), _broker.getRootMessageLogger(), executor, new BrokerOptions()); + _broker.getLogRecorder(), _broker.getRootMessageLogger(), executor, new BrokerOptions(), mock(StoreConfigurationChangeListener.class)); _store = mock(ConfigurationEntryStore.class); diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/model/adapter/AuthenticationProviderFactoryTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/model/adapter/AuthenticationProviderFactoryTest.java index fbb1e4105f..ed22843e07 100644 --- a/qpid/java/broker/src/test/java/org/apache/qpid/server/model/adapter/AuthenticationProviderFactoryTest.java +++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/model/adapter/AuthenticationProviderFactoryTest.java @@ -43,6 +43,7 @@ import org.apache.qpid.server.security.auth.manager.PrincipalDatabaseAuthenticat public class AuthenticationProviderFactoryTest extends TestCase { + private PreferencesProviderCreator _preferencesProviderCreator = mock(PreferencesProviderCreator.class); public void testCreatePasswordCredentialManagingAuthenticationProvider() { @@ -95,7 +96,7 @@ public class AuthenticationProviderFactoryTest extends TestCase Collections.singleton(authenticationManagerFactory)); when(authenticationManagerFactory.createInstance(attributes)).thenReturn(authenticationManager); - AuthenticationProviderFactory providerFactory = new AuthenticationProviderFactory(authManagerFactoryServiceLoader); + AuthenticationProviderFactory providerFactory = new AuthenticationProviderFactory(authManagerFactoryServiceLoader, _preferencesProviderCreator); AuthenticationProvider provider = null; if (create) @@ -124,7 +125,7 @@ public class AuthenticationProviderFactoryTest extends TestCase when(managerFactory.createInstance(any(Map.class))).thenReturn(mock(PrincipalDatabaseAuthenticationManager.class)); when(loader.atLeastOneInstanceOf(AuthenticationManagerFactory.class)).thenReturn(Collections.singleton(managerFactory)); - AuthenticationProviderFactory providerFactory = new AuthenticationProviderFactory(loader); + AuthenticationProviderFactory providerFactory = new AuthenticationProviderFactory(loader, _preferencesProviderCreator); UUID randomUUID = UUID.randomUUID(); AuthenticationProvider provider = providerFactory.create(randomUUID, broker, new HashMap<String, Object>()); @@ -145,7 +146,7 @@ public class AuthenticationProviderFactoryTest extends TestCase when(managerFactory.createInstance(any(Map.class))).thenReturn(mock(AuthenticationManager.class)); when(loader.atLeastOneInstanceOf(AuthenticationManagerFactory.class)).thenReturn(Collections.singleton(managerFactory)); - AuthenticationProviderFactory providerFactory = new AuthenticationProviderFactory(loader); + AuthenticationProviderFactory providerFactory = new AuthenticationProviderFactory(loader, _preferencesProviderCreator); UUID id = UUID.randomUUID(); AuthenticationProvider provider = providerFactory.create(id, broker, new HashMap<String, Object>()); diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/model/adapter/FileSystemPreferencesProviderFactoryTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/model/adapter/FileSystemPreferencesProviderFactoryTest.java new file mode 100644 index 0000000000..fcfb1dd0ea --- /dev/null +++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/model/adapter/FileSystemPreferencesProviderFactoryTest.java @@ -0,0 +1,118 @@ +package org.apache.qpid.server.model.adapter; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.io.File; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +import org.apache.qpid.server.configuration.IllegalConfigurationException; +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.util.BrokerTestHelper; +import org.apache.qpid.test.utils.QpidTestCase; +import org.apache.qpid.test.utils.TestFileUtils; + +public class FileSystemPreferencesProviderFactoryTest extends QpidTestCase +{ + private AuthenticationProvider _authenticationProvider; + private Broker _broker; + private FileSystemPreferencesProviderFactory _factory; + + public void setUp() throws Exception + { + super.setUp(); + BrokerTestHelper.setUp(); + _authenticationProvider = mock(AuthenticationProvider.class); + _broker = BrokerTestHelper.createBrokerMock(); + when(_authenticationProvider.getParent(Broker.class)).thenReturn(_broker); + _factory = new FileSystemPreferencesProviderFactory(); + } + + public void tearDown() throws Exception + { + try + { + BrokerTestHelper.tearDown(); + } + finally + { + super.tearDown(); + } + } + + public void testGetType() + { + assertEquals(FileSystemPreferencesProvider.PROVIDER_TYPE, _factory.getType()); + } + + public void testCreateInstanceRecovering() + { + Map<String, Object> attributes = new HashMap<String, Object>(); + UUID id = UUID.randomUUID(); + attributes.put(PreferencesProvider.TYPE, FileSystemPreferencesProvider.class); + attributes.put(PreferencesProvider.NAME, "test-provider"); + File file = TestFileUtils.createTempFile(this, ".prefs.json", "{\"test_user\":{\"pref1\": \"pref1Value\", \"pref2\": 1.0} }"); + try + { + attributes.put(FileSystemPreferencesProvider.PATH, file.getAbsolutePath()); + PreferencesProvider provider = _factory.createInstance(id, attributes, _authenticationProvider); + assertNotNull("Preferences provider was not instantiated", provider); + assertEquals("Unexpected name", "test-provider", provider.getName()); + assertEquals("Unexpected id", id, provider.getId()); + assertEquals("Unexpected path", file.getAbsolutePath(), + provider.getAttribute(FileSystemPreferencesProvider.PATH)); + } + finally + { + file.delete(); + } + } + + public void testCreateInstanceRecoveringWhenPrefStoreDoesNotExist() + { + Map<String, Object> attributes = new HashMap<String, Object>(); + UUID id = UUID.randomUUID(); + attributes.put(PreferencesProvider.TYPE, FileSystemPreferencesProvider.class); + attributes.put(PreferencesProvider.NAME, "test-provider"); + File file = new File(TMP_FOLDER, UUID.randomUUID() + "prefs.json"); + assertFalse("Preferences store file should not exist", file.exists()); + try + { + attributes.put(FileSystemPreferencesProvider.PATH, file.getAbsolutePath()); + _factory.createInstance(id, attributes, _authenticationProvider); + } + catch (IllegalConfigurationException e) + { + // exception should be thrown if preferences store does not exist + } + } + + public void testCreateInstanceNotRecovering() + { + Map<String, Object> attributes = new HashMap<String, Object>(); + UUID id = UUID.randomUUID(); + attributes.put(PreferencesProvider.TYPE, FileSystemPreferencesProvider.class); + attributes.put(PreferencesProvider.NAME, "test-provider"); + File file = new File(TMP_FOLDER, UUID.randomUUID() + "prefs.json"); + assertFalse("Preferences store file should not exist", file.exists()); + try + { + attributes.put(FileSystemPreferencesProvider.PATH, file.getAbsolutePath()); + PreferencesProvider provider = _factory.createInstance(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)); + assertTrue("Preferences store file should exist", file.exists()); + } + finally + { + file.delete(); + } + } + +} |
