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

Reply via email to