diff options
author | Øyvind Grønnesby <oyving@verizonmedia.com> | 2019-10-07 15:57:56 +0200 |
---|---|---|
committer | Øyvind Grønnesby <oyving@verizonmedia.com> | 2019-10-07 15:57:56 +0200 |
commit | 99db3b6dedf9896f1c0ab76d7263328161bb8373 (patch) | |
tree | 99cd8115020520a25a68de036564564b97c3fa42 /controller-server | |
parent | 385ff3f0d79e76eba8c6cf688bc730fb14b0dd38 (diff) |
Initial tenant cost API that is not wired up to any clients yet
Diffstat (limited to 'controller-server')
2 files changed, 68 insertions, 0 deletions
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java index 24819fda261..dc44e61ab08 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java @@ -100,6 +100,9 @@ import java.security.PublicKey; import java.time.DayOfWeek; import java.time.Duration; import java.time.Instant; +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeParseException; import java.util.Arrays; import java.util.Base64; import java.util.Comparator; @@ -198,6 +201,8 @@ public class ApplicationApiHandler extends LoggingRequestHandler { if (path.matches("/application/v4/user")) return authenticatedUser(request); if (path.matches("/application/v4/tenant")) return tenants(request); if (path.matches("/application/v4/tenant/{tenant}")) return tenant(path.get("tenant"), request); + if (path.matches("/application/v4/tenant/{tenant}/cost")) return tenantCost(path.get("tenant"), request); + if (path.matches("/application/v4/tenant/{tenant}/cost/{month}")) return tenantCost(path.get("tenant"), path.get("month"), request); if (path.matches("/application/v4/tenant/{tenant}/application")) return applications(path.get("tenant"), Optional.empty(), request); if (path.matches("/application/v4/tenant/{tenant}/application/{application}")) return application(path.get("tenant"), path.get("application"), "default", request); if (path.matches("/application/v4/tenant/{tenant}/application/{application}/deploying")) return deploying(path.get("tenant"), path.get("application"), "default", request); @@ -354,6 +359,51 @@ public class ApplicationApiHandler extends LoggingRequestHandler { return new SlimeJsonResponse(slime); } + private HttpResponse tenantCost(String tenantName, HttpRequest request) { + return controller.tenants().get(TenantName.from(tenantName)) + .map(tenant -> tenantCost(tenant, request)) + .orElseGet(() -> ErrorResponse.notFoundError("Tenant '" + tenantName + "' does not exist")); + } + + private HttpResponse tenantCost(Tenant tenant, HttpRequest request) { + var slime = new Slime(); + var objectCursor = slime.setObject(); + var monthsCursor = objectCursor.setArray("months"); + + return new SlimeJsonResponse(slime); + } + + private HttpResponse tenantCost(String tenantName, String monthString, HttpRequest request) { + Optional<Tenant> tenant = controller.tenants().get(TenantName.from(tenantName)); + Optional<LocalDate> month = tenantCostParseMonth(monthString); + + if (tenant.isEmpty()){ + return ErrorResponse.notFoundError("Tenant '" + tenantName + "' does not exist"); + } + + if (month.isEmpty()) { + return ErrorResponse.badRequest("Could not parse month '" + monthString + "'"); + } + + return tenantCost(tenant.get(), month.get(), request); + } + + private Optional<LocalDate> tenantCostParseMonth(String monthString) { + var formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + + try { + return Optional.of(LocalDate.parse(monthString, formatter).withDayOfMonth(1)); + } catch (DateTimeParseException ignored) { + return Optional.empty(); + } + } + + private HttpResponse tenantCost(Tenant tenant, LocalDate month, HttpRequest request) { + var slime = new Slime(); + slime.setObject(); + return new SlimeJsonResponse(slime); + } + private HttpResponse applications(String tenantName, Optional<String> applicationName, HttpRequest request) { TenantName tenant = TenantName.from(tenantName); Slime slime = new Slime(); diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiTest.java index fb59a0e51d8..7543d18ad21 100644 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiTest.java +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiTest.java @@ -183,6 +183,13 @@ public class ApplicationApiTest extends ControllerContainerTest { tester.assertResponse(request("/application/v4/tenant/", GET).userIdentity(USER_ID), new File("tenant-list.json")); + // GET list of months for a tenant + tester.assertResponse(request("/application/v4/tenant/tenant1/cost", GET).userIdentity(USER_ID).oktaAccessToken(OKTA_AT), + "{\"months\":[]}"); + + // GET cost for a month for a tenant + tester.assertResponse(request("/application/v4/tenant/tenant1/cost/2018-01-01", GET).userIdentity(USER_ID).oktaAccessToken(OKTA_AT), + "{}"); // Add another Athens domain, so we can try to create more tenants createAthenzDomainWithAdmin(ATHENZ_TENANT_DOMAIN_2, USER_ID); // New domain to test tenant w/property ID @@ -1106,6 +1113,17 @@ public class ApplicationApiTest extends ControllerContainerTest { "{\"error-code\":\"NOT_FOUND\",\"message\":\"Could not delete instance 'tenant1.application1.instance1': Instance not found\"}", 404); + // GET cost of unknown tenant + tester.assertResponse(request("/application/v4/tenant/no-such-tenant/cost", GET).userIdentity(USER_ID).oktaAccessToken(OKTA_AT), + "{\"error-code\":\"NOT_FOUND\",\"message\":\"Tenant 'no-such-tenant' does not exist\"}", 404); + + tester.assertResponse(request("/application/v4/tenant/no-such-tenant/cost/2018-01-01", GET).userIdentity(USER_ID).oktaAccessToken(OKTA_AT), + "{\"error-code\":\"NOT_FOUND\",\"message\":\"Tenant 'no-such-tenant' does not exist\"}", 404); + + // GET cost with invalid date string + tester.assertResponse(request("/application/v4/tenant/tenant1/cost/not-a-valid-date", GET).userIdentity(USER_ID).oktaAccessToken(OKTA_AT), + "{\"error-code\":\"BAD_REQUEST\",\"message\":\"Could not parse month 'not-a-valid-date'\"}", 400); + // DELETE tenant tester.assertResponse(request("/application/v4/tenant/tenant1", DELETE) .userIdentity(USER_ID) |