diff options
author | Harald Musum <musum@yahooinc.com> | 2023-10-13 15:14:48 +0200 |
---|---|---|
committer | Harald Musum <musum@yahooinc.com> | 2023-10-13 15:14:48 +0200 |
commit | 1fe61e8329e25b41576286b24e867f822226c778 (patch) | |
tree | 6f293914c7691d74c955616c45ee2dac0dbd13e5 | |
parent | 4941bdf24e4ab4ac09348f9d50d65bb4d8112c50 (diff) |
Remove support for legacy price calculations from API
6 files changed, 24 insertions, 139 deletions
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/MockPricingController.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/MockPricingController.java index 8ea1882bff6..0aa07e93010 100644 --- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/MockPricingController.java +++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/MockPricingController.java @@ -1,7 +1,6 @@ // Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.hosted.controller.api.integration; -import com.yahoo.config.provision.ClusterResources; import com.yahoo.vespa.hosted.controller.api.integration.billing.Plan; import com.yahoo.vespa.hosted.controller.api.integration.pricing.ApplicationResources; import com.yahoo.vespa.hosted.controller.api.integration.pricing.PriceInformation; @@ -18,25 +17,6 @@ import static java.math.BigDecimal.valueOf; public class MockPricingController implements PricingController { - // TODO: Remove when not in use anymore - @Override - public PriceInformation price(List<ClusterResources> clusterResources, PricingInfo pricingInfo, Plan plan) { - BigDecimal listPrice = valueOf(clusterResources.stream() - .mapToDouble(resources -> resources.nodes() * - (resources.nodeResources().vcpu() * 1000 + - resources.nodeResources().memoryGb() * 100 + - resources.nodeResources().diskGb() * 10)) - .sum()); - - BigDecimal supportLevelCost = pricingInfo.supportLevel() == BASIC ? new BigDecimal("-160.00") : new BigDecimal("800.00"); - BigDecimal listPriceWithSupport = listPrice.add(supportLevelCost); - BigDecimal enclaveDiscount = pricingInfo.enclave() ? new BigDecimal("-15.1234") : BigDecimal.ZERO; - BigDecimal volumeDiscount = new BigDecimal("-5.64315634"); - BigDecimal committedAmountDiscount = new BigDecimal("-1.23"); - BigDecimal totalAmount = listPrice.add(supportLevelCost).add(enclaveDiscount).add(volumeDiscount).add(committedAmountDiscount); - return new PriceInformation("default", listPriceWithSupport, volumeDiscount, committedAmountDiscount, enclaveDiscount, totalAmount); - } - @Override public Prices priceForApplications(List<ApplicationResources> applicationResources, PricingInfo pricingInfo, Plan plan) { ApplicationResources resources = applicationResources.get(0); diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/pricing/ApplicationResources.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/pricing/ApplicationResources.java index 5c6de406a55..fa742c27486 100644 --- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/pricing/ApplicationResources.java +++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/pricing/ApplicationResources.java @@ -2,6 +2,8 @@ package com.yahoo.vespa.hosted.controller.api.integration.pricing; import java.math.BigDecimal; +import static java.math.BigDecimal.ZERO; + /** * @param applicationName name of the application * @param vcpu vcpus summed over all clusters, instances, zones @@ -17,5 +19,14 @@ public record ApplicationResources(String applicationName, BigDecimal vcpu, BigD BigDecimal gpuMemoryGb, BigDecimal enclaveVcpu, BigDecimal enclaveMemoryGb, BigDecimal enclaveDiskGb, BigDecimal enclaveGpuMemoryGb) { -} + public static ApplicationResources create(String applicationName, BigDecimal vcpu, BigDecimal memoryGb, + BigDecimal diskGb, BigDecimal gpuMemoryGb) { + return new ApplicationResources(applicationName, vcpu, memoryGb, diskGb, gpuMemoryGb, ZERO, ZERO, ZERO, ZERO); + } + public static ApplicationResources createEnclave(String applicationName, BigDecimal vcpu, BigDecimal memoryGb, + BigDecimal diskGb, BigDecimal gpuMemoryGb) { + return new ApplicationResources(applicationName, ZERO, ZERO, ZERO, ZERO, vcpu, memoryGb, diskGb, gpuMemoryGb); + } + +} diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/pricing/PricingController.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/pricing/PricingController.java index 23d5f81dfb7..7b082932588 100644 --- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/pricing/PricingController.java +++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/pricing/PricingController.java @@ -1,7 +1,6 @@ // Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.hosted.controller.api.integration.pricing; -import com.yahoo.config.provision.ClusterResources; import com.yahoo.vespa.hosted.controller.api.integration.billing.Plan; import java.util.List; @@ -13,9 +12,6 @@ import java.util.List; */ public interface PricingController { - // TODO: Legacy, will be removed when not in use anymore - PriceInformation price(List<ClusterResources> clusterResources, PricingInfo pricingInfo, Plan plan); - /** * * @param applicationResources resources used by an application diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/pricing/PricingInfo.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/pricing/PricingInfo.java index 1ab149d083f..ba6f1939fc5 100644 --- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/pricing/PricingInfo.java +++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/pricing/PricingInfo.java @@ -1,11 +1,14 @@ // Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.hosted.controller.api.integration.pricing; -// TODO: Use BigDecimal for committedHourlyAmount -public record PricingInfo(boolean enclave, SupportLevel supportLevel, double committedHourlyAmount) { +import java.math.BigDecimal; + +import static java.math.BigDecimal.ZERO; + +public record PricingInfo(SupportLevel supportLevel, BigDecimal committedHourlyAmount) { public enum SupportLevel { BASIC, COMMERCIAL, ENTERPRISE } - public static PricingInfo empty() { return new PricingInfo(false, SupportLevel.COMMERCIAL, 0); } + public static PricingInfo empty() { return new PricingInfo(SupportLevel.COMMERCIAL, ZERO); } } diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/pricing/PricingApiHandler.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/pricing/PricingApiHandler.java index 7cff6e951c6..48ddd59e3f2 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/pricing/PricingApiHandler.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/pricing/PricingApiHandler.java @@ -83,19 +83,8 @@ public class PricingApiHandler extends ThreadedHttpRequestHandler { private HttpResponse pricing(HttpRequest request) { String rawQuery = request.getUri().getRawQuery(); var priceParameters = parseQuery(rawQuery); - boolean isLegacy = priceParameters.appResources() == null; - if (isLegacy) { - PriceInformation price = calculateLegacyPrice(priceParameters); - return legacyResponse(price, priceParameters); - } else { - Prices price = calculatePrice(priceParameters); - return response(price, priceParameters); - } - } - - private PriceInformation calculateLegacyPrice(PriceParameters priceParameters) { - var priceCalculator = controller.serviceRegistry().pricingController(); - return priceCalculator.price(priceParameters.clusterResources, priceParameters.pricingInfo, priceParameters.plan); + Prices price = calculatePrice(priceParameters); + return response(price, priceParameters); } private Prices calculatePrice(PriceParameters priceParameters) { @@ -106,35 +95,7 @@ public class PricingApiHandler extends ThreadedHttpRequestHandler { private PriceParameters parseQuery(String rawQuery) { if (rawQuery == null) throw new IllegalArgumentException("No price information found in query"); List<String> elements = Arrays.stream(URLDecoder.decode(rawQuery, UTF_8).split("&")).toList(); - - if (keysAndValues(elements).stream().map(Pair::getFirst).toList().contains("resources")) - return parseQueryLegacy(elements); - else - return parseQuery(elements); - } - - private PriceParameters parseQueryLegacy(List<String> elements) { - var supportLevel = SupportLevel.BASIC; - var enclave = false; - var committedSpend = ZERO; - var plan = controller.serviceRegistry().planRegistry().defaultPlan(); // fallback to default plan if not supplied - List<ClusterResources> clusterResources = new ArrayList<>(); - - for (Pair<String, String> entry : keysAndValues(elements)) { - var value = entry.getSecond(); - switch (entry.getFirst().toLowerCase()) { - case "committedspend" -> committedSpend = new BigDecimal(value); - case "enclave" -> enclave = Boolean.parseBoolean(value); - case "planid" -> plan = plan(value).orElseThrow(() -> new IllegalArgumentException("Unknown plan id " + value)); - case "supportlevel" -> supportLevel = SupportLevel.valueOf(value.toUpperCase()); - case "resources" -> clusterResources.add(clusterResources(value)); - default -> throw new IllegalArgumentException("Unknown query parameter '" + entry.getFirst() + '\''); - } - } - if (clusterResources.isEmpty()) throw new IllegalArgumentException("No cluster resources found in query"); - - PricingInfo pricingInfo = new PricingInfo(enclave, supportLevel, committedSpend.doubleValue()); - return new PriceParameters(clusterResources, pricingInfo, plan, null); + return parseQuery(elements); } private PriceParameters parseQuery(List<String> elements) { @@ -157,8 +118,7 @@ public class PricingApiHandler extends ThreadedHttpRequestHandler { } if (appResources.isEmpty()) throw new IllegalArgumentException("No application resources found in query"); - // TODO: enclave does not make sense in PricingInfo anymore, remove when legacy method is removed - PricingInfo pricingInfo = new PricingInfo(false, supportLevel, committedSpend.doubleValue()); + PricingInfo pricingInfo = new PricingInfo(supportLevel, committedSpend); return new PriceParameters(List.of(), pricingInfo, plan, appResources); } @@ -239,21 +199,6 @@ public class PricingApiHandler extends ThreadedHttpRequestHandler { return controller.serviceRegistry().planRegistry().plan(element); } - private static SlimeJsonResponse legacyResponse(PriceInformation priceInfo, PriceParameters priceParameters) { - var slime = new Slime(); - Cursor cursor = slime.setObject(); - - var array = cursor.setArray("priceInfo"); - addItem(array, supportLevelDescription(priceParameters), priceInfo.listPriceWithSupport()); - addItem(array, "Enclave", priceInfo.enclaveDiscount()); - addItem(array, "Volume discount", priceInfo.volumeDiscount()); - addItem(array, "Committed spend", priceInfo.committedAmountDiscount()); - - setBigDecimal(cursor, "totalAmount", priceInfo.totalAmount()); - - return new SlimeJsonResponse(slime); - } - private static SlimeJsonResponse response(Prices prices, PriceParameters priceParameters) { var slime = new Slime(); Cursor cursor = slime.setObject(); diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/pricing/PricingApiHandlerTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/pricing/PricingApiHandlerTest.java index 321e582437a..6262697f0c3 100644 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/pricing/PricingApiHandlerTest.java +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/pricing/PricingApiHandlerTest.java @@ -22,25 +22,6 @@ public class PricingApiHandlerTest extends ControllerContainerCloudTest { private static final String responseFiles = "src/test/java/com/yahoo/vespa/hosted/controller/restapi/pricing/responses/"; @Test - void testPricingInfoBasicLegacy() { - ContainerTester tester = new ContainerTester(container, responseFiles); - assertEquals(SystemName.Public, tester.controller().system()); - - var request = request("/pricing/v1/pricing?" + urlEncodedPriceInformationLegacy(BASIC, false)); - tester.assertJsonResponse(request, """ - { - "priceInfo": [ - {"description": "Basic support unit price", "amount": "2240.00"}, - {"description": "Volume discount", "amount": "-5.64"}, - {"description": "Committed spend", "amount": "-1.23"} - ], - "totalAmount": "2233.13" - } - """, - 200); - } - - @Test void testPricingInfoBasic() { ContainerTester tester = new ContainerTester(container, responseFiles); assertEquals(SystemName.Public, tester.controller().system()); @@ -94,26 +75,6 @@ public class PricingApiHandlerTest extends ControllerContainerCloudTest { } @Test - void testPricingInfoCommercialEnclaveLegacy() { - ContainerTester tester = new ContainerTester(container, responseFiles); - assertEquals(SystemName.Public, tester.controller().system()); - - var request = request("/pricing/v1/pricing?" + urlEncodedPriceInformationLegacy(COMMERCIAL, true)); - tester.assertJsonResponse(request, """ - { - "priceInfo": [ - {"description": "Commercial support unit price", "amount": "3200.00"}, - {"description": "Enclave", "amount": "-15.12"}, - {"description": "Volume discount", "amount": "-5.64"}, - {"description": "Committed spend", "amount": "-1.23"} - ], - "totalAmount": "3178.00" - } - """, - 200); - } - - @Test void testPricingInfoCommercialEnclave() { ContainerTester tester = new ContainerTester(container, responseFiles); assertEquals(SystemName.Public, tester.controller().system()); @@ -198,23 +159,12 @@ public class PricingApiHandlerTest extends ControllerContainerCloudTest { tester.assertJsonResponse(request("/pricing/v1/pricing?supportLevel=basic&committedSpend=0&key=value"), "{\"error-code\":\"BAD_REQUEST\",\"message\":\"Unknown query parameter 'key'\"}", 400); - tester.assertJsonResponse(request("/pricing/v1/pricing?supportLevel=basic&committedSpend=0&resources=key%3Dvalue"), - "{\"error-code\":\"BAD_REQUEST\",\"message\":\"Unknown resource type 'key'\"}", + tester.assertJsonResponse(request("/pricing/v1/pricing?supportLevel=basic&committedSpend=0&application=key%3Dvalue"), + "{\"error-code\":\"BAD_REQUEST\",\"message\":\"Unknown key 'key'\"}", 400); } /** - * 2 clusters, with each having 1 node, with 1 vcpu, 1 Gb memory, 10 Gb disk and no GPU - * price will be 20000 + 2000 + 200 - */ - String urlEncodedPriceInformationLegacy(PricingInfo.SupportLevel supportLevel, boolean enclave) { - String resources = URLEncoder.encode("nodes=1,vcpu=1,memoryGb=1,diskGb=10,gpuMemoryGb=0", UTF_8); - return "supportLevel=" + supportLevel.name().toLowerCase() + "&committedSpend=100&enclave=" + enclave + - "&resources=" + resources + - "&resources=" + resources; - } - - /** * 1 app, with 2 clusters (with total resources for all clusters with each having * 1 node, with 1 vcpu, 1 Gb memory, 10 Gb disk and no GPU, * price will be 20000 + 2000 + 200 |