killbill-memoizeit

jaxrs: remove dependency on Ehcache Instead, use the CacheControllerDispatcher

3/20/2017 7:19:56 PM

Details

jaxrs/pom.xml 4(+0 -4)

diff --git a/jaxrs/pom.xml b/jaxrs/pom.xml
index b76c36c..fd16d11 100644
--- a/jaxrs/pom.xml
+++ b/jaxrs/pom.xml
@@ -76,10 +76,6 @@
             <artifactId>joda-time</artifactId>
         </dependency>
         <dependency>
-            <groupId>net.sf.ehcache</groupId>
-            <artifactId>ehcache</artifactId>
-        </dependency>
-        <dependency>
             <groupId>org.apache.shiro</groupId>
             <artifactId>shiro-core</artifactId>
         </dependency>
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/AdminResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/AdminResource.java
index 27168ba..8cf1ef2 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/AdminResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/AdminResource.java
@@ -67,6 +67,7 @@ import org.killbill.billing.util.api.CustomFieldUserApi;
 import org.killbill.billing.util.api.RecordIdApi;
 import org.killbill.billing.util.api.TagUserApi;
 import org.killbill.billing.util.cache.Cachable.CacheType;
+import org.killbill.billing.util.cache.CacheControllerDispatcher;
 import org.killbill.billing.util.callcontext.CallContext;
 import org.killbill.billing.util.callcontext.TenantContext;
 import org.killbill.billing.util.entity.Pagination;
@@ -82,6 +83,7 @@ import org.killbill.notificationq.api.NotificationQueue;
 import org.killbill.notificationq.api.NotificationQueueService;
 
 import com.fasterxml.jackson.core.JsonGenerator;
+import com.google.common.base.Function;
 import com.google.common.base.Predicate;
 import com.google.common.base.Strings;
 import com.google.common.collect.ImmutableList;
@@ -92,8 +94,6 @@ import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import io.swagger.annotations.ApiResponse;
 import io.swagger.annotations.ApiResponses;
-import net.sf.ehcache.CacheManager;
-import net.sf.ehcache.Ehcache;
 
 import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
 
@@ -107,7 +107,7 @@ public class AdminResource extends JaxRsResourceBase {
     private final AdminPaymentApi adminPaymentApi;
     private final InvoiceUserApi invoiceUserApi;
     private final TenantUserApi tenantApi;
-    private final CacheManager cacheManager;
+    private final CacheControllerDispatcher cacheControllerDispatcher;
     private final RecordIdApi recordIdApi;
     private final PersistentBus persistentBus;
     private final NotificationQueueService notificationQueueService;
@@ -121,7 +121,7 @@ public class AdminResource extends JaxRsResourceBase {
                          final PaymentApi paymentApi,
                          final AdminPaymentApi adminPaymentApi,
                          final InvoiceUserApi invoiceUserApi,
-                         final CacheManager cacheManager,
+                         final CacheControllerDispatcher cacheControllerDispatcher,
                          final TenantUserApi tenantApi,
                          final RecordIdApi recordIdApi,
                          final PersistentBus persistentBus,
@@ -133,7 +133,7 @@ public class AdminResource extends JaxRsResourceBase {
         this.invoiceUserApi = invoiceUserApi;
         this.tenantApi = tenantApi;
         this.recordIdApi = recordIdApi;
-        this.cacheManager = cacheManager;
+        this.cacheControllerDispatcher = cacheControllerDispatcher;
         this.persistentBus = persistentBus;
         this.notificationQueueService = notificationQueueService;
     }
@@ -322,17 +322,17 @@ public class AdminResource extends JaxRsResourceBase {
     public Response invalidatesCache(@QueryParam("cacheName") final String cacheName,
                                      @javax.ws.rs.core.Context final HttpServletRequest request) {
         if (null != cacheName && !cacheName.isEmpty()) {
-            final Ehcache cache = cacheManager.getEhcache(cacheName);
-            // check if cache is null
-            if (cache == null) {
+            // Clear given cache
+            final CacheType cacheType = CacheType.findByName(cacheName);
+            if (cacheType != null) {
+                cacheControllerDispatcher.getCacheController(cacheType).removeAll();
+            } else {
                 log.warn("Cache for specified cacheName='{}' does not exist or is not alive", cacheName);
                 return Response.status(Status.BAD_REQUEST).build();
             }
-            // Clear given cache
-            cache.removeAll();
         } else {
             // if not given a specific cacheName, clear all
-            cacheManager.clearAll();
+            cacheControllerDispatcher.clearAll();
         }
         return Response.status(Status.OK).build();
     }
@@ -342,20 +342,18 @@ public class AdminResource extends JaxRsResourceBase {
     @Produces(APPLICATION_JSON)
     @ApiOperation(value = "Invalidates Caches per account level")
     @ApiResponses(value = {})
-    public Response invalidatesCacheByAccount(@PathParam("accountId") final String accountId,
+    public Response invalidatesCacheByAccount(@PathParam("accountId") final String accountIdStr,
                                               @javax.ws.rs.core.Context final HttpServletRequest request) {
+        final UUID accountId = UUID.fromString(accountIdStr);
 
-        // clear account-record-id cache by accountId
-        final Ehcache accountRecordIdCache = cacheManager.getEhcache(CacheType.ACCOUNT_RECORD_ID.getCacheName());
-        accountRecordIdCache.remove(accountId);
+        // clear account-record-id cache by accountId (note: String!)
+        cacheControllerDispatcher.getCacheController(CacheType.ACCOUNT_RECORD_ID).remove(accountIdStr);
 
         // clear account-immutable cache by accountId
-        final Ehcache accountImmutableCache = cacheManager.getEhcache(CacheType.ACCOUNT_IMMUTABLE.getCacheName());
-        accountImmutableCache.remove(UUID.fromString(accountId));
+        cacheControllerDispatcher.getCacheController(CacheType.ACCOUNT_IMMUTABLE).remove(accountId);
 
         // clear account-bcd cache by accountId
-        final Ehcache accountBcdCache = cacheManager.getEhcache(CacheType.ACCOUNT_BCD.getCacheName());
-        accountBcdCache.remove(UUID.fromString(accountId));
+        cacheControllerDispatcher.getCacheController(CacheType.ACCOUNT_BCD).remove(accountId);
 
         return Response.status(Status.OK).build();
     }
@@ -369,52 +367,44 @@ public class AdminResource extends JaxRsResourceBase {
                                              @javax.ws.rs.core.Context final HttpServletRequest request) throws TenantApiException {
 
         // creating Tenant Context from Request
-        TenantContext tenantContext = context.createContext(request);
+        final TenantContext tenantContext = context.createContext(request);
 
-        Tenant currentTenant = tenantApi.getTenantById(tenantContext.getTenantId());
+        final Tenant currentTenant = tenantApi.getTenantById(tenantContext.getTenantId());
 
         // getting Tenant Record Id
-        Long tenantRecordId = recordIdApi.getRecordId(tenantContext.getTenantId(), ObjectType.TENANT, tenantContext);
+        final Long tenantRecordId = recordIdApi.getRecordId(tenantContext.getTenantId(), ObjectType.TENANT, tenantContext);
+
+        final Function<Object, Boolean> tenantKeysMatcher = new Function<Object, Boolean>() {
+            @Override
+            public Boolean apply(@Nullable final Object key) {
+                return key != null && key.toString().endsWith("::" + tenantRecordId);
+            }
+        };
 
         // clear tenant-record-id cache by tenantId
-        final Ehcache tenantRecordIdCache = cacheManager.getEhcache(CacheType.TENANT_RECORD_ID.getCacheName());
-        tenantRecordIdCache.remove(currentTenant.getId().toString());
+        cacheControllerDispatcher.getCacheController(CacheType.TENANT_RECORD_ID).remove(currentTenant.getId().toString());
 
         // clear tenant-payment-state-machine-config cache by tenantRecordId
-        final Ehcache tenantPaymentStateMachineConfigCache = cacheManager.getEhcache(CacheType.TENANT_PAYMENT_STATE_MACHINE_CONFIG.getCacheName());
-        removeCacheByKey(tenantPaymentStateMachineConfigCache, tenantRecordId.toString());
+        cacheControllerDispatcher.getCacheController(CacheType.TENANT_PAYMENT_STATE_MACHINE_CONFIG).remove(tenantKeysMatcher);
 
         // clear tenant cache by tenantApiKey
-        final Ehcache tenantCache = cacheManager.getEhcache(CacheType.TENANT.getCacheName());
-        tenantCache.remove(currentTenant.getApiKey());
+        cacheControllerDispatcher.getCacheController(CacheType.TENANT).remove(currentTenant.getApiKey());
 
         // clear tenant-kv cache by tenantRecordId
-        final Ehcache tenantKvCache = cacheManager.getEhcache(CacheType.TENANT_KV.getCacheName());
-        removeCacheByKey(tenantKvCache, tenantRecordId.toString());
+        cacheControllerDispatcher.getCacheController(CacheType.TENANT_KV).remove(tenantKeysMatcher);
 
         // clear tenant-config cache by tenantRecordId
-        final Ehcache tenantConfigCache = cacheManager.getEhcache(CacheType.TENANT_CONFIG.getCacheName());
-        tenantConfigCache.remove(tenantRecordId);
+        cacheControllerDispatcher.getCacheController(CacheType.TENANT_CONFIG).remove(tenantRecordId);
 
         // clear tenant-overdue-config cache by tenantRecordId
-        final Ehcache tenantOverdueConfigCache = cacheManager.getEhcache(CacheType.TENANT_OVERDUE_CONFIG.getCacheName());
-        tenantOverdueConfigCache.remove(tenantRecordId);
+        cacheControllerDispatcher.getCacheController(CacheType.TENANT_OVERDUE_CONFIG).remove(tenantRecordId);
 
         // clear tenant-catalog cache by tenantRecordId
-        final Ehcache tenantCatalogCache = cacheManager.getEhcache(CacheType.TENANT_CATALOG.getCacheName());
-        tenantCatalogCache.remove(tenantRecordId);
+        cacheControllerDispatcher.getCacheController(CacheType.TENANT_CATALOG).remove(tenantRecordId);
 
         return Response.status(Status.OK).build();
     }
 
-    private void removeCacheByKey(final Ehcache tenantCache, final String tenantRecordId) {
-        for (Object key : tenantCache.getKeys()) {
-            if (null != key && key.toString().endsWith("::" + tenantRecordId)) {
-                tenantCache.remove(key);
-            }
-        }
-    }
-
     private Iterable<NotificationEventWithMetadata<NotificationEvent>> getNotifications(@Nullable final String queueName,
                                                                                         @Nullable final String serviceName,
                                                                                         final boolean includeInProcessing,
diff --git a/util/src/main/java/org/killbill/billing/util/cache/CacheController.java b/util/src/main/java/org/killbill/billing/util/cache/CacheController.java
index b2a9673..137c301 100644
--- a/util/src/main/java/org/killbill/billing/util/cache/CacheController.java
+++ b/util/src/main/java/org/killbill/billing/util/cache/CacheController.java
@@ -18,12 +18,16 @@ package org.killbill.billing.util.cache;
 
 import org.killbill.billing.util.cache.Cachable.CacheType;
 
+import com.google.common.base.Function;
+
 public interface CacheController<K, V> {
 
     V get(K key, CacheLoaderArgument objectType);
 
     boolean remove(K key);
 
+    void remove(Function<K, Boolean> keyMatcher);
+
     void putIfAbsent(final K key, V value);
 
     int size();
diff --git a/util/src/main/java/org/killbill/billing/util/cache/EhCacheBasedCacheController.java b/util/src/main/java/org/killbill/billing/util/cache/EhCacheBasedCacheController.java
index 298de85..62d12c6 100644
--- a/util/src/main/java/org/killbill/billing/util/cache/EhCacheBasedCacheController.java
+++ b/util/src/main/java/org/killbill/billing/util/cache/EhCacheBasedCacheController.java
@@ -18,10 +18,14 @@
 
 package org.killbill.billing.util.cache;
 
+import java.util.Collection;
+import java.util.HashSet;
+
 import org.killbill.billing.util.cache.Cachable.CacheType;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.google.common.base.Function;
 import net.sf.ehcache.CacheException;
 import net.sf.ehcache.Ehcache;
 import net.sf.ehcache.Element;
@@ -77,6 +81,17 @@ public class EhCacheBasedCacheController<K, V> implements CacheController<K, V> 
     }
 
     @Override
+    public void remove(final Function<K, Boolean> keyMatcher) {
+        final Collection<K> toRemove = new HashSet<K>();
+        for (final Object key : cache.getKeys()) {
+            if (keyMatcher.apply((K) key) == Boolean.TRUE) {
+                toRemove.add((K) key);
+            }
+        }
+        cache.removeAll(toRemove);
+    }
+
+    @Override
     public void removeAll() {
         cache.removeAll();
     }