killbill-uncached
Changes
jaxrs/pom.xml 4(+4 -0)
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();
}
}