Author: [email protected]
Date: Wed Aug 17 11:26:50 2011
New Revision: 1333
Log:
AMDATU-314 Applying provided patch to resolve concurrency issues
Modified:
trunk/amdatu-core/tenant/src/main/java/org/amdatu/core/tenant/service/TenantManagementCache.java
Modified:
trunk/amdatu-core/tenant/src/main/java/org/amdatu/core/tenant/service/TenantManagementCache.java
==============================================================================
---
trunk/amdatu-core/tenant/src/main/java/org/amdatu/core/tenant/service/TenantManagementCache.java
(original)
+++
trunk/amdatu-core/tenant/src/main/java/org/amdatu/core/tenant/service/TenantManagementCache.java
Wed Aug 17 11:26:50 2011
@@ -13,173 +13,174 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.amdatu.core.tenant.service;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.ReentrantReadWriteLock;
-
-import org.amdatu.core.tenant.TenantEntity;
-import org.amdatu.core.tenant.TenantException;
-import org.amdatu.core.tenant.TenantManagementService;
-import org.osgi.service.log.LogService;
-
-/**
- * This class implements a cache for the Tenant management service,
implemented as an aspect of the
- * original Tenant management service. Note that tenants in Amdatu are
actually read-only; they are
- * "provisioned" from configuration management.
- *
- * @author ivol
- */
-public class TenantManagementCache implements TenantManagementService {
- // Service dependencies injected by the dependency manager
- private volatile TenantManagementService m_tenantService;
- private volatile LogService m_logService;
-
- // The tenant cache
- private List<TenantEntity> m_tenantCache = null;
-
- // We currently use all-exclusive access.
- private ReentrantReadWriteLock m_lock = new ReentrantReadWriteLock();
-
- public void start() throws TenantException {
- // read the tenants upon startup
- loadCache();
-
- m_logService.log(LogService.LOG_INFO, "Tenant management cache
started");
- }
-
- public TenantEntity createTenant(String id, String name) throws
TenantException {
- Lock writelock = m_lock.writeLock();
- writelock.lock();
- try {
- // First clear the cache. This is necessary since while invoking
createTenant
- // on the tenant management service, getTenantById will be invoked
immediately
- // after the tenant has been created but before the method returns.
- clearCache();
-
- TenantEntity tenant = m_tenantService.createTenant(id, name);
- return tenant;
- } finally {
- writelock.unlock();
- }
- }
-
- public TenantEntity createTenant(String id, String name, Map<String,
String> properties) throws TenantException {
- Lock writelock = m_lock.writeLock();
- writelock.lock();
- try {
- // First clear the cache. This is necessary since while invoking
createTenant
- // on the tenant management service, getTenantById will be invoked
immediately
- // after the tenant has been created but before the method returns.
- clearCache();
-
- TenantEntity tenant = m_tenantService.createTenant(id, name,
properties);
- return tenant;
- } finally {
- writelock.unlock();
- }
- }
-
- public void updateTenant(TenantEntity tenant) throws TenantException {
- Lock writelock = m_lock.writeLock();
- writelock.lock();
- try {
- // First clear the cache. This is necessary since while invoking
createTenant
- // on the tenant management service, getTenantById will be invoked
immediately
- // after the tenant has been created but before the method returns.
- clearCache();
-
- m_tenantService.updateTenant(tenant);
- } finally {
- writelock.unlock();
- }
- }
-
- public void deleteTenant(TenantEntity tenant) throws TenantException {
- Lock writelock = m_lock.writeLock();
- writelock.lock();
- try {
- // First clear the cache. This is necessary since while invoking
createTenant
- // on the tenant management service, getTenantById will be invoked
immediately
- // after the tenant has been created but before the method returns.
- clearCache();
-
- m_tenantService.deleteTenant(tenant);
- } finally {
- writelock.unlock();
- }
- }
-
- public TenantEntity getTenantById(String id) throws TenantException {
- if (m_tenantCache == null) {
- loadCache();
- }
-
- Lock readlock = m_lock.readLock();
- readlock.lock();
- try {
- for (TenantEntity tenant : m_tenantCache) {
- if (tenant.getId().equals(id)) {
- return tenant;
- }
- }
- } finally {
- readlock.unlock();
- }
- return null;
- }
-
- public List<TenantEntity> getTenants() throws TenantException {
- if (m_tenantCache == null) {
- loadCache();
- }
-
- List<TenantEntity> result = new ArrayList<TenantEntity>();
- Lock readlock = m_lock.readLock();
- readlock.lock();
- try {
- result.addAll(m_tenantCache);
- } finally {
- readlock.unlock();
- }
- return result;
- }
-
- public List<TenantEntity> getTenants(Map<String, String> properties)
throws TenantException {
- if (m_tenantCache == null) {
- loadCache();
- }
-
- Lock readlock = m_lock.readLock();
- readlock.lock();
- try {
- List<TenantEntity> matchingTenants = new ArrayList<TenantEntity>();
- for (TenantEntity tenant : m_tenantCache) {
- if (tenant.matches(properties)) {
- matchingTenants.add(tenant);
- }
- }
- return matchingTenants;
- } finally {
- readlock.unlock();
- }
- }
-
- private void loadCache() throws TenantException {
- Lock writelock = m_lock.writeLock();
- writelock.lock();
- try {
- m_tenantCache = new ArrayList<TenantEntity>();
- m_tenantCache.addAll(m_tenantService.getTenants());
- } finally {
- writelock.unlock();
- }
- }
-
- private void clearCache() {
- m_tenantCache = null;
- }
-}
+package org.amdatu.core.tenant.service;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+
+import org.amdatu.core.tenant.TenantEntity;
+import org.amdatu.core.tenant.TenantException;
+import org.amdatu.core.tenant.TenantManagementService;
+import org.osgi.service.log.LogService;
+
+/**
+ * This class implements a cache for the Tenant management service,
implemented as an aspect of the
+ * original Tenant management service. Note that tenants in Amdatu are
actually read-only; they are
+ * "provisioned" from configuration management.
+ *
+ * @author ivol
+ */
+public class TenantManagementCache implements TenantManagementService {
+ // Service dependencies injected by the dependency manager
+ private volatile TenantManagementService m_tenantService;
+ private volatile LogService m_logService;
+
+ // The tenant cache
+ private List<TenantEntity> m_tenantCache = null;
+
+ private ReentrantReadWriteLock m_lock = new ReentrantReadWriteLock();
+
+ public void start() throws TenantException {
+ m_logService.log(LogService.LOG_INFO, "Tenant management cache
started");
+ }
+
+ public TenantEntity createTenant(String id, String name) throws
TenantException {
+ TenantEntity tenant = m_tenantService.createTenant(id, name);
+ addToCache(tenant);
+ return tenant;
+ }
+
+ public TenantEntity createTenant(String id, String name, Map<String,
String> properties) throws TenantException {
+ TenantEntity tenant = m_tenantService.createTenant(id, name,
properties);
+ addToCache(tenant);
+ return tenant;
+ }
+
+ public void updateTenant(TenantEntity tenant) throws TenantException {
+ m_tenantService.updateTenant(tenant);
+ updateCache(tenant);
+ }
+
+ public void deleteTenant(TenantEntity tenant) throws TenantException {
+ m_tenantService.deleteTenant(tenant);
+ deleteFromCache(tenant);
+ }
+
+ public TenantEntity getTenantById(String id) throws TenantException {
+ // First try to load from the tenant from the cache
+ if (m_tenantCache != null) {
+ TenantEntity tenant = getFromCache(id);
+ if (tenant != null) {
+ return tenant;
+ }
+ }
+
+ // If the tenant was not contained by the cache, try returning the
tenant directly from the
+ // tenant management service
+ return m_tenantService.getTenantById(id);
+ }
+
+ public List<TenantEntity> getTenants() throws TenantException {
+ if (m_tenantCache == null) {
+ reloadCache();
+ }
+
+ List<TenantEntity> result = new ArrayList<TenantEntity>();
+ Lock readlock = m_lock.readLock();
+ readlock.lock();
+ try {
+ result.addAll(m_tenantCache);
+ }
+ finally {
+ readlock.unlock();
+ }
+ return result;
+ }
+
+ public List<TenantEntity> getTenants(Map<String, String> properties)
throws TenantException {
+ if (m_tenantCache == null) {
+ reloadCache();
+ }
+
+ Lock readlock = m_lock.readLock();
+ readlock.lock();
+ try {
+ List<TenantEntity> matchingTenants = new ArrayList<TenantEntity>();
+ for (TenantEntity tenant : m_tenantCache) {
+ if (tenant.matches(properties)) {
+ matchingTenants.add(tenant);
+ }
+ }
+ return matchingTenants;
+ }
+ finally {
+ readlock.unlock();
+ }
+ }
+
+ private TenantEntity getFromCache(String id) {
+ Lock readlock = m_lock.readLock();
+ readlock.lock();
+ try {
+ for (TenantEntity tenant : m_tenantCache) {
+ if (tenant.getId().equals(id)) {
+ return tenant;
+ }
+ }
+ }
+ finally {
+ readlock.unlock();
+ }
+ return null;
+ }
+
+ private void addToCache(TenantEntity tenant) {
+ Lock writelock = m_lock.writeLock();
+ writelock.lock();
+ try {
+ m_tenantCache.add(tenant);
+ }
+ finally {
+ writelock.unlock();
+ }
+ }
+
+ private void updateCache(TenantEntity tenant) {
+ Lock writelock = m_lock.writeLock();
+ writelock.lock();
+ try {
+ // Equals is by getId()
+ m_tenantCache.remove(tenant);
+ m_tenantCache.add(tenant);
+ }
+ finally {
+ writelock.unlock();
+ }
+ }
+
+ private void deleteFromCache(TenantEntity tenant) {
+ Lock writelock = m_lock.writeLock();
+ writelock.lock();
+ try {
+ m_tenantCache.remove(tenant);
+ }
+ finally {
+ writelock.unlock();
+ }
+ }
+
+ private void reloadCache() throws TenantException {
+ Lock writelock = m_lock.writeLock();
+ writelock.lock();
+ try {
+ m_tenantCache = new ArrayList<TenantEntity>();
+ m_tenantCache.addAll(m_tenantService.getTenants());
+ }
+ finally {
+ writelock.unlock();
+ }
+ }
+}
_______________________________________________
Amdatu-commits mailing list
[email protected]
http://lists.amdatu.org/mailman/listinfo/amdatu-commits