From 34a98cbbba1309514a76229bc3f9eb8f0c483411 Mon Sep 17 00:00:00 2001 From: Jonathan Cobb Date: Thu, 30 Jan 2020 16:23:59 -0500 Subject: [PATCH] add support for apps-per-plan --- .../src/main/java/bubble/ApiConstants.java | 1 + .../bubble/dao/bill/BubblePlanAppDAO.java | 17 ++- .../java/bubble/model/bill/BubblePlan.java | 4 +- .../java/bubble/model/bill/BubblePlanApp.java | 4 +- .../resources/bill/AccountPlansResource.java | 20 ++++ .../bill/BubblePlanAppsResource.java | 23 ++++ .../resources/bill/BubblePlansResource.java | 6 +- .../service/cloud/AnsiblePrepService.java | 2 +- .../test/java/bubble/test/PaymentTest.java | 2 + .../test/resources/models/manifest-test.json | 4 +- .../resources/models/system/bubblePlan.json | 49 +++++---- .../models/system/bubblePlan_withApps.json | 37 +++++++ .../models/tests/payment/plan_apps.json | 104 ++++++++++++++++++ 13 files changed, 239 insertions(+), 34 deletions(-) create mode 100644 bubble-server/src/test/resources/models/system/bubblePlan_withApps.json create mode 100644 bubble-server/src/test/resources/models/tests/payment/plan_apps.json diff --git a/bubble-server/src/main/java/bubble/ApiConstants.java b/bubble-server/src/main/java/bubble/ApiConstants.java index 3f512cf4..00d473e2 100644 --- a/bubble-server/src/main/java/bubble/ApiConstants.java +++ b/bubble-server/src/main/java/bubble/ApiConstants.java @@ -141,6 +141,7 @@ public class ApiConstants { public static final String EP_MODEL = "/model"; public static final String EP_VPN = "/vpn"; public static final String EP_IPS = "/ips"; + public static final String EP_PLAN = "/plan"; public static final String EP_PAYMENT_METHOD = "/paymentMethod"; public static final String EP_PAYMENT_METHODS = PAYMENT_METHODS_ENDPOINT; public static final String EP_PAYMENT = "/payment"; diff --git a/bubble-server/src/main/java/bubble/dao/bill/BubblePlanAppDAO.java b/bubble-server/src/main/java/bubble/dao/bill/BubblePlanAppDAO.java index 42eb4d72..5e29cca7 100644 --- a/bubble-server/src/main/java/bubble/dao/bill/BubblePlanAppDAO.java +++ b/bubble-server/src/main/java/bubble/dao/bill/BubblePlanAppDAO.java @@ -1,7 +1,10 @@ package bubble.dao.bill; import bubble.dao.account.AccountOwnedEntityDAO; +import bubble.dao.app.BubbleAppDAO; +import bubble.model.app.BubbleApp; import bubble.model.bill.BubblePlanApp; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Repository; import java.util.List; @@ -9,8 +12,18 @@ import java.util.List; @Repository public class BubblePlanAppDAO extends AccountOwnedEntityDAO { - public List findByAccountAndPlan(String account, String bubblePlan) { - return findByFields("account", account, "plan", bubblePlan); + @Autowired private BubbleAppDAO appDAO; + + public List findByPlan(String bubblePlan) { + return findByField("plan", bubblePlan); + } + + public BubblePlanApp findByAccountAndPlanAndId(String account, String bubblePlan, String id) { + final BubblePlanApp planApp = findByUniqueFields("plan", bubblePlan, "app", id); + if (planApp != null) return planApp; + + final BubbleApp app = appDAO.findByAccountAndId(account, id); + return app == null ? null : findByUniqueFields("plan", bubblePlan, "app", app.getUuid()); } } diff --git a/bubble-server/src/main/java/bubble/model/bill/BubblePlan.java b/bubble-server/src/main/java/bubble/model/bill/BubblePlan.java index f71bfa25..62602bfc 100644 --- a/bubble-server/src/main/java/bubble/model/bill/BubblePlan.java +++ b/bubble-server/src/main/java/bubble/model/bill/BubblePlan.java @@ -9,8 +9,8 @@ import lombok.NoArgsConstructor; import lombok.Setter; import lombok.experimental.Accessors; import org.cobbzilla.util.collection.HasPriority; -import org.cobbzilla.wizard.model.IdentifiableBase; import org.cobbzilla.wizard.model.entityconfig.EntityFieldType; +import org.cobbzilla.wizard.model.entityconfig.IdentifiableBaseParentEntity; import org.cobbzilla.wizard.model.entityconfig.annotations.*; import org.cobbzilla.wizard.validation.HasValue; import org.joda.time.format.DateTimeFormat; @@ -35,7 +35,7 @@ import static org.cobbzilla.util.reflect.ReflectionUtil.copy; }) @Entity @NoArgsConstructor @Accessors(chain=true) @ECIndexes({ @ECIndex(unique=true, of={"account", "name"}) }) -public class BubblePlan extends IdentifiableBase implements HasAccount, HasPriority { +public class BubblePlan extends IdentifiableBaseParentEntity implements HasAccount, HasPriority { public static final int MAX_CHARGENAME_LEN = 12; diff --git a/bubble-server/src/main/java/bubble/model/bill/BubblePlanApp.java b/bubble-server/src/main/java/bubble/model/bill/BubblePlanApp.java index 4ad32470..f32a3a73 100644 --- a/bubble-server/src/main/java/bubble/model/bill/BubblePlanApp.java +++ b/bubble-server/src/main/java/bubble/model/bill/BubblePlanApp.java @@ -20,7 +20,9 @@ import static org.cobbzilla.util.reflect.ReflectionUtil.copy; @ECType(root=true) @ECTypeURIs(baseURI=EP_APPS, listFields={"plan", "app"}) @Entity @NoArgsConstructor @Accessors(chain=true) -@ECIndexes({ @ECIndex(unique=true, of={"account", "plan", "app"}) }) +@ECIndexes({ + @ECIndex(unique=true, of={"plan", "app"}) +}) public class BubblePlanApp extends IdentifiableBase implements HasAccountNoName { public static final String[] CREATE_FIELDS = {"plan", "app"}; diff --git a/bubble-server/src/main/java/bubble/resources/bill/AccountPlansResource.java b/bubble-server/src/main/java/bubble/resources/bill/AccountPlansResource.java index d0c1f28b..58b1ebba 100644 --- a/bubble-server/src/main/java/bubble/resources/bill/AccountPlansResource.java +++ b/bubble-server/src/main/java/bubble/resources/bill/AccountPlansResource.java @@ -256,4 +256,24 @@ public class AccountPlansResource extends AccountOwnedResource list(ContainerRequest ctx) { + return getDao().findByPlan(plan.getUuid()); + } + + @Override protected BubblePlanApp find(ContainerRequest ctx, String id) { + return getDao().findByAccountAndPlanAndId(account.getUuid(), plan.getUuid(), id); + } + + @Override protected boolean canCreate(Request req, ContainerRequest ctx, Account caller, BubblePlanApp request) { + return caller.admin(); + } + + @Override protected boolean canUpdate(ContainerRequest ctx, Account caller, BubblePlanApp found, BubblePlanApp request) { + return false; + } + + @Override protected boolean canDelete(ContainerRequest ctx, Account caller, BubblePlanApp found) { + return caller.admin(); + } + @Override protected BubblePlanApp setReferences(ContainerRequest ctx, Account caller, BubblePlanApp request) { final BubbleApp app = appDAO.findByAccountAndId(getAccountUuid(ctx), request.getApp()); if (app == null) throw notFoundEx(request.getApp()); diff --git a/bubble-server/src/main/java/bubble/resources/bill/BubblePlansResource.java b/bubble-server/src/main/java/bubble/resources/bill/BubblePlansResource.java index 7f3d6b47..c0a56d7c 100644 --- a/bubble-server/src/main/java/bubble/resources/bill/BubblePlansResource.java +++ b/bubble-server/src/main/java/bubble/resources/bill/BubblePlansResource.java @@ -16,8 +16,7 @@ import static bubble.ApiConstants.EP_APPS; import static bubble.ApiConstants.PLANS_ENDPOINT; import static bubble.model.bill.BubblePlan.MAX_CHARGENAME_LEN; import static org.cobbzilla.util.daemon.ZillaRuntime.empty; -import static org.cobbzilla.wizard.resources.ResourceUtil.invalidEx; -import static org.cobbzilla.wizard.resources.ResourceUtil.notFoundEx; +import static org.cobbzilla.wizard.resources.ResourceUtil.*; @Path(PLANS_ENDPOINT) @Service @Slf4j @@ -36,7 +35,8 @@ public class BubblePlansResource extends AccountOwnedResource= 1"}] + } + }, + + { + "comment": "add basic plan, using 'free' payment method", + "request": { + "uri": "me/plans", + "method": "put", + "entity": { + "name": "test-net-{{rand 5}}", + "domain": "{{defaultDomain}}", + "locale": "en_US", + "timezone": "EST", + "plan": "{{plans.[0].name}}", + "footprint": "US", + "paymentMethodObject": { + "paymentMethodType": "free", + "paymentInfo": "free" + } + } + }, + "response": { + "store": "accountPlan" + } + }, + + { + "comment": "get plan apps, should be 1", + "request": { "uri": "me/plans/{{accountPlan.uuid}}/apps" }, + "response": { + "check": [{"condition": "json.length == 1"}] + } + }, + + { + "comment": "add plus plan, using 'free' payment method", + "request": { + "uri": "me/plans", + "method": "put", + "entity": { + "name": "test-net-{{rand 5}}", + "domain": "{{defaultDomain}}", + "locale": "en_US", + "timezone": "EST", + "plan": "{{plans.[1].name}}", + "footprint": "US", + "paymentMethodObject": { + "paymentMethodType": "free", + "paymentInfo": "free" + } + } + }, + "response": { + "store": "accountPlan2" + } + }, + + { + "comment": "get plan apps, should be 2", + "request": { "uri": "me/plans/{{accountPlan2.uuid}}/apps" }, + "response": { + "check": [{"condition": "json.length == 2"}] + } + } + +] \ No newline at end of file