Author: [email protected]
Date: Wed Jun  6 11:29:05 2012
New Revision: 2437

Log:
[AMDATUCASSANDRA-190] Fixed NullPointerException in CassandraStorageProvider 
and added unit tests to check for this error

Added:
   
branches/amdatu-cassandra-0.2.4/cassandra-stores/cassandra-store-useradmin/src/test/
   
branches/amdatu-cassandra-0.2.4/cassandra-stores/cassandra-store-useradmin/src/test/java/
   
branches/amdatu-cassandra-0.2.4/cassandra-stores/cassandra-store-useradmin/src/test/java/org/
   
branches/amdatu-cassandra-0.2.4/cassandra-stores/cassandra-store-useradmin/src/test/java/org/amdatu/
   
branches/amdatu-cassandra-0.2.4/cassandra-stores/cassandra-store-useradmin/src/test/java/org/amdatu/cassandra/
   
branches/amdatu-cassandra-0.2.4/cassandra-stores/cassandra-store-useradmin/src/test/java/org/amdatu/cassandra/test/
   
branches/amdatu-cassandra-0.2.4/cassandra-stores/cassandra-store-useradmin/src/test/java/org/amdatu/cassandra/test/unit/
   
branches/amdatu-cassandra-0.2.4/cassandra-stores/cassandra-store-useradmin/src/test/java/org/amdatu/cassandra/test/unit/MockedUserAdminFactory.java
   
branches/amdatu-cassandra-0.2.4/cassandra-stores/cassandra-store-useradmin/src/test/java/org/amdatu/cassandra/test/unit/UserAdminStoreTest.java
   
branches/amdatu-cassandra-0.2.4/test-unit/framework/src/main/java/org/amdatu/cassandra/test/unit/framework/mock/BundleContextMock.java
   
branches/amdatu-cassandra-0.2.4/test-unit/framework/src/main/java/org/amdatu/cassandra/test/unit/framework/mock/FilterMock.java
   
branches/amdatu-cassandra-0.2.4/test-unit/framework/src/main/java/org/amdatu/cassandra/test/unit/framework/mock/ServiceReferenceMock.java
   
branches/amdatu-cassandra-0.2.4/test-unit/framework/src/main/java/org/amdatu/cassandra/test/unit/framework/mock/ServiceRegistrationMock.java
Modified:
   
branches/amdatu-cassandra-0.2.4/cassandra-listener/src/test/java/org/amdatu/cassandra/test/unit/listener/ListenerTest.java
   
branches/amdatu-cassandra-0.2.4/cassandra-listener/src/test/java/org/amdatu/cassandra/test/unit/listener/mock/BundleContextMock.java
   
branches/amdatu-cassandra-0.2.4/cassandra-listener/src/test/java/org/amdatu/cassandra/test/unit/listener/mock/ServiceReferenceMock.java
   
branches/amdatu-cassandra-0.2.4/cassandra-listener/src/test/java/org/amdatu/cassandra/test/unit/listener/mock/ServiceRegistrationMock.java
   
branches/amdatu-cassandra-0.2.4/cassandra-stores/cassandra-store-useradmin/src/main/java/org/amdatu/cassandra/store/useradmin/service/CassandraStorageProvider.java
   
branches/amdatu-cassandra-0.2.4/cassandra-stores/cassandra-store-useradmin/src/main/java/org/amdatu/cassandra/store/useradmin/service/RoleColumnFamilyProvider.java
   branches/amdatu-cassandra-0.2.4/test-unit/framework/pom.xml

Modified: 
branches/amdatu-cassandra-0.2.4/cassandra-listener/src/test/java/org/amdatu/cassandra/test/unit/listener/ListenerTest.java
==============================================================================
--- 
branches/amdatu-cassandra-0.2.4/cassandra-listener/src/test/java/org/amdatu/cassandra/test/unit/listener/ListenerTest.java
  (original)
+++ 
branches/amdatu-cassandra-0.2.4/cassandra-listener/src/test/java/org/amdatu/cassandra/test/unit/listener/ListenerTest.java
  Wed Jun  6 11:29:05 2012
@@ -26,8 +26,8 @@
 import org.amdatu.cassandra.listener.service.CassandraUpdateListenerImpl;
 import org.amdatu.cassandra.persistencemanager.CassandraPersistenceManager;
 import org.amdatu.cassandra.test.unit.framework.UnitTestFramework;
+import org.amdatu.cassandra.test.unit.framework.mock.BundleContextMock;
 import org.amdatu.cassandra.test.unit.framework.mock.EventAdminMock;
-import org.amdatu.cassandra.test.unit.listener.mock.BundleContextMock;
 import org.amdatu.cassandra.test.unit.listener.mock.CPMFactoryMock;
 
 import java.nio.ByteBuffer;

Modified: 
branches/amdatu-cassandra-0.2.4/cassandra-stores/cassandra-store-useradmin/src/main/java/org/amdatu/cassandra/store/useradmin/service/CassandraStorageProvider.java
==============================================================================
--- 
branches/amdatu-cassandra-0.2.4/cassandra-stores/cassandra-store-useradmin/src/main/java/org/amdatu/cassandra/store/useradmin/service/CassandraStorageProvider.java
 (original)
+++ 
branches/amdatu-cassandra-0.2.4/cassandra-stores/cassandra-store-useradmin/src/main/java/org/amdatu/cassandra/store/useradmin/service/CassandraStorageProvider.java
 Wed Jun  6 11:29:05 2012
@@ -15,8 +15,14 @@
  */
 package org.amdatu.cassandra.store.useradmin.service;
 
+import me.prettyprint.cassandra.serializers.SerializerTypeInferer;
+import me.prettyprint.cassandra.serializers.StringSerializer;
+import me.prettyprint.hector.api.Keyspace;
+import me.prettyprint.hector.api.Serializer;
 import me.prettyprint.hector.api.beans.HColumn;
 import me.prettyprint.hector.api.beans.HSuperColumn;
+import me.prettyprint.hector.api.factory.HFactory;
+import me.prettyprint.hector.api.mutation.Mutator;
 
 import 
org.amdatu.cassandra.persistencemanager.hector.HectorCassandraPersistenceManager;
 
@@ -90,6 +96,24 @@
     public void stop() {
         m_logService.log(LogService.LOG_INFO, "Cassandra storage provider 
service stopped");
     }
+    
+    /**
+     * Default (empty) constructor.
+     */
+    public CassandraStorageProvider() {
+    }
+
+    /**
+     * Constructor used by the Unit test.
+     * 
+     * @param pm
+     * @param logService
+     */
+    public CassandraStorageProvider(final HectorCassandraPersistenceManager 
pm, final LogService logService, BundleContext context) {
+        m_pm = pm;
+        m_logService = logService;
+        m_context = context;
+    }
 
     // Creates a new user with the specified name
     @Override
@@ -173,7 +197,7 @@
         WriteLock lock = m_lock.writeLock();
         try {
             lock.lock();
-            internalClearProperties(user, SUPER_COLUMN_CREDENTIALS);
+            internalClearCredentials(user);
         }
         finally {
             lock.unlock();
@@ -365,7 +389,7 @@
         WriteLock lock = m_lock.writeLock();
         try {
             lock.lock();
-            internalClearProperties(role, SUPER_COLUMN_PROPERTIES);
+            internalClearProperties(role);
         }
         finally {
             lock.unlock();
@@ -602,33 +626,39 @@
     }
 
     // Adds a single property to a persistent map. Note that key=column
-    private void internalAddProperty(final Role role, final String 
superColumn, final String key, final Object value)
+    private <T extends Object> void internalAddProperty(final Role role, final 
String superColumn, final String key, final Object value)
         throws StorageException {
-        String rowKey = getKey(role);
-        m_pm.setValue(CF_ROLE, rowKey, superColumn, key, value);
-        if (value instanceof String) {
-            m_pm.setValue(CF_ROLE, rowKey, SUPER_COLUMN_PROPERTY_TYPES, key, 
STRING_TYPE);
-        }
-        else if (value instanceof byte[]) {
-            m_pm.setValue(CF_ROLE, rowKey, SUPER_COLUMN_PROPERTY_TYPES, key, 
BYTES_TYPE);
-        }
-        else {
+        // The UserAdmin OSGi spec only supports String and byte[] values
+        if (!(value instanceof String) && !(value instanceof byte[])) {
             throw new StorageException(
-                "The current implementation of the UserAdmin only supports 
storing properties of type byte[]");
+            "The OSGi UserAdmin specification only supports storing 
credentials and properties of type String and byte[]");
+        }
+        
+        // Use atomic operation to add the property and its type
+        if (SUPER_COLUMN_CREDENTIALS.equals(superColumn)) {
+            String rowKey = getKey(role);
+            m_pm.setValue(CF_ROLE, rowKey, superColumn, key, value);
+        } else {
+            atomicAddProperty(getKey(role), key, value);
         }
     }
 
     // Removes a single property from a persistent map
     private void internalRemoveProperty(final Role role, final String 
superColumn, final String key)
         throws StorageException {
-        m_pm.deleteColumn(CF_ROLE, getKey(role), superColumn, key);
-        m_pm.deleteColumn(CF_ROLE, getKey(role), SUPER_COLUMN_PROPERTY_TYPES, 
key);
+        // Use atomic operation to remove the property and its type
+        atomicRemoveProperty(getKey(role), key);
     }
-
+    
+    // Clears all properties from a persistent map
+    private void internalClearCredentials(final Role role) throws 
StorageException {
+        m_pm.deleteSuperColumn(CF_ROLE, getKey(role), 
SUPER_COLUMN_CREDENTIALS);
+    }
+    
     // Clears all properties from a persistent map
-    private void internalClearProperties(final Role role, final String 
superColumn) throws StorageException {
-        m_pm.deleteSuperColumn(CF_ROLE, getKey(role), superColumn);
-        m_pm.deleteSuperColumn(CF_ROLE, getKey(role), 
SUPER_COLUMN_PROPERTY_TYPES);
+    private void internalClearProperties(final Role role) throws 
StorageException {
+        // Use atomic operation to remove the properties and its types
+        atomicRemoveProperty(getKey(role), null);
     }
 
     // Converts Object to a Json string
@@ -659,4 +689,66 @@
             }
         }
     }
+    
+    // Atomic implementation of add property: sets property value and property 
type in batch
+    private <T extends Object> void atomicAddProperty(final String rowKey, 
final String name, final T value) {
+        // Get the atomic mutator
+        Keyspace ks = m_pm.getHectorKeyspace();
+        StringSerializer stringSerializer = StringSerializer.get();
+        Mutator<String> mutator = HFactory.createMutator(ks, stringSerializer);
+        Serializer<T> propValueSerializer = 
SerializerTypeInferer.getSerializer(value);
+        
+        // Create the properties column to insert/update
+        HColumn<String, T> propColumn = HFactory.createColumn(name, value, 
stringSerializer, propValueSerializer);
+        List<HColumn<String, T>> propColumnList = toList(propColumn);
+        
+        // Insert/update the column in the properties super column
+        mutator.addInsertion(rowKey, CF_ROLE, 
HFactory.createSuperColumn(SUPER_COLUMN_PROPERTIES, propColumnList,
+            stringSerializer, stringSerializer, propValueSerializer));
+        
+        // Create the properties column to insert/update
+        HColumn<String, String> propTypeColumn;
+        if (value instanceof String) {
+            propTypeColumn = HFactory.createColumn(name, STRING_TYPE, 
stringSerializer, stringSerializer);
+        } else {
+            propTypeColumn = HFactory.createColumn(name, BYTES_TYPE, 
stringSerializer, stringSerializer);
+        }
+        List<HColumn<String, String>> propTypeColumnList = 
toList(propTypeColumn);
+        
+        // Insert/update the column in the property types super column
+        mutator.addInsertion(rowKey, CF_ROLE, 
HFactory.createSuperColumn(SUPER_COLUMN_PROPERTY_TYPES, propTypeColumnList,
+            stringSerializer, stringSerializer, stringSerializer));
+        mutator.execute();
+    }
+    
+    // Atomic implementation of remove property: removes property value and 
property type in batch
+    // The name may be null, in that case ALL properties are removed, but 
without removing the complete
+    // supercolumn (only the columns are removed).
+    private void atomicRemoveProperty(final String rowKey, final String name) {
+        // Get the atomic mutator
+        Keyspace ks = m_pm.getHectorKeyspace();
+        StringSerializer stringSerializer = StringSerializer.get();
+        Mutator<String> mutator = HFactory.createMutator(ks, stringSerializer);
+        
+        if (name == null) {
+            // Loop over all columns in the properties supercolumn and delete 
the columns by name
+            List<HSuperColumn<String, String, byte[]>> superColumns = 
m_pm.getSuperColumns(CF_ROLE, rowKey, byte[].class);
+            HSuperColumn<String, String, byte[]> propertiesSC = 
getSuperColumn(superColumns, SUPER_COLUMN_PROPERTIES);
+            List<HColumn<String, byte[]>> columns = propertiesSC.getColumns();
+            for (HColumn<String, byte[]> column : columns) {
+                mutator.addSubDelete(rowKey, CF_ROLE, SUPER_COLUMN_PROPERTIES, 
column.getName(), stringSerializer, stringSerializer);
+                mutator.addSubDelete(rowKey, CF_ROLE, 
SUPER_COLUMN_PROPERTY_TYPES, column.getName(), stringSerializer, 
stringSerializer);
+            }
+        } else {
+            mutator.addSubDelete(rowKey, CF_ROLE, SUPER_COLUMN_PROPERTIES, 
name, stringSerializer, stringSerializer);
+            mutator.addSubDelete(rowKey, CF_ROLE, SUPER_COLUMN_PROPERTY_TYPES, 
name, stringSerializer, stringSerializer);
+        }
+        mutator.execute();
+    }
+
+    private <T extends Object> List<HColumn<String, T>> toList(final 
HColumn<String, T> column) {
+        List<HColumn<String, T>> list = new ArrayList<HColumn<String, T>>();
+        list.add(column);
+        return list;
+    }
 }

Modified: 
branches/amdatu-cassandra-0.2.4/cassandra-stores/cassandra-store-useradmin/src/main/java/org/amdatu/cassandra/store/useradmin/service/RoleColumnFamilyProvider.java
==============================================================================
--- 
branches/amdatu-cassandra-0.2.4/cassandra-stores/cassandra-store-useradmin/src/main/java/org/amdatu/cassandra/store/useradmin/service/RoleColumnFamilyProvider.java
 (original)
+++ 
branches/amdatu-cassandra-0.2.4/cassandra-stores/cassandra-store-useradmin/src/main/java/org/amdatu/cassandra/store/useradmin/service/RoleColumnFamilyProvider.java
 Wed Jun  6 11:29:05 2012
@@ -38,6 +38,15 @@
     // This service is tenant aware
     private Tenant m_tenant;
 
+    /**
+     * Sets the tenant.
+     * 
+     * @param tenant the tenant
+     */
+    public void setTenant(final Tenant tenant) {
+        m_tenant = tenant;
+    }
+
     @Override
     public ColumnFamilyDefinition[] getColumnFamilies() {
         return new ColumnFamilyDefinition[] {new ColumnFamilyDefinition(

Added: 
branches/amdatu-cassandra-0.2.4/cassandra-stores/cassandra-store-useradmin/src/test/java/org/amdatu/cassandra/test/unit/MockedUserAdminFactory.java
==============================================================================
--- (empty file)
+++ 
branches/amdatu-cassandra-0.2.4/cassandra-stores/cassandra-store-useradmin/src/test/java/org/amdatu/cassandra/test/unit/MockedUserAdminFactory.java
 Wed Jun  6 11:29:05 2012
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2010, 2011 The Amdatu Foundation
+ *
+ * Licensed 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.amdatu.cassandra.test.unit;
+
+import java.util.Dictionary;
+import java.util.Hashtable;
+import java.util.Map;
+
+import org.apache.commons.lang.NotImplementedException;
+import org.ops4j.pax.useradmin.service.spi.UserAdminFactory;
+import org.osgi.service.useradmin.Group;
+import org.osgi.service.useradmin.Role;
+import org.osgi.service.useradmin.User;
+
+@SuppressWarnings({"rawtypes", "unchecked"})
+public class MockedUserAdminFactory implements UserAdminFactory {
+
+    private Dictionary toDictionary(Map<String, Object> map) {
+        Dictionary dictionary = null;
+        if (map != null) {
+            dictionary = new Hashtable<String, Object>();
+            for (String key : map.keySet()) {
+                dictionary.put(key, map.get(key));
+            }
+        }
+        return dictionary;
+    }
+
+    public User createUser(final String aName, final Map<String, Object> 
propertiesMap,
+        final Map<String, Object> credentialsMap) {
+        final String name = aName;
+        final Dictionary properties = toDictionary(propertiesMap);
+        final Dictionary credentials = toDictionary(credentialsMap);
+        return new User() {
+            public String getName() {
+                return name;
+            }
+
+            public int getType() {
+                return Role.USER;
+            }
+
+            public Dictionary getProperties() {
+                return properties;
+            }
+
+            public Dictionary getCredentials() {
+                return credentials;
+            }
+
+            public boolean hasCredential(String key, Object value) {
+                return credentials != null && credentials.get(key) != null;
+            }
+        };
+    }
+
+    public Group createGroup(String aName, Map<String, Object> propertiesMap, 
Map<String, Object> credentialsMap) {
+        final String name = aName;
+        final Dictionary properties = toDictionary(propertiesMap);
+        final Dictionary credentials = toDictionary(credentialsMap);
+        return new Group() {
+
+            public Dictionary getCredentials() {
+                return credentials;
+            }
+
+            public boolean hasCredential(String key, Object value) {
+                return credentials != null && credentials.get(key) != null;
+            }
+
+            public String getName() {
+                return name;
+            }
+
+            public int getType() {
+                return Role.GROUP;
+            }
+
+            public Dictionary getProperties() {
+                return properties;
+            }
+
+            public boolean addMember(Role role) {
+                throw new NotImplementedException("This method is not yet 
implemented in this mock object");
+            }
+
+            public boolean addRequiredMember(Role role) {
+                throw new NotImplementedException("This method is not yet 
implemented in this mock object");
+            }
+
+            public boolean removeMember(Role role) {
+                throw new NotImplementedException("This method is not yet 
implemented in this mock object");
+            }
+
+            public Role[] getMembers() {
+                throw new NotImplementedException("This method is not yet 
implemented in this mock object");
+            }
+
+            public Role[] getRequiredMembers() {
+                throw new NotImplementedException("This method is not yet 
implemented in this mock object");
+            }
+        };
+    }
+}

Added: 
branches/amdatu-cassandra-0.2.4/cassandra-stores/cassandra-store-useradmin/src/test/java/org/amdatu/cassandra/test/unit/UserAdminStoreTest.java
==============================================================================
--- (empty file)
+++ 
branches/amdatu-cassandra-0.2.4/cassandra-stores/cassandra-store-useradmin/src/test/java/org/amdatu/cassandra/test/unit/UserAdminStoreTest.java
     Wed Jun  6 11:29:05 2012
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 2010, 2011 The Amdatu Foundation
+ *
+ * Licensed 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.amdatu.cassandra.test.unit;
+
+import 
org.amdatu.cassandra.persistencemanager.hector.HectorCassandraPersistenceManager;
+import org.amdatu.cassandra.store.useradmin.service.CassandraStorageProvider;
+import org.amdatu.cassandra.store.useradmin.service.RoleColumnFamilyProvider;
+import org.amdatu.cassandra.test.unit.framework.UnitTestFramework;
+import org.amdatu.cassandra.test.unit.framework.hector.HectorUnitTestFramework;
+import org.amdatu.cassandra.test.unit.framework.mock.BundleContextMock;
+import org.amdatu.core.tenant.TenantEntity;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import junit.framework.Assert;
+
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.ops4j.pax.useradmin.service.spi.StorageException;
+import org.osgi.service.useradmin.User;
+
+public class UserAdminStoreTest {
+    private static final String TEST_KEYSPACE = "UnitTestKeyspace";
+    private static final String TEST_USER = "testuser";
+    private static final int THREADS = 5;
+    private static final int PROPERTIES = 25;
+
+    private CassandraStorageProvider m_store;
+    private MockedUserAdminFactory m_factory;
+    private static HectorUnitTestFramework EMBEDDED_FRAMEWORK;
+
+    @BeforeClass
+    public static void setup() throws Exception {
+        // Create the Cassandra unit test frameworks; one which actually 
embeds Cassandra and
+        // one that mocks Cassandra
+        EMBEDDED_FRAMEWORK = new HectorUnitTestFramework(true, TEST_KEYSPACE);
+
+        // Append column families from our definition to the test keyspace
+        RoleColumnFamilyProvider provider = new RoleColumnFamilyProvider();
+        provider.setTenant(new TenantEntity(TEST_KEYSPACE, TEST_KEYSPACE));
+        EMBEDDED_FRAMEWORK.addColumnFamilies(provider);
+    }
+
+    @Test
+    public void testAll() throws Exception {
+        HectorCassandraPersistenceManager pm = 
EMBEDDED_FRAMEWORK.getPersistenceManager();
+        m_store = new CassandraStorageProvider(pm, 
UnitTestFramework.createLogService(), new BundleContextMock());
+        m_factory = new MockedUserAdminFactory();
+
+        testPropertiesAndCredentials();
+        concurrencyTest();
+    }
+
+    private void testPropertiesAndCredentials() throws Exception {
+        User user = m_store.createUser(m_factory, TEST_USER);
+        m_store.setUserCredential(user, "password", "secret");
+        m_store.setRoleAttribute(user, "propkey", "propvalue");
+        
+        // Verify that the values have been set properly; retrieve user by the 
set property
+        User verUser = m_store.getUser(m_factory, "propkey", "propvalue");
+        Assert.assertNotNull(verUser);
+        Assert.assertTrue(verUser.hasCredential("password", "secret"));
+
+        // AMDATUCASSANDRA-190 case 1: invoke clearUserCredentials
+        m_store.clearUserCredentials(user);
+        m_store.getRole(m_factory, TEST_USER);
+
+        // AMDATUCASSANDRA-190 case 2: invoke setRoleAttribute with a value <> 
String or byte[]
+        try {
+            m_store.setRoleAttribute(user, "propkey2", 3);
+        }
+        catch (StorageException e) {
+            // Ignore the error
+        }
+        m_store.getRole(m_factory, TEST_USER);
+
+        // AMDATUCASSANDRA-190 case 3: invoke setUserCredential with a value 
<> String or byte[]
+        try {
+            m_store.setUserCredential(user, "password2", 3);
+        }
+        catch (StorageException e) {
+            // Ignore the error
+        }
+        m_store.getRole(m_factory, TEST_USER);
+    }
+
+    public void concurrencyTest() throws Exception {
+        // Start N threads that concurrent read, add and remove proeprties 
from the same user
+        List<EditPropertiesTestThread> threads = new 
ArrayList<EditPropertiesTestThread>();
+        for (int i = 0; i < THREADS; i++) {
+            EditPropertiesTestThread thread = new EditPropertiesTestThread();
+            threads.add(thread);
+            thread.start();
+        }
+
+        // Wait for the threads to finish
+        for (EditPropertiesTestThread thread : threads) {
+            thread.join();
+            Assert.assertFalse(thread.isFailed());
+        }
+
+        // Test remove all properties
+        User user = (User) m_store.getRole(m_factory, TEST_USER);
+        Assert.assertTrue(!user.getProperties().isEmpty());
+        m_store.clearRoleAttributes(user);
+        user = (User) m_store.getRole(m_factory, TEST_USER);
+        Assert.assertTrue(user.getProperties().isEmpty());
+    }
+
+    class EditPropertiesTestThread extends Thread {
+        private boolean m_failed = false;
+
+        public void run() {
+            try {
+                String threadId = Thread.currentThread().getId() + "_";
+
+                // Test set property
+                for (int i = 0; i < PROPERTIES; i++) {
+                    User user = (User) m_store.getRole(m_factory, TEST_USER);
+                    String propKey = threadId + "property_" + i;
+                    String propValue = threadId + "value_" + i;
+                    m_store.setRoleAttribute(user, propKey, propValue);
+
+                    // Verify that the property has been set
+                    user = (User) m_store.getRole(m_factory, TEST_USER);
+                    Assert.assertEquals(propValue, 
user.getProperties().get(propKey));
+
+                }
+
+                // Test remove single property
+                for (int i = 0; i < PROPERTIES - 1; i++) {
+                    User user = (User) m_store.getRole(m_factory, TEST_USER);
+                    String propKey = threadId + "property_" + i;
+                    Assert.assertNotNull(user.getProperties().get(propKey));
+                    m_store.removeRoleAttribute(user, propKey);
+
+                    // Verify that the property has been set
+                    user = (User) m_store.getRole(m_factory, TEST_USER);
+                    Assert.assertNull(user.getProperties().get(propKey));
+                }
+            }
+            catch (StorageException e) {
+                m_failed = true;
+                System.err.println(e.toString());
+                e.printStackTrace();
+            }
+        }
+
+        public boolean isFailed() {
+            return m_failed;
+        }
+    }
+}

Modified: branches/amdatu-cassandra-0.2.4/test-unit/framework/pom.xml
==============================================================================
--- branches/amdatu-cassandra-0.2.4/test-unit/framework/pom.xml (original)
+++ branches/amdatu-cassandra-0.2.4/test-unit/framework/pom.xml Wed Jun  6 
11:29:05 2012
@@ -41,6 +41,11 @@
       <scope>compile</scope>
     </dependency>
     <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
       <groupId>org.slf4j</groupId>
       <artifactId>slf4j-jdk14</artifactId>
       <version>${slf4j.version}</version>

Added: 
branches/amdatu-cassandra-0.2.4/test-unit/framework/src/main/java/org/amdatu/cassandra/test/unit/framework/mock/BundleContextMock.java
==============================================================================
--- (empty file)
+++ 
branches/amdatu-cassandra-0.2.4/test-unit/framework/src/main/java/org/amdatu/cassandra/test/unit/framework/mock/BundleContextMock.java
      Wed Jun  6 11:29:05 2012
@@ -0,0 +1,207 @@
+/*
+ * Copyright (c) 2010, 2011 The Amdatu Foundation
+ *
+ * Licensed 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.amdatu.cassandra.test.unit.framework.mock;
+
+import java.io.File;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.List;
+
+import org.junit.Assert;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.BundleListener;
+import org.osgi.framework.Filter;
+import org.osgi.framework.FrameworkListener;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceListener;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+
+@SuppressWarnings("rawtypes")
+public class BundleContextMock implements BundleContext {
+    private static String CF_FILTER = "columnfamily";
+    private static String KEYSPACEID_FILTER = "keyspaceid";
+    
+    // Simple in-memory list of service registrations
+    private List<ServiceRegistrationMock> m_serviceRegistry = new 
ArrayList<ServiceRegistrationMock>();
+
+    public ServiceRegistration registerService(final String clazz, final 
Object service, final Dictionary properties) {
+        // Remember the service
+        ServiceRegistrationMock servReg = new ServiceRegistrationMock(clazz, 
service, properties);
+        m_serviceRegistry.add(servReg);
+        return servReg;
+    }
+
+    public ServiceReference[] getAllServiceReferences(final String clazz, 
final String filter)
+        throws InvalidSyntaxException {
+        removeInvalidServiceRegistrations();
+
+        List<ServiceReference> servRefs = new ArrayList<ServiceReference>();
+        for (ServiceRegistrationMock servReg : m_serviceRegistry) {
+            if (servReg.getClassName().equals(clazz)) {
+                if (filter == null) {
+                    servRefs.add(servReg.getReference());
+                }
+                else {
+                    // In our case filter syntax is always "(keyspaceid=...")"
+                    // or (&(keyspaceid=system)(columnfamily=IndexInfo))
+                    Object ksProp =
+                        servReg.getReference().getProperty(KEYSPACEID_FILTER);
+                    if (ksProp != null) {
+                        String keyspace = ksProp.toString();
+                        String expr = "(" + KEYSPACEID_FILTER + "=" + keyspace 
+ ")";
+                        if (filter.equals(expr)) {
+                            servRefs.add(servReg.getReference());
+                        }
+                        Object cfProp = 
servReg.getReference().getProperty(CF_FILTER);
+                        if (cfProp != null) {
+                            expr =
+                                "(&" + expr + "(" + CF_FILTER + "=" + 
cfProp.toString()
+                                    + "))";
+                            if (filter.equals(expr)) {
+                                servRefs.add(servReg.getReference());
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        return servRefs.toArray(new ServiceReference[servRefs.size()]);
+    }
+
+    public ServiceReference getServiceReference(final String clazz) {
+        removeInvalidServiceRegistrations();
+
+        for (ServiceRegistrationMock servRef : m_serviceRegistry) {
+            if (servRef.getClassName().equals(clazz)) {
+                return servRef.getReference();
+            }
+        }
+        return null;
+    }
+
+    public boolean ungetService(final ServiceReference reference) {
+        ServiceRegistrationMock remove = null;
+        for (ServiceRegistrationMock servReg : m_serviceRegistry) {
+            if (reference.equals(servReg.getReference())) {
+                remove = servReg;
+            }
+        }
+        if (remove != null) {
+            m_serviceRegistry.remove(reference);
+        }
+        return false;
+    }
+
+    private void removeInvalidServiceRegistrations() {
+        List<ServiceRegistrationMock> invalidServReg = new 
ArrayList<ServiceRegistrationMock>();
+        for (ServiceRegistrationMock servReg : m_serviceRegistry) {
+            if (!servReg.isValid()) {
+                invalidServReg.add(servReg);
+            }
+        }
+        for (ServiceRegistrationMock servRef : invalidServReg) {
+            m_serviceRegistry.remove(servRef);
+        }
+    }
+
+    public Object getService(final ServiceReference reference) {
+        for (ServiceRegistrationMock servReg : m_serviceRegistry) {
+            if (servReg.getReference().equals(reference)) {
+                return servReg.getObject();
+            }
+        }
+        return null;
+    }
+
+    // Methods with intentional empty implementations
+    public void addServiceListener(final ServiceListener listener, final 
String filter) throws InvalidSyntaxException {
+    }
+
+    public void addServiceListener(final ServiceListener listener) {
+    }
+
+    public void removeServiceListener(final ServiceListener listener) {
+    }
+
+    public void addBundleListener(final BundleListener listener) {
+    }
+
+    public void removeBundleListener(final BundleListener listener) {
+    }
+
+    public void addFrameworkListener(final FrameworkListener listener) {
+    }
+
+    public void removeFrameworkListener(final FrameworkListener listener) {
+    }
+
+    // Not (yet) implemented methods
+    public String getProperty(final String key) {
+        Assert.fail("Method of mock object not implemented");
+        return null;
+    }
+
+    public Bundle getBundle() {
+        Assert.fail("Method of mock object not implemented");
+        return null;
+    }
+
+    public Bundle installBundle(final String location, final InputStream 
input) throws BundleException {
+        Assert.fail("Method of mock object not implemented");
+        return null;
+    }
+
+    public Bundle installBundle(final String location) throws BundleException {
+        Assert.fail("Method of mock object not implemented");
+        return null;
+    }
+
+    public Bundle getBundle(final long id) {
+        Assert.fail("Method of mock object not implemented");
+        return null;
+    }
+
+    public Bundle[] getBundles() {
+        Assert.fail("Method of mock object not implemented");
+        return null;
+    }
+
+    public ServiceRegistration registerService(final String[] clazzes, final 
Object service,
+        final Dictionary properties) {
+        Assert.fail("Method of mock object not implemented");
+        return null;
+    }
+
+    public ServiceReference[] getServiceReferences(final String clazz, final 
String filter)
+        throws InvalidSyntaxException {
+        Assert.fail("Method of mock object not implemented");
+        return null;
+    }
+
+    public File getDataFile(final String filename) {
+        Assert.fail("Method of mock object not implemented");
+        return null;
+    }
+
+    public Filter createFilter(final String filter) throws 
InvalidSyntaxException {
+        return FrameworkUtil.createFilter(filter);
+    }
+}

Added: 
branches/amdatu-cassandra-0.2.4/test-unit/framework/src/main/java/org/amdatu/cassandra/test/unit/framework/mock/FilterMock.java
==============================================================================
--- (empty file)
+++ 
branches/amdatu-cassandra-0.2.4/test-unit/framework/src/main/java/org/amdatu/cassandra/test/unit/framework/mock/FilterMock.java
     Wed Jun  6 11:29:05 2012
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2010, 2011 The Amdatu Foundation
+ * 
+ * Licensed 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.amdatu.cassandra.test.unit.framework.mock;
+
+import java.util.Dictionary;
+
+import org.junit.Assert;
+import org.osgi.framework.ServiceReference;
+
+@SuppressWarnings("rawtypes")
+public class FilterMock {
+    private String m_filterString;
+
+    public FilterMock(String filter) {
+        m_filterString = filter;
+    }
+
+    public boolean match(ServiceReference reference) {
+        Assert.fail("Method of mock object not implemented");
+        return false;
+    }
+
+    public boolean match(Dictionary dictionary) {
+        Assert.fail("Method of mock object not implemented");
+        return false;
+    }
+
+    public boolean matchCase(Dictionary dictionary) {
+        Assert.fail("Method of mock object not implemented");
+        return false;
+    }
+}

Added: 
branches/amdatu-cassandra-0.2.4/test-unit/framework/src/main/java/org/amdatu/cassandra/test/unit/framework/mock/ServiceReferenceMock.java
==============================================================================
--- (empty file)
+++ 
branches/amdatu-cassandra-0.2.4/test-unit/framework/src/main/java/org/amdatu/cassandra/test/unit/framework/mock/ServiceReferenceMock.java
   Wed Jun  6 11:29:05 2012
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2010, 2011 The Amdatu Foundation
+ *
+ * Licensed 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.amdatu.cassandra.test.unit.framework.mock;
+
+import java.util.Dictionary;
+
+import org.junit.Assert;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.ServiceReference;
+
+@SuppressWarnings("rawtypes")
+public class ServiceReferenceMock implements ServiceReference {
+    private Dictionary m_properties;
+
+    public ServiceReferenceMock(final Dictionary properties) {
+        m_properties = properties;
+    }
+
+    public Object getProperty(final String key) {
+        if (m_properties != null) {
+            return m_properties.get(key);
+        }
+        return null;
+    }
+
+    // Not (yet) implemented methods
+    public String[] getPropertyKeys() {
+        Assert.fail("Method of mock object not implemented");
+        return null;
+    }
+
+    public Bundle getBundle() {
+        Assert.fail("Method of mock object not implemented");
+        return null;
+    }
+
+    public Bundle[] getUsingBundles() {
+        Assert.fail("Method of mock object not implemented");
+        return null;
+    }
+
+    public boolean isAssignableTo(final Bundle bundle, final String className) 
{
+        Assert.fail("Method of mock object not implemented");
+        return false;
+    }
+
+    public int compareTo(final Object reference) {
+        Assert.fail("Method of mock object not implemented");
+        return 0;
+    }
+}

Added: 
branches/amdatu-cassandra-0.2.4/test-unit/framework/src/main/java/org/amdatu/cassandra/test/unit/framework/mock/ServiceRegistrationMock.java
==============================================================================
--- (empty file)
+++ 
branches/amdatu-cassandra-0.2.4/test-unit/framework/src/main/java/org/amdatu/cassandra/test/unit/framework/mock/ServiceRegistrationMock.java
        Wed Jun  6 11:29:05 2012
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2010, 2011 The Amdatu Foundation
+ *
+ * Licensed 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.amdatu.cassandra.test.unit.framework.mock;
+
+import java.util.Dictionary;
+
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+
+@SuppressWarnings({ "unused", "rawtypes" })
+public class ServiceRegistrationMock implements ServiceRegistration {
+    private ServiceReference m_serviceReference;
+    private Dictionary m_properties;
+    private String m_className;
+    private Object m_object;
+    private boolean m_valid = true;
+
+    public ServiceRegistrationMock(final String clazz, final Object object, 
final Dictionary properties) {
+        m_serviceReference = new ServiceReferenceMock(properties);
+        m_properties = properties;
+        m_className = clazz;
+        m_object = object;
+    }
+
+    public ServiceReference getReference() {
+        return m_serviceReference;
+    }
+
+    public void setProperties(final Dictionary properties) {
+        m_properties = properties;
+    }
+
+    public String getClassName() {
+        return m_className;
+    }
+
+    public Object getObject() {
+        return m_object;
+    }
+
+    public void unregister() {
+        m_valid = false;
+    }
+
+    public boolean isValid() {
+        return m_valid;
+    }
+}
_______________________________________________
Amdatu-commits mailing list
[email protected]
http://lists.amdatu.org/mailman/listinfo/amdatu-commits

Reply via email to