diff options
2 files changed, 63 insertions, 0 deletions
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/billing/BillingApiHandlerV2.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/billing/BillingApiHandlerV2.java index 718320c02ca..83cd5dab2f3 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/billing/BillingApiHandlerV2.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/billing/BillingApiHandlerV2.java @@ -4,6 +4,7 @@ package com.yahoo.vespa.hosted.controller.restapi.billing; import com.yahoo.config.provision.TenantName; import com.yahoo.container.jdisc.HttpResponse; import com.yahoo.container.jdisc.ThreadedHttpRequestHandler; +import com.yahoo.messagebus.Message; import com.yahoo.restapi.MessageResponse; import com.yahoo.restapi.RestApi; import com.yahoo.restapi.RestApiException; @@ -98,6 +99,9 @@ public class BillingApiHandlerV2 extends RestApiRequestHandler<BillingApiHandler .post(Slime.class, self::newAdditionalItem)) .addRoute(RestApi.route("/billing/v2/accountant/tenant/{tenant}/item/{item}") .delete(self::deleteAdditionalItem)) + .addRoute(RestApi.route("/billing/v2/accountant/tenant/{tenant}/plan") + .get(self::accountantTenantPlan) + .post(Slime.class, self::setAccountantTenantPlan)) .addRoute(RestApi.route("/billing/v2/accountant/bill/{invoice}/export") .put(Slime.class, self::putAccountantInvoiceExport)) .addRoute(RestApi.route("/billing/v2/accountant/plans") @@ -361,6 +365,39 @@ public class BillingApiHandlerV2 extends RestApiRequestHandler<BillingApiHandler return slime; } + private MessageResponse setAccountantTenantPlan(RestApi.RequestContext requestContext, Slime body) { + var tenantName = TenantName.from(requestContext.pathParameters().getStringOrThrow("tenant")); + var tenant = tenants.require(tenantName, CloudTenant.class); + + var planId = PlanId.from(getInspectorFieldOrThrow(body.get(), "id")); + var response = billing.setPlan(tenant.name(), planId, false, true); + + if (response.isSuccess()) { + return new MessageResponse("Plan: " + planId.value()); + } else { + throw new RestApiException.BadRequest("Could not change plan: " + response.getErrorMessage()); + } + } + + private Slime accountantTenantPlan(RestApi.RequestContext requestContext) { + var tenantName = TenantName.from(requestContext.pathParameters().getStringOrThrow("tenant")); + var tenant = tenants.require(tenantName, CloudTenant.class); + + var planId = billing.getPlan(tenant.name()); + var plan = planRegistry.plan(planId); + + if (plan.isEmpty()) { + throw new RestApiException.BadRequest("Plan with ID '" + planId.value() + "' does not exist"); + } + + var slime = new Slime(); + var root = slime.setObject(); + root.setString("id", plan.get().id().value()); + root.setString("name", plan.get().displayName()); + + return slime; + } + // --------- INVOICE RENDERING ---------- private void invoicesSummaryToSlime(Cursor slime, List<Bill> bills) { diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/billing/BillingApiHandlerV2Test.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/billing/BillingApiHandlerV2Test.java index a2290f1f664..424b8d84472 100644 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/billing/BillingApiHandlerV2Test.java +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/billing/BillingApiHandlerV2Test.java @@ -185,4 +185,30 @@ public class BillingApiHandlerV2Test extends ControllerContainerCloudTest { {"message":"Successfully deleted line item line-item-id"}"""); } } + + @Test + void require_current_plan() { + { + var accountantRequest = request("/billing/v2/accountant/tenant/tenant1/plan") + .roles(Role.hostedAccountant()); + tester.assertResponse(accountantRequest, """ + {"id":"trial","name":"Free Trial - for testing purposes"}"""); + } + + { + var accountantRequest = request("/billing/v2/accountant/tenant/tenant1/plan", Request.Method.POST) + .roles(Role.hostedAccountant()) + .data(""" + {"id": "paid"}"""); + tester.assertResponse(accountantRequest, """ + {"message":"Plan: paid"}"""); + } + + { + var accountantRequest = request("/billing/v2/accountant/tenant/tenant1/plan") + .roles(Role.hostedAccountant()); + tester.assertResponse(accountantRequest, """ + {"id":"paid","name":"Paid Plan - for testing purposes"}"""); + } + } } |