killbill-uncached

#304 - Changing POST endpoints with DELETE - Updated how the

8/18/2016 1:48:23 PM

Details

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

diff --git a/jaxrs/pom.xml b/jaxrs/pom.xml
index 20befb1..d477452 100644
--- a/jaxrs/pom.xml
+++ b/jaxrs/pom.xml
@@ -76,6 +76,10 @@
             <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 fc21dcf..5b9fd42 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
@@ -17,11 +17,13 @@
 
 package org.killbill.billing.jaxrs.resources;
 
+import java.util.List;
 import java.util.UUID;
 
 import javax.inject.Inject;
 import javax.servlet.http.HttpServletRequest;
 import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
 import javax.ws.rs.HeaderParam;
 import javax.ws.rs.POST;
 import javax.ws.rs.PUT;
@@ -121,7 +123,7 @@ public class AdminResource extends JaxRsResourceBase {
         return Response.status(Status.OK).build();
     }
 
-    @POST
+    @DELETE
     @Path("/" + CACHE)
     @Produces(APPLICATION_JSON)
     @ApiOperation(value = "Invalidates the given Cache if specified, otherwise invalidates all caches")
@@ -145,7 +147,7 @@ public class AdminResource extends JaxRsResourceBase {
         return Response.status(Status.OK).build();
     }
 
-    @POST
+    @DELETE
     @Path("/" + CACHE + "/" + ACCOUNTS + "/{accountId:" + UUID_PATTERN + "}/")
     @Produces(APPLICATION_JSON)
     @ApiOperation(value = "Invalidates Caches per account level")
@@ -168,7 +170,7 @@ public class AdminResource extends JaxRsResourceBase {
         return Response.status(Status.OK).build();
     }
 
-    @POST
+    @DELETE
     @Path("/" + CACHE + "/" + TENANTS)
     @Produces(APPLICATION_JSON)
     @ApiOperation(value = "Invalidates Caches per tenant level")
@@ -190,8 +192,7 @@ public class AdminResource extends JaxRsResourceBase {
 
         // clear tenant-payment-state-machine-config cache by tenantRecordId
         final Ehcache tenantPaymentStateMachineConfigCache = cacheManager.getEhcache(CacheType.TENANT_PAYMENT_STATE_MACHINE_CONFIG.getCacheName());
-        String tenantPaymentStateMachineConfigCacheKey = "PLUGIN_PAYMENT_STATE_MACHINE_noop::" + tenantRecordId.toString();
-        tenantPaymentStateMachineConfigCache.remove(tenantPaymentStateMachineConfigCacheKey);
+        removeCacheByKey(tenantPaymentStateMachineConfigCache, tenantRecordId.toString());
 
         // clear tenant cache by tenantApiKey
         final Ehcache tenantCache = cacheManager.getEhcache(CacheType.TENANT.getCacheName());
@@ -199,8 +200,7 @@ public class AdminResource extends JaxRsResourceBase {
 
         // clear tenant-kv cache by tenantRecordId
         final Ehcache tenantKvCache = cacheManager.getEhcache(CacheType.TENANT_KV.getCacheName());
-        String tenantKvCacheKey = "PUSH_NOTIFICATION_CB::" + tenantRecordId.toString();
-        tenantKvCache.remove(tenantKvCacheKey);
+        removeCacheByKey(tenantKvCache, tenantRecordId.toString());
 
         // clear tenant-config cache by tenantRecordId
         final Ehcache tenantConfigCache = cacheManager.getEhcache(CacheType.TENANT_CONFIG.getCacheName());
@@ -216,4 +216,13 @@ public class AdminResource extends JaxRsResourceBase {
 
         return Response.status(Status.OK).build();
     }
+
+    private void removeCacheByKey(final Ehcache tenantCache, final String tenantRecordId) {
+        for (String key : (List<String>) tenantCache.getKeys()) {
+            if (key.endsWith("::" + tenantRecordId)) {
+                tenantCache.remove(key);
+            }
+        }
+    }
+
 }
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/TestResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/TestResource.java
index 66f4d51..9e1f704 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/TestResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/TestResource.java
@@ -68,8 +68,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;
 
diff --git a/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestCache.java b/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestCache.java
index 6bf8368..f62d16a 100644
--- a/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestCache.java
+++ b/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestCache.java
@@ -16,14 +16,29 @@
 
 package org.killbill.billing.jaxrs;
 
+import java.util.List;
+import java.util.UUID;
+
+import org.killbill.billing.catalog.api.BillingPeriod;
+import org.killbill.billing.catalog.api.PriceListSet;
+import org.killbill.billing.catalog.api.ProductCategory;
+import org.killbill.billing.client.RequestOptions;
 import org.killbill.billing.client.model.Account;
-import org.killbill.billing.tenant.api.DefaultTenant;
+import org.killbill.billing.client.model.PaymentMethod;
+import org.killbill.billing.client.model.PaymentMethodPluginDetail;
+import org.killbill.billing.client.model.Subscription;
+import org.killbill.billing.client.model.Tenant;
 import org.killbill.billing.util.cache.Cachable.CacheType;
 import org.testng.Assert;
 import org.testng.annotations.Test;
 
+import com.google.common.io.Resources;
 import net.sf.ehcache.Ehcache;
 
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertTrue;
+
 public class TestCache extends TestJaxrsBase {
 
     @Test(groups = "slow", description = "Can Invalidate (clear) a Cache by name")
@@ -31,7 +46,7 @@ public class TestCache extends TestJaxrsBase {
         // get Ehcache item with name "record-id"
         final Ehcache cache = cacheManager.getEhcache(CacheType.RECORD_ID.getCacheName());
         // verify that it is not null and has one stored key (the default tenant created for all integration tests)
-        Assert.assertNotNull(cache);
+        assertNotNull(cache);
         Assert.assertEquals(cache.getSize(), 1);
 
         // invalidate the specified cache
@@ -46,7 +61,7 @@ public class TestCache extends TestJaxrsBase {
         // get Ehcache item with name "record-id"
         final Ehcache cache = cacheManager.getEhcache(CacheType.RECORD_ID.getCacheName());
         // verify that it is not null and has one stored key (the default tenant created for all integration tests)
-        Assert.assertNotNull(cache);
+        assertNotNull(cache);
         Assert.assertEquals(cache.getSize(), 1);
 
         // invalidate all caches
@@ -66,12 +81,12 @@ public class TestCache extends TestJaxrsBase {
         final Ehcache accountBcdCache = cacheManager.getEhcache(CacheType.ACCOUNT_BCD.getCacheName());
 
         // verify that they are not null and have the accountId stored as a key (the account created before)
-        Assert.assertNotNull(accountRecordIdCache);
-        Assert.assertNotNull(accountRecordIdCache.get(input.getAccountId().toString()));
-        Assert.assertNotNull(accountImmutableCache);
-        Assert.assertNotNull(accountImmutableCache.get(input.getAccountId()));
-        Assert.assertNotNull(accountBcdCache);
-        Assert.assertNotNull(accountBcdCache.get(input.getAccountId()));
+        assertNotNull(accountRecordIdCache);
+        assertNotNull(accountRecordIdCache.get(input.getAccountId().toString()));
+        assertNotNull(accountImmutableCache);
+        assertNotNull(accountImmutableCache.get(input.getAccountId()));
+        assertNotNull(accountBcdCache);
+        assertNotNull(accountBcdCache.get(input.getAccountId()));
 
         // invalidate caches per account level by accountId
         killBillClient.invalidateCacheByAccount(input.getAccountId().toString(), requestOptions);
@@ -84,8 +99,29 @@ public class TestCache extends TestJaxrsBase {
 
     @Test(groups = "slow", description = "Can Invalidate (clear) all Tenant Caches for current Tenant")
     public void testInvalidateCacheByTenant() throws Exception {
-
-        createAccountWithPMBundleAndSubscriptionAndWaitForFirstInvoice();
+        // creating a new Tenant for this test
+        final String testApiKey = "testApiKey";
+        final String testApiSecret = "testApiSecret";
+        final Tenant tenant = new Tenant();
+        tenant.setApiKey(testApiKey);
+        tenant.setApiSecret(testApiSecret);
+        loginTenant(testApiKey, testApiSecret);
+        Tenant currentTenant = killBillClient.createTenant(tenant, false, requestOptions);
+
+        // using custom RequestOptions with the new Tenant created before
+        RequestOptions inputOptions = RequestOptions.builder()
+                                                    .withCreatedBy(createdBy)
+                                                    .withReason(reason)
+                                                    .withComment(comment)
+                                                    .withTenantApiKey(currentTenant.getApiKey())
+                                                    .withTenantApiSecret(currentTenant.getApiSecret())
+                                                    .build();
+
+        // Uploading the test catalog using the new Tenant created before
+        killBillClient.uploadXMLCatalog(Resources.getResource("catalogTest.xml").getPath(), inputOptions);
+
+        // creating an Account with PaymentMethod and a Subscription
+        createAccountWithPMBundleAndSubscriptionAndWaitForFirstInvoiceWithInputOptions(inputOptions);
 
         // get all caches per tenant level
         final Ehcache tenantRecordIdCache = cacheManager.getEhcache(CacheType.TENANT_RECORD_ID.getCacheName());
@@ -96,36 +132,67 @@ public class TestCache extends TestJaxrsBase {
         final Ehcache tenantOverdueConfigCache = cacheManager.getEhcache(CacheType.TENANT_OVERDUE_CONFIG.getCacheName());
         final Ehcache tenantCatalogCache = cacheManager.getEhcache(CacheType.TENANT_CATALOG.getCacheName());
 
-        DefaultTenant currentTenant = (DefaultTenant) tenantCache.get(tenantCache.getKeys().get(0)).getObjectValue();
+        // getting current Tenant's record Id from the specific Cache
+        Long tenantRecordId = (Long) tenantRecordIdCache.get(currentTenant.getTenantId().toString()).getObjectValue();
 
         // verify that they are not null and have the expected tenant information
-        Assert.assertNotNull(tenantRecordIdCache);
-        Assert.assertNotNull(tenantRecordIdCache.get(currentTenant.getId().toString()));
-        Assert.assertNotNull(tenantPaymentStateMachineConfigCache);
-        String tenantPaymentStateMachineConfigCacheKey = "PLUGIN_PAYMENT_STATE_MACHINE_noop::1";
-        Assert.assertNotNull(tenantPaymentStateMachineConfigCache.get(tenantPaymentStateMachineConfigCacheKey));
-        Assert.assertNotNull(tenantCache);
-        Assert.assertNotNull(tenantCache.get(DEFAULT_API_KEY));
-        Assert.assertNotNull(tenantKvCache);
-        String tenantKvCacheKey = "PUSH_NOTIFICATION_CB::1";
-        Assert.assertNotNull(tenantKvCache.get(tenantKvCacheKey));
-        Assert.assertNotNull(tenantConfigCache);
-        Assert.assertNotNull(tenantConfigCache.get(1L));
-        Assert.assertNotNull(tenantOverdueConfigCache);
-        Assert.assertNotNull(tenantOverdueConfigCache.get(1L));
-        Assert.assertNotNull(tenantCatalogCache);
-        Assert.assertNotNull(tenantCatalogCache.get(1L));
-
-        // invalidate caches per tenant level by tenantId
-        killBillClient.invalidateCacheByTenant(requestOptions);
+        assertNotNull(tenantRecordIdCache);
+        assertNotNull(tenantRecordIdCache.get(currentTenant.getTenantId().toString()));
+        assertNotNull(tenantPaymentStateMachineConfigCache);
+        assertTrue(hasKeysByTenantRecordId(tenantPaymentStateMachineConfigCache, tenantRecordId.toString()));
+        assertNotNull(tenantCache);
+        assertNotNull(tenantCache.get(testApiKey));
+        assertNotNull(tenantKvCache);
+        assertTrue(hasKeysByTenantRecordId(tenantKvCache, tenantRecordId.toString()));
+        assertNotNull(tenantConfigCache);
+        assertNotNull(tenantConfigCache.get(tenantRecordId));
+        assertNotNull(tenantOverdueConfigCache);
+        assertNotNull(tenantOverdueConfigCache.get(tenantRecordId));
+        assertNotNull(tenantCatalogCache);
+        assertNotNull(tenantCatalogCache.get(tenantRecordId));
+
+        // invalidate caches per tenant level
+        killBillClient.invalidateCacheByTenant(inputOptions);
 
         // verify that now the caches don't have the previous values
-        Assert.assertNull(tenantRecordIdCache.get(currentTenant.getId().toString()));
-        Assert.assertNull(tenantPaymentStateMachineConfigCache.get(tenantPaymentStateMachineConfigCacheKey));
-        Assert.assertNull(tenantCache.get(DEFAULT_API_KEY));
-        Assert.assertNull(tenantKvCache.get(tenantKvCacheKey));
-        Assert.assertNull(tenantConfigCache.get(1L));
-        Assert.assertNull(tenantOverdueConfigCache.get(1L));
-        Assert.assertNull(tenantCatalogCache.get(1L));
+        Assert.assertNull(tenantRecordIdCache.get(currentTenant.getTenantId().toString()));
+        assertFalse(hasKeysByTenantRecordId(tenantPaymentStateMachineConfigCache, tenantRecordId.toString()));
+        Assert.assertNull(tenantCache.get(testApiKey));
+        assertFalse(hasKeysByTenantRecordId(tenantKvCache, tenantRecordId.toString()));
+        Assert.assertNull(tenantConfigCache.get(tenantRecordId));
+        Assert.assertNull(tenantOverdueConfigCache.get(tenantRecordId));
+        Assert.assertNull(tenantCatalogCache.get(tenantRecordId));
+    }
+
+    private boolean hasKeysByTenantRecordId(final Ehcache tenantCache, final String tenantRecordId) {
+        for (String key : (List<String>) tenantCache.getKeys()) {
+            if (key.endsWith("::" + tenantRecordId)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private void createAccountWithPMBundleAndSubscriptionAndWaitForFirstInvoiceWithInputOptions(final RequestOptions inputOptions) throws Exception {
+        Account account = killBillClient.createAccount(getAccount(), inputOptions);
+
+        final PaymentMethodPluginDetail info = new PaymentMethodPluginDetail();
+        info.setProperties(null);
+        final PaymentMethod paymentMethodJson = new PaymentMethod(null, UUID.randomUUID().toString(), account.getAccountId(), true, PLUGIN_NAME, info);
+        killBillClient.createPaymentMethod(paymentMethodJson, inputOptions);
+
+        final Subscription subscription = new Subscription();
+        subscription.setAccountId(account.getAccountId());
+        subscription.setExternalKey(UUID.randomUUID().toString());
+        subscription.setProductName("Shotgun");
+        subscription.setProductCategory(ProductCategory.BASE);
+        subscription.setBillingPeriod(BillingPeriod.MONTHLY);
+        subscription.setPriceList(PriceListSet.DEFAULT_PRICELIST_NAME);
+
+        final Subscription subscriptionJson = killBillClient.createSubscription(subscription, clock.getUTCToday(), DEFAULT_WAIT_COMPLETION_TIMEOUT_SEC, inputOptions);
+
+        assertNotNull(subscriptionJson);
+        clock.addDays(32);
+        crappyWaitForLackOfProperSynchonization();
     }
 }