killbill-aplcache

jaxrs, catalog: add new query param when creating tenant to

8/8/2016 5:19:39 PM

Details

diff --git a/catalog/src/main/java/org/killbill/billing/catalog/api/user/DefaultCatalogUserApi.java b/catalog/src/main/java/org/killbill/billing/catalog/api/user/DefaultCatalogUserApi.java
index 3bafe9c..55b244c 100644
--- a/catalog/src/main/java/org/killbill/billing/catalog/api/user/DefaultCatalogUserApi.java
+++ b/catalog/src/main/java/org/killbill/billing/catalog/api/user/DefaultCatalogUserApi.java
@@ -98,6 +98,24 @@ public class DefaultCatalogUserApi implements CatalogUserApi {
         }
     }
 
+
+    @Override
+    public void createDefaultEmptyCatalog(final DateTime effectiveDate, final CallContext callContext) throws CatalogApiException {
+
+        try {
+            final InternalTenantContext internalTenantContext = internalCallContextFactory.createInternalTenantContextWithoutAccountRecordId(callContext);
+            final StandaloneCatalog currentCatalog = getCurrentStandaloneCatalogForTenant(internalTenantContext);
+            final CatalogUpdater catalogUpdater = (currentCatalog != null) ?
+                                                  new CatalogUpdater(currentCatalog) :
+                                                  new CatalogUpdater("dummy", BillingMode.IN_ADVANCE, effectiveDate, null);
+
+            catalogCache.clearCatalog(internalTenantContext);
+            tenantApi.updateTenantKeyValue(TenantKey.CATALOG.toString(), catalogUpdater.getCatalogXML(), callContext);
+        } catch (TenantApiException e) {
+            throw new CatalogApiException(e);
+        }
+    }
+
     @Override
     public void addSimplePlan(final SimplePlanDescriptor descriptor, final DateTime effectiveDate, final CallContext callContext) throws CatalogApiException {
 
diff --git a/catalog/src/main/java/org/killbill/billing/catalog/CatalogUpdater.java b/catalog/src/main/java/org/killbill/billing/catalog/CatalogUpdater.java
index 8afdfa1..1c3f024 100644
--- a/catalog/src/main/java/org/killbill/billing/catalog/CatalogUpdater.java
+++ b/catalog/src/main/java/org/killbill/billing/catalog/CatalogUpdater.java
@@ -51,6 +51,7 @@ import com.google.common.collect.Iterables;
 public class CatalogUpdater {
 
     private static URI DUMMY_URI;
+
     static {
         try {
             DUMMY_URI = new URI("dummy");
@@ -58,8 +59,6 @@ public class CatalogUpdater {
         }
     };
 
-    private static final DefaultPriceList DEFAULT_PRICELIST = new DefaultPriceList().setName(PriceListSet.DEFAULT_PRICELIST_NAME);
-
     private final DefaultMutableStaticCatalog catalog;
 
     public CatalogUpdater(final StandaloneCatalog standaloneCatalog) {
@@ -67,15 +66,19 @@ public class CatalogUpdater {
     }
 
     public CatalogUpdater(final String catalogName, final BillingMode billingMode, final DateTime effectiveDate, final Currency... currencies) {
+
+        final DefaultPriceList defaultPriceList = new DefaultPriceList().setName(PriceListSet.DEFAULT_PRICELIST_NAME);
         final StandaloneCatalog tmp = new StandaloneCatalog()
                 .setCatalogName(catalogName)
                 .setEffectiveDate(effectiveDate.toDate())
-                .setSupportedCurrencies(currencies)
                 .setRecurringBillingMode(billingMode)
                 .setProducts(new DefaultProduct[0])
                 .setPlans(new DefaultPlan[0])
-                .setPriceLists(new DefaultPriceListSet(DEFAULT_PRICELIST, new DefaultPriceList[0]))
-                .setPlanRules(getSaneDefaultPlanRules());
+                .setPriceLists(new DefaultPriceListSet(defaultPriceList, new DefaultPriceList[0]))
+                .setPlanRules(getSaneDefaultPlanRules(defaultPriceList));
+        if (currencies != null && currencies.length > 0) {
+            tmp.setSupportedCurrencies(currencies);
+        }
         tmp.initialize(tmp, DUMMY_URI);
 
         this.catalog = new DefaultMutableStaticCatalog(tmp);
@@ -93,6 +96,7 @@ public class CatalogUpdater {
         }
     }
 
+
     public void addSimplePlanDescriptor(final SimplePlanDescriptor desc) throws CatalogApiException {
 
         // We need at least a planId
@@ -120,7 +124,7 @@ public class CatalogUpdater {
 
             plan = new DefaultPlan();
             plan.setName(desc.getPlanId());
-            plan.setPriceListName(DEFAULT_PRICELIST.getName());
+            plan.setPriceListName(PriceListSet.DEFAULT_PRICELIST_NAME);
             plan.setProduct(product);
 
             if (desc.getTrialLength() > 0 && desc.getTrialTimeUnit() != TimeUnit.UNLIMITED) {
@@ -142,11 +146,10 @@ public class CatalogUpdater {
             catalog.addCurrency(desc.getCurrency());
             // Reset the fixed price to null so the isZero() logic goes through new currencies and set the zero price for all
             if (plan.getInitialPhases().length == 1) {
-                ((DefaultInternationalPrice)plan.getInitialPhases()[0].getFixed().getPrice()).setPrices(null);
+                ((DefaultInternationalPrice) plan.getInitialPhases()[0].getFixed().getPrice()).setPrices(null);
             }
         }
 
-
         DefaultPlanPhase evergreenPhase = plan.getFinalPhase();
         if (evergreenPhase == null) {
             evergreenPhase = new DefaultPlanPhase();
@@ -200,7 +203,7 @@ public class CatalogUpdater {
             if ((isDescConfiguredWithTrial && !isPlanConfiguredWithTrial) ||
                 (!isDescConfiguredWithTrial && isPlanConfiguredWithTrial)) {
                 failedValidation = true;
-            // Both have trials , check they match
+                // Both have trials , check they match
             } else if (isDescConfiguredWithTrial && isPlanConfiguredWithTrial) {
                 if (plan.getInitialPhases()[0].getDuration().getUnit() != desc.getTrialTimeUnit() ||
                     plan.getInitialPhases()[0].getDuration().getNumber() != desc.getTrialLength()) {
@@ -227,19 +230,17 @@ public class CatalogUpdater {
                         if (currentAmount.compareTo(desc.getAmount()) != 0) {
                             failedValidation = true;
                         }
-                    } catch (CatalogApiException ignoreIfCurrencyIsCurrentlyUndefined) {}
+                    } catch (CatalogApiException ignoreIfCurrencyIsCurrentlyUndefined) {
+                    }
                 }
             }
         }
 
-
         if (failedValidation) {
             throw new CatalogApiException(ErrorCode.CAT_FAILED_SIMPLE_PLAN_VALIDATION, plan.toString(), desc.toString());
         }
     }
 
-
-
     private boolean isCurrencySupported(final Currency targetCurrency) {
         return Iterables.any(ImmutableList.copyOf(catalog.getCurrentSupportedCurrencies()), new Predicate<Currency>() {
             @Override
@@ -287,7 +288,7 @@ public class CatalogUpdater {
         }).orNull();
     }
 
-    private DefaultPlanRules getSaneDefaultPlanRules() {
+    private DefaultPlanRules getSaneDefaultPlanRules(final DefaultPriceList defaultPriceList) {
 
         final DefaultCaseChangePlanPolicy[] changePolicy = new DefaultCaseChangePlanPolicy[1];
         changePolicy[0] = new DefaultCaseChangePlanPolicy();
@@ -311,7 +312,7 @@ public class CatalogUpdater {
 
         final DefaultCasePriceList[] priceList = new DefaultCasePriceList[1];
         priceList[0] = new DefaultCasePriceList();
-        priceList[0].setToPriceList(DEFAULT_PRICELIST);
+        priceList[0].setToPriceList(defaultPriceList);
 
         return new DefaultPlanRules()
                 .setChangeCase(changePolicy)
diff --git a/catalog/src/main/java/org/killbill/billing/catalog/DefaultPriceList.java b/catalog/src/main/java/org/killbill/billing/catalog/DefaultPriceList.java
index 7d7903d..f912ecd 100644
--- a/catalog/src/main/java/org/killbill/billing/catalog/DefaultPriceList.java
+++ b/catalog/src/main/java/org/killbill/billing/catalog/DefaultPriceList.java
@@ -40,9 +40,9 @@ public class DefaultPriceList extends ValidatingConfig<StandaloneCatalog> implem
     @XmlID
     private String name;
 
-    @XmlElementWrapper(name = "plans", required = true)
+    @XmlElementWrapper(name = "plans", required = false)
     @XmlIDREF
-    @XmlElement(name = "plan", required = true)
+    @XmlElement(name = "plan", required = false)
     private DefaultPlan[] plans;
 
     public DefaultPriceList() {
@@ -82,13 +82,15 @@ public class DefaultPriceList extends ValidatingConfig<StandaloneCatalog> implem
 
     @Override
     public ValidationErrors validate(final StandaloneCatalog catalog, final ValidationErrors errors) {
-        for (final DefaultPlan cur : getPlans()) {
-            final int numPlans = findNumberOfPlans(cur.getProduct(), cur.getRecurringBillingPeriod());
-            if (numPlans > 1) {
-                errors.add(new ValidationError(
-                        String.format("There are %d plans in pricelist %s and have the same product/billingPeriod (%s, %s)",
-                                      numPlans, getName(), cur.getProduct().getName(), cur.getRecurringBillingPeriod()), catalog.getCatalogURI(),
-                        DefaultPriceListSet.class, getName()));
+        if (getPlans() != null) {
+            for (final DefaultPlan cur : getPlans()) {
+                final int numPlans = findNumberOfPlans(cur.getProduct(), cur.getRecurringBillingPeriod());
+                if (numPlans > 1) {
+                    errors.add(new ValidationError(
+                            String.format("There are %d plans in pricelist %s and have the same product/billingPeriod (%s, %s)",
+                                          numPlans, getName(), cur.getProduct().getName(), cur.getRecurringBillingPeriod()), catalog.getCatalogURI(),
+                            DefaultPriceListSet.class, getName()));
+                }
             }
         }
         return errors;
diff --git a/catalog/src/main/java/org/killbill/billing/catalog/StandaloneCatalog.java b/catalog/src/main/java/org/killbill/billing/catalog/StandaloneCatalog.java
index 9d2fb75..fe0c663 100644
--- a/catalog/src/main/java/org/killbill/billing/catalog/StandaloneCatalog.java
+++ b/catalog/src/main/java/org/killbill/billing/catalog/StandaloneCatalog.java
@@ -66,23 +66,23 @@ public class StandaloneCatalog extends ValidatingConfig<StandaloneCatalog> imple
     @XmlElement(required = true)
     private BillingMode recurringBillingMode;
 
-    @XmlElementWrapper(name = "currencies", required = true)
-    @XmlElement(name = "currency", required = true)
+    @XmlElementWrapper(name = "currencies", required = false)
+    @XmlElement(name = "currency", required = false)
     private Currency[] supportedCurrencies;
 
     @XmlElementWrapper(name = "units", required = false)
     @XmlElement(name = "unit", required = false)
     private DefaultUnit[] units;
 
-    @XmlElementWrapper(name = "products", required = true)
-    @XmlElement(name = "product", required = true)
+    @XmlElementWrapper(name = "products", required = false)
+    @XmlElement(name = "product", required = false)
     private DefaultProduct[] products;
 
     @XmlElement(name = "rules", required = true)
     private DefaultPlanRules planRules;
 
-    @XmlElementWrapper(name = "plans", required = true)
-    @XmlElement(name = "plan", required = true)
+    @XmlElementWrapper(name = "plans", required = false)
+    @XmlElement(name = "plan", required = false)
     private DefaultPlan[] plans;
 
     @XmlElement(name = "priceLists", required = true)
diff --git a/catalog/src/test/java/org/killbill/billing/catalog/TestCatalogUpdater.java b/catalog/src/test/java/org/killbill/billing/catalog/TestCatalogUpdater.java
index 3bc6a66..c101cd0 100644
--- a/catalog/src/test/java/org/killbill/billing/catalog/TestCatalogUpdater.java
+++ b/catalog/src/test/java/org/killbill/billing/catalog/TestCatalogUpdater.java
@@ -20,6 +20,7 @@ package org.killbill.billing.catalog;
 import java.io.ByteArrayInputStream;
 import java.math.BigDecimal;
 import java.net.URI;
+import java.net.URISyntaxException;
 import java.nio.charset.Charset;
 
 import org.joda.time.DateTime;
@@ -51,6 +52,18 @@ import static org.testng.Assert.fail;
 public class TestCatalogUpdater extends CatalogTestSuiteNoDB {
 
     @Test(groups = "fast")
+    public void testEmptyDefaultCatalog() throws Exception {
+
+        final DateTime now = clock.getUTCNow();
+
+        final CatalogUpdater catalogUpdater = new CatalogUpdater("dummy", BillingMode.IN_ADVANCE, now, null);
+        final String catalogXML = catalogUpdater.getCatalogXML();
+        final StandaloneCatalog catalog = XMLLoader.getObjectFromStream(new URI("dummy"), new ByteArrayInputStream(catalogXML.getBytes(Charset.forName("UTF-8"))), StandaloneCatalog.class);
+        assertEquals(catalog.getCurrentPlans().length, 0);
+    }
+
+
+        @Test(groups = "fast")
     public void testAddNoTrialPlanOnFirstCatalog() throws CatalogApiException {
 
         final DateTime now = clock.getUTCNow();
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/JaxrsResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/JaxrsResource.java
index 0c833c8..bfe6b8f 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/JaxrsResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/JaxrsResource.java
@@ -105,6 +105,8 @@ public interface JaxrsResource {
     public static final String QUERY_PAYMENT_METHOD_ID = "paymentMethodId";
     public static final String QUERY_PAYMENT_CONTROL_PLUGIN_NAME = "controlPluginName";
 
+    public static final String QUERY_TENANT_USE_GLOBAL_DEFAULT = "useGlobalDefault";
+
 
     public static final String QUERY_TAGS = "tagList";
     public static final String QUERY_CUSTOM_FIELDS = "customFieldList";
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/TenantResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/TenantResource.java
index fb17eaf..baeb070 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/TenantResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/TenantResource.java
@@ -23,6 +23,7 @@ import javax.annotation.Nullable;
 import javax.servlet.http.HttpServletRequest;
 import javax.ws.rs.Consumes;
 import javax.ws.rs.DELETE;
+import javax.ws.rs.DefaultValue;
 import javax.ws.rs.GET;
 import javax.ws.rs.HeaderParam;
 import javax.ws.rs.POST;
@@ -36,6 +37,8 @@ import javax.ws.rs.core.UriInfo;
 
 import org.killbill.billing.ObjectType;
 import org.killbill.billing.account.api.AccountUserApi;
+import org.killbill.billing.catalog.api.CatalogApiException;
+import org.killbill.billing.catalog.api.CatalogUserApi;
 import org.killbill.billing.jaxrs.json.TenantJson;
 import org.killbill.billing.jaxrs.json.TenantKeyJson;
 import org.killbill.billing.jaxrs.util.Context;
@@ -70,6 +73,7 @@ import static javax.ws.rs.core.MediaType.TEXT_PLAIN;
 public class TenantResource extends JaxRsResourceBase {
 
     private final TenantUserApi tenantApi;
+    private final CatalogUserApi catalogUserApi;
 
     @Inject
     public TenantResource(final TenantUserApi tenantApi,
@@ -79,10 +83,12 @@ public class TenantResource extends JaxRsResourceBase {
                           final AuditUserApi auditUserApi,
                           final AccountUserApi accountUserApi,
                           final PaymentApi paymentApi,
+                          final CatalogUserApi catalogUserApi,
                           final Clock clock,
                           final Context context) {
         super(uriBuilder, tagUserApi, customFieldUserApi, auditUserApi, accountUserApi, paymentApi, null, clock, context);
         this.tenantApi = tenantApi;
+        this.catalogUserApi = catalogUserApi;
     }
 
     @TimedResource
@@ -114,17 +120,22 @@ public class TenantResource extends JaxRsResourceBase {
     @ApiOperation(value = "Create a tenant")
     @ApiResponses(value = {@ApiResponse(code = 500, message = "Tenant already exists")})
     public Response createTenant(final TenantJson json,
+                                 @QueryParam(QUERY_TENANT_USE_GLOBAL_DEFAULT) @DefaultValue("true") final Boolean useGlobalDefault,
                                  @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                  @HeaderParam(HDR_REASON) final String reason,
                                  @HeaderParam(HDR_COMMENT) final String comment,
                                  @javax.ws.rs.core.Context final HttpServletRequest request,
-                                 @javax.ws.rs.core.Context final UriInfo uriInfo) throws TenantApiException {
+                                 @javax.ws.rs.core.Context final UriInfo uriInfo) throws TenantApiException, CatalogApiException {
         verifyNonNullOrEmpty(json, "TenantJson body should be specified");
         verifyNonNullOrEmpty(json.getApiKey(), "TenantJson apiKey needs to be set",
                              json.getApiSecret(), "TenantJson apiSecret needs to be set");
 
         final TenantData data = json.toTenantData();
         final Tenant tenant = tenantApi.createTenant(data, context.createContext(createdBy, reason, comment, request));
+        if (!useGlobalDefault) {
+            final CallContext callContext = context.createContext(createdBy, reason, comment, request);
+            catalogUserApi.createDefaultEmptyCatalog(clock.getUTCNow(),callContext);
+        }
         return uriBuilder.buildResponse(uriInfo, TenantResource.class, "getTenant", tenant.getId());
     }
 
diff --git a/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestCatalog.java b/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestCatalog.java
index ffb96bd..8949aba 100644
--- a/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestCatalog.java
+++ b/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestCatalog.java
@@ -23,6 +23,7 @@ import java.sql.Date;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
+import java.util.UUID;
 
 import org.joda.time.DateTime;
 import org.killbill.billing.catalog.api.BillingPeriod;
@@ -30,12 +31,14 @@ import org.killbill.billing.catalog.api.Currency;
 import org.killbill.billing.catalog.api.ProductCategory;
 import org.killbill.billing.catalog.api.TimeUnit;
 import org.killbill.billing.client.KillBillClientException;
+import org.killbill.billing.client.RequestOptions;
 import org.killbill.billing.client.model.Catalog;
 import org.killbill.billing.client.model.Catalogs;
 import org.killbill.billing.client.model.Plan;
 import org.killbill.billing.client.model.PlanDetail;
 import org.killbill.billing.client.model.Product;
 import org.killbill.billing.client.model.SimplePlan;
+import org.killbill.billing.client.model.Tenant;
 import org.killbill.billing.client.model.Usage;
 import org.testng.Assert;
 import org.testng.annotations.Test;
@@ -45,7 +48,9 @@ import com.google.common.io.Resources;
 
 public class TestCatalog extends TestJaxrsBase {
 
-    @Test(groups = "slow", description = "Upload and retrieve a per tenant catalog")
+
+
+        @Test(groups = "slow", description = "Upload and retrieve a per tenant catalog")
     public void testMultiTenantCatalog() throws Exception {
         final String catalogPath = Resources.getResource("SpyCarBasic.xml").getPath();
         killBillClient.uploadXMLCatalog(catalogPath, createdBy, reason, comment);
@@ -141,4 +146,41 @@ public class TestCatalog extends TestJaxrsBase {
         Assert.assertEquals(catalogsJson.get(0).getPriceLists().get(0).getPlans().size(), 2);
 
     }
+
+    @Test(groups = "slow", description = "Upload and retrieve a per plugin payment state machine config")
+    public void testAddSimplePlanWithoutKBDefault() throws Exception {
+        // Create another tenant initialized with no default catalog,...
+        final Tenant otherTenantNoKBDefault = new Tenant();
+        otherTenantNoKBDefault.setApiKey(UUID.randomUUID().toString());
+        otherTenantNoKBDefault.setApiSecret(UUID.randomUUID().toString());
+
+        killBillClient.createTenant(otherTenantNoKBDefault, false, requestOptions);
+
+        final RequestOptions requestOptionsOtherTenant = requestOptions.extend()
+                                                                       .withTenantApiKey(otherTenantNoKBDefault.getApiKey())
+                                                                       .withTenantApiSecret(otherTenantNoKBDefault.getApiSecret())
+                                                                       .build();
+
+        killBillClient.addSimplePan(new SimplePlan("foo-monthly", "Foo", ProductCategory.BASE, Currency.USD, BigDecimal.TEN, BillingPeriod.MONTHLY, 0, TimeUnit.UNLIMITED, ImmutableList.<String>of()), requestOptionsOtherTenant);
+        List<Catalog> catalogsJson = killBillClient.getJSONCatalog(requestOptionsOtherTenant);
+        Assert.assertEquals(catalogsJson.size(),1);
+        Assert.assertEquals(catalogsJson.get(0).getProducts().size(),1);
+        Assert.assertEquals(catalogsJson.get(0).getProducts().get(0).getName(),"Foo");
+        Assert.assertEquals(catalogsJson.get(0).getPriceLists().size(),1);
+        Assert.assertEquals(catalogsJson.get(0).getPriceLists().get(0).getName(), "DEFAULT");
+        Assert.assertEquals(catalogsJson.get(0).getPriceLists().get(0).getPlans().size(), 1);
+        Assert.assertEquals(catalogsJson.get(0).getPriceLists().get(0).getPlans().get(0), "foo-monthly");
+
+
+        killBillClient.addSimplePan(new SimplePlan("foo-annual", "Foo", ProductCategory.BASE, Currency.USD, new BigDecimal("100.00"), BillingPeriod.ANNUAL, 0, TimeUnit.UNLIMITED, ImmutableList.<String>of()), requestOptionsOtherTenant);
+
+        catalogsJson = killBillClient.getJSONCatalog(requestOptionsOtherTenant);
+        Assert.assertEquals(catalogsJson.size(),1);
+        Assert.assertEquals(catalogsJson.get(0).getProducts().size(),1);
+        Assert.assertEquals(catalogsJson.get(0).getProducts().get(0).getName(),"Foo");
+        Assert.assertEquals(catalogsJson.get(0).getPriceLists().size(),1);
+        Assert.assertEquals(catalogsJson.get(0).getPriceLists().get(0).getName(), "DEFAULT");
+        Assert.assertEquals(catalogsJson.get(0).getPriceLists().get(0).getPlans().size(), 2);
+    }
+
 }
diff --git a/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestTenantKV.java b/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestTenantKV.java
index f2539d8..5232201 100644
--- a/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestTenantKV.java
+++ b/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestTenantKV.java
@@ -72,7 +72,7 @@ public class TestTenantKV extends TestJaxrsBase {
         final Tenant otherTenantWithDifferentStateMachine = new Tenant();
         otherTenantWithDifferentStateMachine.setApiKey(UUID.randomUUID().toString());
         otherTenantWithDifferentStateMachine.setApiSecret(UUID.randomUUID().toString());
-        killBillClient.createTenant(otherTenantWithDifferentStateMachine, requestOptions);
+        killBillClient.createTenant(otherTenantWithDifferentStateMachine, true, requestOptions);
         final RequestOptions requestOptionsOtherTenant = requestOptions.extend()
                                                                        .withTenantApiKey(otherTenantWithDifferentStateMachine.getApiKey())
                                                                        .withTenantApiSecret(otherTenantWithDifferentStateMachine.getApiSecret())