Author: [email protected]
Date: Wed Feb 16 14:23:56 2011
New Revision: 794
Log:
[AMDATU-311] Fixed concurrency issue by adding reentrant read/write locks on
public API methods
Modified:
trunk/amdatu-cassandra/cassandra-useradminstore/src/main/java/org/amdatu/cassandra/useradminstore/service/CassandraStorageProvider.java
Modified:
trunk/amdatu-cassandra/cassandra-useradminstore/src/main/java/org/amdatu/cassandra/useradminstore/service/CassandraStorageProvider.java
==============================================================================
---
trunk/amdatu-cassandra/cassandra-useradminstore/src/main/java/org/amdatu/cassandra/useradminstore/service/CassandraStorageProvider.java
(original)
+++
trunk/amdatu-cassandra/cassandra-useradminstore/src/main/java/org/amdatu/cassandra/useradminstore/service/CassandraStorageProvider.java
Wed Feb 16 14:23:56 2011
@@ -25,6 +25,9 @@
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
import org.amdatu.cassandra.persistencemanager.CassandraException;
import org.amdatu.cassandra.persistencemanager.CassandraPersistenceManager;
@@ -77,6 +80,9 @@
private volatile LogService m_logService;
private volatile CassandraPersistenceManager m_pm;
+ // Reantrant read/write lock
+ private ReentrantReadWriteLock m_lock = new ReentrantReadWriteLock();
+
public void start() {
m_logService.log(LogService.LOG_INFO, "Cassandra storage provider
service started");
}
@@ -87,19 +93,29 @@
// Creates a new user with the specified name
public User createUser(UserAdminFactory factory, String userName) throws
StorageException {
- // Create the user object using the user admin factory
- User user = factory.createUser(userName, new HashMap<String,
Object>(), new HashMap<String, Object>());
+ WriteLock lock = m_lock.writeLock();
+ try {
+ lock.lock();
+
+ // Create the user object using the user admin factory
+ User user = factory.createUser(userName, new HashMap<String,
Object>(), new HashMap<String, Object>());
- // Now persist the user in Cassandra (throws a StorageException if the
user already exists)
- internalPersistRole(user);
+ // Now persist the user in Cassandra (throws a StorageException if
the user already exists)
+ internalPersistRole(user);
- m_logService.log(LogService.LOG_DEBUG, "User with name '" + userName +
"' created");
- return user;
+ m_logService.log(LogService.LOG_DEBUG, "User with name '" +
userName + "' created");
+ return user;
+ } finally {
+ lock.unlock();
+ }
}
// Returns the user with the specified credentials
public User getUser(UserAdminFactory factory, String key, String value)
throws StorageException {
+ ReadLock lock = m_lock.readLock();
try {
+ lock.lock();
+
// First we try to match by row key (which is the name)
String rowKey = USER_KEY_PREFIX + value;
if (m_pm.exists(CF_ROLE, rowKey)) {
@@ -123,112 +139,206 @@
throw new StorageException(e.getMessage());
} catch (InvalidSyntaxException e) {
throw new StorageException(e.getMessage());
+ } finally {
+ lock.unlock();
}
}
// Update the user credentials in Cassandra
public void setUserCredential(User user, String key, Object value) throws
StorageException {
- internalAddProperty(user, SUPER_COLUMN_CREDENTIALS, key, value);
+ WriteLock lock = m_lock.writeLock();
+ try {
+ lock.lock();
+ internalAddProperty(user, SUPER_COLUMN_CREDENTIALS, key, value);
+ } finally {
+ lock.unlock();
+ }
}
// Removes a single user credential
public void removeUserCredential(User user, String key) throws
StorageException {
- internalRemoveProperty(user, SUPER_COLUMN_CREDENTIALS, key);
+ WriteLock lock = m_lock.writeLock();
+ try {
+ lock.lock();
+ internalRemoveProperty(user, SUPER_COLUMN_CREDENTIALS, key);
+ } finally {
+ lock.unlock();
+ }
}
// Removed the user credentials
public void clearUserCredentials(User user) throws StorageException {
- internalClearProperties(user, SUPER_COLUMN_CREDENTIALS);
+ WriteLock lock = m_lock.writeLock();
+ try {
+ lock.lock();
+ internalClearProperties(user, SUPER_COLUMN_CREDENTIALS);
+ } finally {
+ lock.unlock();
+ }
}
// Creates a new group with the specified name
public Group createGroup(UserAdminFactory factory, String groupName)
throws StorageException {
- // Create the group object using the user admin factory
- Group group = factory.createGroup(groupName, new HashMap<String,
Object>(), new HashMap<String, Object>());
+ WriteLock lock = m_lock.writeLock();
+ try {
+ lock.lock();
+
+ // Create the group object using the user admin factory
+ Group group = factory.createGroup(groupName, new HashMap<String,
Object>(), new HashMap<String, Object>());
- // Now persist the group in Cassandra (throws a StorageException if
the group already exists)
- internalPersistRole(group);
+ // Now persist the group in Cassandra (throws a StorageException
if the group already exists)
+ internalPersistRole(group);
- return group;
+ return group;
+ } finally {
+ lock.unlock();
+ }
}
// Returns the role with the specified name. Role may be a user or group.
public Role getRole(UserAdminFactory userAdminFactory, String roleName)
throws StorageException {
+ ReadLock lock = m_lock.readLock();
try {
- // Try to load the role assuming it is a user
- return internalLoadRole(userAdminFactory, USER_KEY_PREFIX +
roleName, null);
- } catch (StorageException e) {
- // Try to load the role assuming it is a group
+ lock.lock();
+
try {
- return internalLoadRole(userAdminFactory, GROUP_KEY_PREFIX +
roleName, null);
- }
- catch (StorageException e2) {
- return null;
+ // Try to load the role assuming it is a user
+ return internalLoadRole(userAdminFactory, USER_KEY_PREFIX +
roleName, null);
+ } catch (StorageException e) {
+ // Try to load the role assuming it is a group
+ try {
+ return internalLoadRole(userAdminFactory, GROUP_KEY_PREFIX
+ roleName, null);
+ }
+ catch (StorageException e2) {
+ return null;
+ }
}
+ } finally {
+ lock.unlock();
}
}
// Finds all roles that match the specified filter
public Collection<Role> findRoles(UserAdminFactory factory, String
filterString) throws StorageException {
+ ReadLock lock = m_lock.readLock();
try {
- Filter filter = null;
- if (null != filterString) {
- filter = m_context.createFilter(filterString);
+ lock.lock();
+ try {
+ Filter filter = null;
+ if (null != filterString) {
+ filter = m_context.createFilter(filterString);
+ }
+ Collection<Role> roles = internalLoadRoles(factory, filter);
+ return roles;
+ } catch (InvalidSyntaxException e) {
+ throw new StorageException("Invalid filter '" + e.getFilter()
+ "': " + e.getMessage());
}
- Collection<Role> roles = internalLoadRoles(factory, filter);
- return roles;
- } catch (InvalidSyntaxException e) {
- throw new StorageException("Invalid filter '" + e.getFilter() +
"': " + e.getMessage());
+ } finally {
+ lock.unlock();
}
}
// Deletes the specified role
public boolean deleteRole(Role role) throws StorageException {
- internalDeleteRole(role);
- return true;
+ WriteLock lock = m_lock.writeLock();
+ try {
+ lock.lock();
+ internalDeleteRole(role);
+ return true;
+ } finally {
+ lock.unlock();
+ }
}
// Returns all basic members of a certain group
public Collection<Role> getMembers(UserAdminFactory factory, Group group)
throws StorageException {
- return internalLoadMembers(factory, group, COLUMN_BASIC_MEMBERS);
+ ReadLock lock = m_lock.readLock();
+ try {
+ lock.lock();
+ return internalLoadMembers(factory, group, COLUMN_BASIC_MEMBERS);
+ } finally {
+ lock.unlock();
+ }
}
// Returns all required members
public Collection<Role> getRequiredMembers(UserAdminFactory factory, Group
group) throws StorageException {
- return internalLoadMembers(factory, group, COLUMN_REQUIRED_MEMBERS);
+ ReadLock lock = m_lock.readLock();
+ try {
+ lock.lock();
+ return internalLoadMembers(factory, group,
COLUMN_REQUIRED_MEMBERS);
+ } finally {
+ lock.unlock();
+ }
}
// Add a basic member to the group
public boolean addMember(Group group, Role role) throws StorageException {
- return internalAddMember(group, role, COLUMN_BASIC_MEMBERS);
+ WriteLock lock = m_lock.writeLock();
+ try {
+ lock.lock();
+ return internalAddMember(group, role, COLUMN_BASIC_MEMBERS);
+ } finally {
+ lock.unlock();
+ }
}
// Add a required member to the group
public boolean addRequiredMember(Group group, Role role) throws
StorageException {
- return internalAddMember(group, role, COLUMN_REQUIRED_MEMBERS);
+ WriteLock lock = m_lock.writeLock();
+ try {
+ lock.lock();
+ return internalAddMember(group, role, COLUMN_REQUIRED_MEMBERS);
+ } finally {
+ lock.unlock();
+ }
}
// Removes a member, but basic or required??? We remove both
public boolean removeMember(Group group, Role role) throws
StorageException {
- String groupKey = getKey(group);
- String roleKey = getKey(role);
- return internalRemoveMember(groupKey, roleKey, COLUMN_BASIC_MEMBERS)
- || internalRemoveMember(groupKey, roleKey, COLUMN_REQUIRED_MEMBERS);
+ WriteLock lock = m_lock.writeLock();
+ try {
+ lock.lock();
+ String groupKey = getKey(group);
+ String roleKey = getKey(role);
+ return internalRemoveMember(groupKey, roleKey,
COLUMN_BASIC_MEMBERS)
+ || internalRemoveMember(groupKey, roleKey,
COLUMN_REQUIRED_MEMBERS);
+ } finally {
+ lock.unlock();
+ }
}
// Sets the value of a role attribute
public void setRoleAttribute(Role role, String key, Object value) throws
StorageException {
- internalAddProperty(role, SUPER_COLUMN_PROPERTIES, key, value);
+ WriteLock lock = m_lock.writeLock();
+ try {
+ lock.lock();
+ internalAddProperty(role, SUPER_COLUMN_PROPERTIES, key, value);
+ } finally {
+ lock.unlock();
+ }
}
// Removed a single role attribute
public void removeRoleAttribute(Role role, String key) throws
StorageException {
- internalRemoveProperty(role, SUPER_COLUMN_PROPERTIES, key);
+ WriteLock lock = m_lock.writeLock();
+ try {
+ lock.lock();
+ internalRemoveProperty(role, SUPER_COLUMN_PROPERTIES, key);
+ } finally {
+ lock.unlock();
+ }
}
// Removes all role attributes
public void clearRoleAttributes(Role role) throws StorageException {
- internalClearProperties(role, SUPER_COLUMN_PROPERTIES);
+ WriteLock lock = m_lock.writeLock();
+ try {
+ lock.lock();
+ internalClearProperties(role, SUPER_COLUMN_PROPERTIES);
+ } finally {
+ lock.unlock();
+ }
}
// Helper method to generate unique key stored in Role ColumnFamily
_______________________________________________
Amdatu-commits mailing list
[email protected]
http://lists.amdatu.org/mailman/listinfo/amdatu-commits