You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by or...@apache.org on 2013/09/14 13:24:14 UTC
svn commit: r1523217 - in /qpid/trunk/qpid/java/broker/src:
main/java/org/apache/qpid/server/model/
main/java/org/apache/qpid/server/model/adapter/
test/java/org/apache/qpid/server/model/adapter/
Author: orudyy
Date: Sat Sep 14 11:24:14 2013
New Revision: 1523217
URL: http://svn.apache.org/r1523217
Log:
QPID-5138: Introduce preferences provider interface and its implementation storing preferences on file system
Added:
qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/model/PreferencesProvider.java
qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/FileSystemPreferencesProvider.java
qpid/trunk/qpid/java/broker/src/test/java/org/apache/qpid/server/model/adapter/FileSystemPreferencesProviderTest.java
Added: qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/model/PreferencesProvider.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/model/PreferencesProvider.java?rev=1523217&view=auto
==============================================================================
--- qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/model/PreferencesProvider.java (added)
+++ qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/model/PreferencesProvider.java Sat Sep 14 11:24:14 2013
@@ -0,0 +1,89 @@
+/*
+ *
+ * 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.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Set;
+
+public interface PreferencesProvider extends ConfiguredObject
+{
+ String ID = "id";
+ String NAME = "name";
+ String TYPE = "type";
+ String CREATED = "created";
+ String UPDATED = "updated";
+ String DURABLE = "durable";
+ String LIFETIME_POLICY = "lifetimePolicy";
+ String STATE = "state";
+ String TIME_TO_LIVE = "timeToLive";
+
+ Collection<String> AVAILABLE_ATTRIBUTES =
+ Collections.unmodifiableList(
+ Arrays.asList(
+ ID,
+ NAME,
+ STATE,
+ TYPE,
+ CREATED,
+ UPDATED,
+ DURABLE,
+ LIFETIME_POLICY,
+ TIME_TO_LIVE
+ ));
+
+ /**
+ * Returns preferences {@link Map} for a given user ID
+ * @param userId user ID to retrieve preferences for
+ * @return preferences {@link Map}
+ */
+ Map<String, Object> getPreferences(String userId);
+
+ /**
+ * Set user preferences as specified in a given {@link Map}
+ * @param userId user ID to set preferences for
+ * @param preferences new preferences
+ * @return existing user preferences
+ */
+ Map<String, Object> setPreferences(String userId, Map<String, Object> preferences);
+
+ /**
+ * Delete preferences for a given user ID
+ * @param userId user ID to delete preferences for
+ * @return user preferences before the deletion
+ */
+ Map<String, Object> deletePreferences(String userId);
+
+ /**
+ * Returns set of the user IDs having preferences set
+ * @return user IDs
+ */
+ Set<String> listUserIDs();
+
+ /**
+ * Returns authentication provider associated with this preferences provider
+ * @return authentication provider
+ */
+ AuthenticationProvider getAuthenticationProvider();
+}
Added: qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/FileSystemPreferencesProvider.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/FileSystemPreferencesProvider.java?rev=1523217&view=auto
==============================================================================
--- qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/FileSystemPreferencesProvider.java (added)
+++ qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/FileSystemPreferencesProvider.java Sat Sep 14 11:24:14 2013
@@ -0,0 +1,566 @@
+package org.apache.qpid.server.model.adapter;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+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.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+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.apache.qpid.AMQStoreException;
+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.ConfiguredObject;
+import org.apache.qpid.server.model.IllegalStateTransitionException;
+import org.apache.qpid.server.model.LifetimePolicy;
+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.util.MapValueConverter;
+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;
+
+public class FileSystemPreferencesProvider extends AbstractAdapter implements PreferencesProvider
+{
+ private static final Logger LOGGER = Logger.getLogger(FileSystemPreferencesProvider.class);
+ public static String PATH = "path";
+ public static final String PROVIDER_TYPE = "FileSystemPreferences";
+
+ // TODO: use resolver to resolve path from
+ // '${qpid.work_dir}/preferences/${authenticationProviderName}'
+ @SuppressWarnings("serial")
+ private static final Map<String, Object> DEFAULTS = Collections.unmodifiableMap(new HashMap<String, Object>()
+ {{
+ put(PATH, System.getProperty("user.home") + File.separator + ".qpid" + File.separator + "preferences.json");
+ put(TYPE, FileSystemPreferencesProvider.class.getSimpleName());
+ }});
+
+ @SuppressWarnings("serial")
+ private static final Map<String, Type> ATTRIBUTE_TYPES = Collections.unmodifiableMap(new HashMap<String, Type>()
+ {{
+ put(NAME, String.class);
+ put(PATH, String.class);
+ put(TYPE, String.class);
+ }});
+
+ @SuppressWarnings("serial")
+ private static Collection<String> AVAILABLE_ATTRIBUTES = Collections.unmodifiableList(new ArrayList<String>(
+ PreferencesProvider.AVAILABLE_ATTRIBUTES)
+ {{
+ add(PATH);
+ }});
+
+ private final AuthenticationProvider _authenticationProvider;
+ private AtomicReference<State> _state;
+
+ private final ObjectMapper _objectMapper;
+ private final Map<String, Map<String, Object>> _preferences;
+ private File _preferencesLocation;
+ private FileLock _fileLock;
+
+ protected FileSystemPreferencesProvider(UUID id, Map<String, Object> attributes, AuthenticationProvider authenticationProvider, TaskExecutor taskExecutor)
+ {
+ super(id, DEFAULTS, MapValueConverter.convert(attributes, ATTRIBUTE_TYPES), taskExecutor);
+ State state = MapValueConverter.getEnumAttribute(State.class, STATE, attributes, State.INITIALISING);
+ _state = new AtomicReference<State>(state);
+ addParent(AuthenticationProvider.class, authenticationProvider);
+ _authenticationProvider = authenticationProvider;
+ _objectMapper = new ObjectMapper();
+ _objectMapper.configure(SerializationConfig.Feature.INDENT_OUTPUT, true);
+ _objectMapper.configure(JsonParser.Feature.ALLOW_COMMENTS, true);
+ _preferences = new TreeMap<String, Map<String, Object>>();
+ _preferencesLocation = new File(MapValueConverter.getStringAttribute(PATH, attributes));
+ _preferences.putAll(load(_objectMapper, _preferencesLocation));
+ }
+
+ @Override
+ public Collection<String> getAttributeNames()
+ {
+ return AVAILABLE_ATTRIBUTES;
+ }
+
+ @Override
+ public String getName()
+ {
+ return (String) getAttribute(AuthenticationProvider.NAME);
+ }
+
+ @Override
+ public String setName(String currentName, String desiredName) throws IllegalStateException, AccessControlException
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public State getActualState()
+ {
+ 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 long getTimeToLive()
+ {
+ return 0;
+ }
+
+ @Override
+ public long setTimeToLive(long expected, long desired) throws IllegalStateException, AccessControlException,
+ IllegalArgumentException
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Statistics getStatistics()
+ {
+ return NoStatistics.getInstance();
+ }
+
+ @Override
+ public <C extends ConfiguredObject> Collection<C> getChildren(Class<C> clazz)
+ {
+ return Collections.emptySet();
+ }
+
+ @Override
+ public Object getAttribute(String name)
+ {
+ if (CREATED.equals(name))
+ {
+ // TODO
+ }
+ else 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 getActualState();
+ }
+ else if (TIME_TO_LIVE.equals(name))
+ {
+ // TODO
+ }
+ else if (UPDATED.equals(name))
+ {
+ // TODO
+ }
+ 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
+ {
+ close();
+ }
+ finally
+ {
+ _preferencesLocation.delete();
+ _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
+ {
+ getFileLock();
+ Map<String, Map<String, Object>> preferences = load(_objectMapper, _preferencesLocation);
+ setPreferences(preferences);
+ return true;
+ }
+ catch (Exception 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 new RuntimeException(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))
+ {
+ close();
+ return true;
+ }
+ }
+ else if (desiredState == State.STOPPED)
+ {
+ if (_state.compareAndSet(state, State.STOPPED))
+ {
+ close();
+ return true;
+ }
+ else
+ {
+ throw new IllegalStateException("Cannot stop authentication preferences in state: " + state);
+ }
+ }
+
+ return false;
+ }
+
+ @Override
+ public Map<String, Object> getPreferences(String userId)
+ {
+ Map<String, Object> userPreferences = null;
+ synchronized (_preferences)
+ {
+ userPreferences = _preferences.get(userId);
+ }
+ if (userPreferences != null)
+ {
+ return new HashMap<String, Object>(userPreferences);
+ }
+ return Collections.emptyMap();
+ }
+
+ @Override
+ public Map<String, Object> setPreferences(String userId, Map<String, Object> preferences)
+ {
+ 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);
+ }
+ savePreferences();
+ }
+ return userPreferences;
+ }
+
+ @Override
+ public Map<String, Object> deletePreferences(String userId)
+ {
+ Map<String, Object> userPreferences = null;
+ synchronized (_preferences)
+ {
+ if (_preferences.containsKey(userId))
+ {
+ userPreferences = _preferences.remove(userId);
+ savePreferences();
+ }
+ }
+ return userPreferences;
+ }
+
+ @Override
+ public Set<String> listUserIDs()
+ {
+ synchronized (_preferences)
+ {
+ return Collections.unmodifiableSet(_preferences.keySet());
+ }
+ }
+
+ public 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);
+ Map<String, Map<String, Object>> newPreferences = null;
+ File storeFile = new File(effectivePath);
+ if (!effectivePath.equals(currentPath))
+ {
+ if (!storeFile.exists())
+ {
+ throw new IllegalConfigurationException("Path to preferences file does not exist!");
+ }
+ newPreferences = load(_objectMapper, storeFile);
+ }
+ super.changeAttributes(attributes);
+
+ if (newPreferences != null)
+ {
+ setPreferences(newPreferences);
+ _preferencesLocation = storeFile;
+ }
+
+ // if provider was previously in ERRORED state then set its state to
+ // ACTIVE
+ _state.compareAndSet(State.ERRORED, State.ACTIVE);
+ }
+
+ private void setPreferences(Map<String, Map<String, Object>> preferences)
+ {
+ synchronized (_preferences)
+ {
+ _preferences.clear();
+ _preferences.putAll(preferences);
+ }
+ }
+
+ 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 (!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("") || !(path instanceof String))
+ {
+ throw new IllegalConfigurationException("Path to preferences file is not specified");
+ }
+ }
+
+ public File createStoreIfNotExist()
+ {
+ String path = (String)getAttribute(PATH);
+ File preferencesLocation = new File(path);
+ if (!preferencesLocation.exists())
+ {
+ File parent = preferencesLocation.getParentFile();
+ if (!parent.exists() && !parent.mkdirs())
+ {
+ throw new IllegalConfigurationException("Cannot store preferences at " + path);
+ }
+ try
+ {
+ preferencesLocation.createNewFile();
+ }
+ catch (IOException e)
+ {
+ throw new IllegalConfigurationException("Cannot store preferences at " + path);
+ }
+ }
+ return preferencesLocation;
+ }
+
+ private Map<String, Map<String, Object>> load(ObjectMapper mapper, File file)
+ {
+ if (!file.exists() || file.length() == 0)
+ {
+ return Collections.emptyMap();
+ }
+
+ try
+ {
+ return mapper.readValue(file, new TypeReference<Map<String, Map<String, Object>>>()
+ {
+ });
+ }
+ catch (JsonProcessingException e)
+ {
+ throw new IllegalConfigurationException("Cannot parse json", e);
+ }
+ catch (IOException e)
+ {
+ throw new IllegalConfigurationException("Cannot read json", e);
+ }
+ }
+
+ private void savePreferences()
+ {
+ save(_objectMapper, _preferencesLocation, _preferences);
+ }
+
+ private void save(ObjectMapper mapper, File file, Map<String, Map<String, Object>> preferences)
+ {
+ try
+ {
+ RandomAccessFile raf = new RandomAccessFile(file, "rw");
+ try
+ {
+ FileChannel channel = raf.getChannel();
+ try
+ {
+ FileLock lock = null;
+ try
+ {
+ lock = channel.tryLock();
+ if (lock == null)
+ {
+ throw new IllegalConfigurationException("Cannot aquire exclusive lock on preferences file for "
+ + getName());
+ }
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ mapper.writeValue(baos, preferences);
+ channel.write(ByteBuffer.wrap(baos.toByteArray()));
+ }
+ catch (OverlappingFileLockException e)
+ {
+ throw new IllegalConfigurationException("Cannot aquire exclusive lock on preferences file for "
+ + getName(), e);
+ }
+ finally
+ {
+ if (lock != null)
+ {
+ lock.release();
+ }
+ }
+ }
+ finally
+ {
+ channel.close();
+ }
+ }
+ finally
+ {
+ raf.close();
+ }
+ }
+ catch (FileNotFoundException e)
+ {
+ throw new IllegalConfigurationException("Cannot find preferences file for " + getName(), e);
+ }
+ catch (IOException e)
+ {
+ throw new IllegalConfigurationException("Cannot store preferences file for " + getName(), e);
+ }
+ }
+
+ private void getFileLock() throws IOException, AMQStoreException
+ {
+ File lockFile = new File(_preferencesLocation.getAbsolutePath() + ".lck");
+ lockFile.createNewFile();
+
+ FileOutputStream out = new FileOutputStream(lockFile);
+ FileChannel channel = out.getChannel();
+ try
+ {
+ _fileLock = channel.tryLock();
+ }
+ catch(OverlappingFileLockException e)
+ {
+ _fileLock = null;
+ }
+ if(_fileLock == null)
+ {
+ throw new AMQStoreException("Cannot get lock on file " + lockFile.getAbsolutePath() + " is another instance running?");
+ }
+ lockFile.deleteOnExit();
+ }
+
+ public void close()
+ {
+ try
+ {
+ releaseFileLock();
+ }
+ catch(IOException e)
+ {
+ LOGGER.error("Cannot close file system preferences provider", e);
+ }
+ finally
+ {
+ new File(_preferencesLocation.getAbsolutePath() + ".lck").delete();
+ _fileLock = null;
+ _preferences.clear();
+ }
+ }
+
+ private void releaseFileLock() throws IOException
+ {
+ _fileLock.release();
+ _fileLock.channel().close();
+ }
+}
Added: qpid/trunk/qpid/java/broker/src/test/java/org/apache/qpid/server/model/adapter/FileSystemPreferencesProviderTest.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker/src/test/java/org/apache/qpid/server/model/adapter/FileSystemPreferencesProviderTest.java?rev=1523217&view=auto
==============================================================================
--- qpid/trunk/qpid/java/broker/src/test/java/org/apache/qpid/server/model/adapter/FileSystemPreferencesProviderTest.java (added)
+++ qpid/trunk/qpid/java/broker/src/test/java/org/apache/qpid/server/model/adapter/FileSystemPreferencesProviderTest.java Sat Sep 14 11:24:14 2013
@@ -0,0 +1,246 @@
+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.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+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.AuthenticationProvider;
+import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.model.State;
+import org.apache.qpid.server.util.BrokerTestHelper;
+import org.apache.qpid.test.utils.QpidTestCase;
+import org.apache.qpid.test.utils.TestFileUtils;
+
+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 AuthenticationProvider _authenticationProvider;
+ private Broker _broker;
+ private String _user1, _user2;
+ private File _preferencesFile;
+
+ protected void setUp() throws Exception
+ {
+ super.setUp();
+ BrokerTestHelper.setUp();
+ _authenticationProvider = mock(AuthenticationProvider.class);
+ _user1 = "user1";
+ _user2 = "user2";
+ _preferencesFile = TestFileUtils.createTempFile(this, ".prefs.json", TEST_PREFERENCES);
+
+ _broker = BrokerTestHelper.createBrokerMock();
+ TaskExecutor taslExecutor = mock(TaskExecutor.class);
+ when(taslExecutor.isTaskExecutorThread()).thenReturn(true);
+ when(_broker.getTaskExecutor()).thenReturn(taslExecutor);
+ when(_authenticationProvider.getParent(Broker.class)).thenReturn(_broker);
+ }
+
+ protected void tearDown() throws Exception
+ {
+ try
+ {
+ BrokerTestHelper.tearDown();
+ _preferencesFile.delete();
+ }
+ finally
+ {
+ super.tearDown();
+ }
+ }
+
+ public void testConstructionWithExistingFile()
+ {
+ _preferencesProvider = createPreferencesProvider();
+ assertEquals(State.INITIALISING, _preferencesProvider.getActualState());
+ }
+
+ public void testConstructionWithNonExistingFile()
+ {
+ File nonExistingFile = new File(TMP_FOLDER, "preferences-" + UUID.randomUUID() + ".json");
+ assertFalse("Preferences file exists", nonExistingFile.exists());
+ try
+ {
+ Map<String, Object> attributes = new HashMap<String, Object>();
+ attributes.put(FileSystemPreferencesProvider.PATH, nonExistingFile.getAbsolutePath());
+ _preferencesProvider = new FileSystemPreferencesProvider(UUID.randomUUID(), attributes, _authenticationProvider, _broker.getTaskExecutor());
+ _preferencesProvider.createStoreIfNotExist();
+ assertEquals(State.INITIALISING, _preferencesProvider.getActualState());
+ assertTrue("Preferences file was not created", nonExistingFile.exists());
+ }
+ finally
+ {
+ nonExistingFile.delete();
+ }
+ }
+
+ public void testConstructionWithEmptyFile() throws Exception
+ {
+ File emptyPrefsFile = new File(TMP_FOLDER, "preferences-" + UUID.randomUUID() + ".json");
+ emptyPrefsFile.createNewFile();
+ assertTrue("Preferences file does notexists", emptyPrefsFile.exists());
+ try
+ {
+ Map<String, Object> attributes = new HashMap<String, Object>();
+ attributes.put(FileSystemPreferencesProvider.PATH, emptyPrefsFile.getAbsolutePath());
+ _preferencesProvider = new FileSystemPreferencesProvider(UUID.randomUUID(), attributes, _authenticationProvider, _broker.getTaskExecutor());
+ assertEquals(State.INITIALISING, _preferencesProvider.getActualState());
+ }
+ finally
+ {
+ emptyPrefsFile.delete();
+ }
+ }
+
+ public void testActivate()
+ {
+ _preferencesProvider = createPreferencesProvider();
+ _preferencesProvider.setDesiredState(State.INITIALISING, State.ACTIVE);
+
+ assertEquals("Unexpexpected state", State.ACTIVE, _preferencesProvider.getActualState());
+ }
+
+ public void testChangeAttributes()
+ {
+ _preferencesProvider = createPreferencesProvider();
+ _preferencesProvider.setDesiredState(State.INITIALISING, State.ACTIVE);
+
+ File newPrefsFile = TestFileUtils.createTempFile(this, ".prefs.json", "{\"user3\":{\"pref1\":\"pref1User3Value\", \"pref3\": 2.0}}");
+ try
+ {
+ Map<String, Object> attributes = new HashMap<String, Object>();
+ attributes.put(FileSystemPreferencesProvider.PATH, newPrefsFile.getAbsolutePath());
+ _preferencesProvider.changeAttributes(attributes);
+ assertEquals("Unexpected path", newPrefsFile.getAbsolutePath(),
+ _preferencesProvider.getAttribute(FileSystemPreferencesProvider.PATH));
+
+ Map<String, Object> preferences1 = _preferencesProvider.getPreferences(_user1);
+ assertTrue("Unexpected preferences for user1", preferences1.isEmpty());
+
+ String user3 = "user3";
+ Map<String, Object> preferences3 = _preferencesProvider.getPreferences(user3);
+ assertFalse("No preference found for user3", preferences3.isEmpty());
+ assertEquals("Unexpected preference 1 for user 3", "pref1User3Value", preferences3.get("pref1"));
+ assertEquals("Unexpected preference 3 for user 3", 2.0, ((Number) preferences3.get("pref3")).floatValue(), 0.01);
+ }
+ finally
+ {
+ newPrefsFile.delete();
+ }
+ }
+
+ public void testGetPreferences()
+ {
+ _preferencesProvider = createPreferencesProvider();
+ _preferencesProvider.setDesiredState(State.INITIALISING, State.ACTIVE);
+
+ Map<String, Object> preferences1 = _preferencesProvider.getPreferences(_user1);
+ assertUser1Preferences(preferences1);
+
+ Map<String, Object> preferences2 = _preferencesProvider.getPreferences(_user2);
+ assertUser2Preferences(preferences2);
+
+ String user3 = "user3";
+ Map<String, Object> preferences3 = _preferencesProvider.getPreferences(user3);
+ assertTrue("No preference found for user3", preferences3.isEmpty());
+ }
+
+ public void testSetPrefernces()
+ {
+ _preferencesProvider = createPreferencesProvider();
+ _preferencesProvider.setDesiredState(State.INITIALISING, State.ACTIVE);
+
+ Map<String, Object> newPreferences = new HashMap<String, Object>();
+ newPreferences.put("pref2", false);
+ newPreferences.put("pref4", 8);
+ Map<String, Object> pref5 = new HashMap<String, Object>();
+ pref5.put("test1", "test1Value");
+ pref5.put("test2", 5);
+ newPreferences.put("pref5", pref5);
+
+ _preferencesProvider.setPreferences(_user1, newPreferences);
+
+ FileSystemPreferencesProvider newProvider = createPreferencesProvider();
+ Map<String, Object> preferences1 = newProvider.getPreferences(_user1);
+ assertNotNull("Preferences should not be null for user 1", preferences1);
+ assertEquals("Unexpected preference 1 for user 1", "pref1User1Value", preferences1.get("pref1"));
+ assertEquals("Unexpected preference 2 for user 1", false, preferences1.get("pref2"));
+ assertEquals("Unexpected preference 3 for user 1", 1.0, ((Number) preferences1.get("pref3")).floatValue(), 0.01);
+ assertEquals("Unexpected preference 4 for user 1", 8, preferences1.get("pref4"));
+ assertNotNull("Unexpected preference 5 for user 1", preferences1.get("pref5"));
+ assertEquals("Unexpected preference 5 for user 1", pref5, preferences1.get("pref5"));
+
+ Map<String, Object> preferences2 = newProvider.getPreferences(_user2);
+ assertUser2Preferences(preferences2);
+
+ String user3 = "user3";
+ Map<String, Object> preferences3 = newProvider.getPreferences(user3);
+ assertTrue("No preference found for user3", preferences3.isEmpty());
+ }
+
+ public void testDeletePrefernces()
+ {
+ _preferencesProvider = createPreferencesProvider();
+ _preferencesProvider.setDesiredState(State.INITIALISING, State.ACTIVE);
+
+ _preferencesProvider.deletePreferences(_user1);
+
+ FileSystemPreferencesProvider newProvider = createPreferencesProvider();
+ Map<String, Object> preferences1 = newProvider.getPreferences(_user1);
+ assertTrue("Preferences should not be set for user 1", preferences1.isEmpty());
+
+ Map<String, Object> preferences2 = newProvider.getPreferences(_user2);
+ assertUser2Preferences(preferences2);
+
+ String user3 = "user3";
+ Map<String, Object> preferences3 = newProvider.getPreferences(user3);
+ assertTrue("No preference found for user3", preferences3.isEmpty());
+ }
+
+ public void testListUserNames()
+ {
+ _preferencesProvider = createPreferencesProvider();
+ _preferencesProvider.setDesiredState(State.INITIALISING, State.ACTIVE);
+
+ Set<String> userNames = _preferencesProvider.listUserIDs();
+
+ assertEquals("Unexpected user names", new HashSet<String>(Arrays.asList("user1", "user2")), userNames);
+ }
+
+ private FileSystemPreferencesProvider 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, _broker.getTaskExecutor());
+ }
+
+ private void assertUser1Preferences(Map<String, Object> preferences1)
+ {
+ assertNotNull("Preferences should not be null for user 1", preferences1);
+ assertEquals("Unexpected preference 1 for user 1", "pref1User1Value", preferences1.get("pref1"));
+ assertEquals("Unexpected preference 2 for user 1", true, preferences1.get("pref2"));
+ assertEquals("Unexpected preference 3 for user 1", 1.0, ((Number) preferences1.get("pref3")).floatValue(), 0.01);
+ assertEquals("Unexpected preference 4 for user 1", 2, preferences1.get("pref4"));
+ assertNull("Unexpected preference 5 for user 1", preferences1.get("pref5"));
+ }
+
+ private void assertUser2Preferences(Map<String, Object> preferences2)
+ {
+ assertNotNull("Preferences should not be null for user 2", preferences2);
+ assertEquals("Unexpected preference 1 for user 2", "pref1User2Value", preferences2.get("pref1"));
+ assertEquals("Unexpected preference 2 for user 2", false, preferences2.get("pref2"));
+ assertEquals("Unexpected preference 2 for user 2", 2.0, ((Number) preferences2.get("pref3")).floatValue(), 0.01);
+ assertEquals("Unexpected preference 3 for user 2", 3, preferences2.get("pref4"));
+ assertNull("Unexpected preference 5 for user 2", preferences2.get("pref5"));
+ }
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org