From 748f6279d83e25183e9ed1053f81f4ea0204008b Mon Sep 17 00:00:00 2001 From: Jon Bratseth Date: Wed, 24 Mar 2021 22:30:06 +0100 Subject: Add stats to node repo client --- .../integration/configserver/ApplicationStats.java | 28 ++++++++++++++++++ .../api/integration/configserver/Cluster.java | 1 - .../api/integration/configserver/Load.java | 27 ++++++++++++++++++ .../integration/configserver/NodeRepoStats.java | 25 ++++++++++++++++ .../noderepository/ApplicationStatsData.java | 33 ++++++++++++++++++++++ .../api/integration/noderepository/LoadData.java | 27 ++++++++++++++++++ .../noderepository/NodeRepoStatsData.java | 33 ++++++++++++++++++++++ .../noderepository/ProvisionResource.java | 5 ++++ 8 files changed, 178 insertions(+), 1 deletion(-) create mode 100644 controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/ApplicationStats.java create mode 100644 controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/Load.java create mode 100644 controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/NodeRepoStats.java create mode 100644 controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/noderepository/ApplicationStatsData.java create mode 100644 controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/noderepository/LoadData.java create mode 100644 controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/noderepository/NodeRepoStatsData.java (limited to 'controller-api') diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/ApplicationStats.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/ApplicationStats.java new file mode 100644 index 00000000000..281641e863f --- /dev/null +++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/ApplicationStats.java @@ -0,0 +1,28 @@ +// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.vespa.hosted.controller.api.integration.configserver; + +import com.yahoo.config.provision.ApplicationId; + +/** + * @author bratseth + */ +public class ApplicationStats { + + private final ApplicationId id; + private final Load load; + private final double cost; + private final double unutilizedCost; + + public ApplicationStats(ApplicationId id, Load load, double cost, double unutilizedCost) { + this.id = id; + this.load = load; + this.cost = cost; + this.unutilizedCost = unutilizedCost; + } + + public ApplicationId id() { return id; } + public Load load() { return load; } + public double cost() { return cost; } + public double unutilizedCost() { return unutilizedCost; } + +} diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/Cluster.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/Cluster.java index 86f649d08ab..d356f5eb89f 100644 --- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/Cluster.java +++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/Cluster.java @@ -28,7 +28,6 @@ public class Cluster { private final double maxQueryGrowthRate; private final double currentQueryFractionOfMax; - public Cluster(ClusterSpec.Id id, ClusterSpec.Type type, ClusterResources min, diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/Load.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/Load.java new file mode 100644 index 00000000000..a16d05a7310 --- /dev/null +++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/Load.java @@ -0,0 +1,27 @@ +// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.vespa.hosted.controller.api.integration.configserver; + +/** + * @author bratseth + */ +public class Load { + + private final double cpu; + private final double memory; + private final double disk; + + public Load(double cpu, double memory, double disk) { + this.cpu = cpu; + this.memory = memory; + this.disk = disk; + } + + public double cpu() { return cpu; } + public double memory() { return memory; } + public double disk() { return disk; } + + public String toString() { + return "load: cpu " + cpu + ", memory " + memory + ", disk " + disk; + } + +} diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/NodeRepoStats.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/NodeRepoStats.java new file mode 100644 index 00000000000..31e5730b6a6 --- /dev/null +++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/NodeRepoStats.java @@ -0,0 +1,25 @@ +// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.vespa.hosted.controller.api.integration.configserver; + +import java.util.List; + +/** + * @author bratseth + */ +public class NodeRepoStats { + + private final Load load; + private final Load activeLoad; + private List applicationStats; + + public NodeRepoStats(Load load, Load activeLoad, List applicationStats) { + this.load = load; + this.activeLoad = activeLoad; + this.applicationStats = List.copyOf(applicationStats); + } + + public Load load() { return load; } + public Load activeLoad() { return activeLoad; } + public List applicationStats() { return applicationStats; } + +} diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/noderepository/ApplicationStatsData.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/noderepository/ApplicationStatsData.java new file mode 100644 index 00000000000..1daf3dd5aaf --- /dev/null +++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/noderepository/ApplicationStatsData.java @@ -0,0 +1,33 @@ +// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.vespa.hosted.controller.api.integration.noderepository; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.yahoo.config.provision.ApplicationId; +import com.yahoo.vespa.hosted.controller.api.integration.configserver.ApplicationStats; + +/** + * @author bratseth + */ +@JsonIgnoreProperties(ignoreUnknown = true) +@JsonInclude(JsonInclude.Include.NON_NULL) +public class ApplicationStatsData { + + @JsonProperty("id") + public String id; + + @JsonProperty("load") + public LoadData load; + + @JsonProperty("cost") + public Double cost; + + @JsonProperty("unutilizedCost") + public Double unutilizedCost; + + public ApplicationStats toApplicationStats() { + return new ApplicationStats(ApplicationId.fromFullString(id), load.toLoad(), cost, unutilizedCost); + } + +} diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/noderepository/LoadData.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/noderepository/LoadData.java new file mode 100644 index 00000000000..ac60ea19134 --- /dev/null +++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/noderepository/LoadData.java @@ -0,0 +1,27 @@ +// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.vespa.hosted.controller.api.integration.noderepository; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.yahoo.vespa.hosted.controller.api.integration.configserver.Load; + +/** + * @author bratseth + */ +@JsonIgnoreProperties(ignoreUnknown = true) +@JsonInclude(JsonInclude.Include.NON_NULL) +public class LoadData { + + @JsonProperty("cpu") + private Double cpu; + @JsonProperty("memory") + private Double memory; + @JsonProperty("disk") + private Double disk; + + public Load toLoad() { + return new Load(cpu, memory, disk); + } + +} diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/noderepository/NodeRepoStatsData.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/noderepository/NodeRepoStatsData.java new file mode 100644 index 00000000000..d3a81201c78 --- /dev/null +++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/noderepository/NodeRepoStatsData.java @@ -0,0 +1,33 @@ +// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.vespa.hosted.controller.api.integration.noderepository; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.yahoo.vespa.hosted.controller.api.integration.configserver.NodeRepoStats; + +import java.util.List; +import java.util.stream.Collectors; + +/** + * @author bratseth + */ +@JsonIgnoreProperties(ignoreUnknown = true) +@JsonInclude(JsonInclude.Include.NON_NULL) +public class NodeRepoStatsData { + + @JsonProperty("load") + public LoadData load; + + @JsonProperty("activeLoad") + public LoadData activeLoad; + + @JsonProperty("applicationStats") + public List applicationStats; + + public NodeRepoStats toNodeRepoStats() { + return new NodeRepoStats(load.toLoad(), activeLoad.toLoad(), + applicationStats.stream().map(stats -> stats.toApplicationStats()).collect(Collectors.toList())); + } + +} diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/noderepository/ProvisionResource.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/noderepository/ProvisionResource.java index 2bfcc20dbd1..26243a28ee0 100644 --- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/noderepository/ProvisionResource.java +++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/noderepository/ProvisionResource.java @@ -2,6 +2,7 @@ package com.yahoo.vespa.hosted.controller.api.integration.noderepository; import com.yahoo.config.provision.TenantName; +import com.yahoo.vespa.hosted.controller.api.integration.configserver.NodeRepoStats; import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; @@ -68,6 +69,10 @@ public interface ProvisionResource { String patchApplication(@PathParam("application") String applicationId, ApplicationPatch applicationPatch, @HeaderParam("X-HTTP-Method-Override") String patchOverride); + @GET + @Path("/stats") + NodeRepoStatsData getStats(); + @PUT @Path("/state/{state}/{hostname}") String setState(@PathParam("state") NodeState state, @PathParam("hostname") String hostname); -- cgit v1.2.3 From f97a835dea395f0d18256535c559bd66746cf04d Mon Sep 17 00:00:00 2001 From: Jon Bratseth Date: Thu, 25 Mar 2021 13:01:09 +0100 Subject: Add stats to controller/v1 API --- .../api/integration/configserver/Load.java | 2 + .../integration/configserver/NodeRepoStats.java | 2 +- .../integration/configserver/NodeRepository.java | 2 + .../noderepository/NodeRepoStatsData.java | 6 +- .../restapi/controller/ControllerApiHandler.java | 3 +- .../restapi/controller/StatsResponse.java | 61 +++++++++++++++++++++ .../controller/integration/NodeRepositoryMock.java | 15 +++++ .../restapi/controller/ControllerApiTest.java | 16 ++++++ .../restapi/controller/responses/root.json | 8 ++- .../restapi/controller/responses/stats.json | 64 ++++++++++++++++++++++ .../provision/restapi/NodesV2ApiHandler.java | 4 +- .../hosted/provision/restapi/responses/root.json | 17 ++++-- .../hosted/provision/restapi/responses/stats.json | 2 +- 13 files changed, 189 insertions(+), 13 deletions(-) create mode 100644 controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/controller/StatsResponse.java create mode 100644 controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/controller/responses/stats.json (limited to 'controller-api') diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/Load.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/Load.java index a16d05a7310..d3fef13aa77 100644 --- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/Load.java +++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/Load.java @@ -24,4 +24,6 @@ public class Load { return "load: cpu " + cpu + ", memory " + memory + ", disk " + disk; } + public static Load zero() { return new Load(0, 0, 0); } + } diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/NodeRepoStats.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/NodeRepoStats.java index 31e5730b6a6..5b5ac21b500 100644 --- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/NodeRepoStats.java +++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/NodeRepoStats.java @@ -10,7 +10,7 @@ public class NodeRepoStats { private final Load load; private final Load activeLoad; - private List applicationStats; + private final List applicationStats; public NodeRepoStats(Load load, Load activeLoad, List applicationStats) { this.load = load; diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/NodeRepository.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/NodeRepository.java index bbe982bd5fe..7d454b2134f 100644 --- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/NodeRepository.java +++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/NodeRepository.java @@ -79,6 +79,8 @@ public interface NodeRepository { void patchApplication(ZoneId zone, ApplicationId application, double currentReadShare, double maxReadShare); + NodeRepoStats getStats(ZoneId zone); + Map getArchiveUris(ZoneId zone); void setArchiveUri(ZoneId zone, TenantName tenantName, URI archiveUri); diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/noderepository/NodeRepoStatsData.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/noderepository/NodeRepoStatsData.java index d3a81201c78..a4b3174b442 100644 --- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/noderepository/NodeRepoStatsData.java +++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/noderepository/NodeRepoStatsData.java @@ -22,12 +22,12 @@ public class NodeRepoStatsData { @JsonProperty("activeLoad") public LoadData activeLoad; - @JsonProperty("applicationStats") - public List applicationStats; + @JsonProperty("applications") + public List applications; public NodeRepoStats toNodeRepoStats() { return new NodeRepoStats(load.toLoad(), activeLoad.toLoad(), - applicationStats.stream().map(stats -> stats.toApplicationStats()).collect(Collectors.toList())); + applications.stream().map(stats -> stats.toApplicationStats()).collect(Collectors.toList())); } } diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/controller/ControllerApiHandler.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/controller/ControllerApiHandler.java index 10c7452a6af..98a9ade1b16 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/controller/ControllerApiHandler.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/controller/ControllerApiHandler.java @@ -68,6 +68,7 @@ public class ControllerApiHandler extends AuditLoggingRequestHandler { if (path.matches("/controller/v1/")) return root(request); if (path.matches("/controller/v1/auditlog/")) return new AuditLogResponse(controller.auditLogger().readLog()); if (path.matches("/controller/v1/maintenance/")) return new JobsResponse(controller.jobControl()); + if (path.matches("/controller/v1/stats")) return new StatsResponse(controller); if (path.matches("/controller/v1/jobs/upgrader")) return new UpgraderResponse(maintenance.upgrader()); if (path.matches("/controller/v1/metering/tenant/{tenant}/month/{month}")) return new MeteringResponse(controller.serviceRegistry().meteringService(), path.get("tenant"), path.get("month")); return notFound(path); @@ -94,7 +95,7 @@ public class ControllerApiHandler extends AuditLoggingRequestHandler { private HttpResponse notFound(Path path) { return ErrorResponse.notFoundError("Nothing at " + path); } private HttpResponse root(HttpRequest request) { - return new ResourceResponse(request, "auditlog", "jobs/upgrader", "maintenance"); + return new ResourceResponse(request, "auditlog", "maintenance", "stats", "jobs/upgrader", "metering/tenant"); } private HttpResponse configureUpgrader(HttpRequest request) { diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/controller/StatsResponse.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/controller/StatsResponse.java new file mode 100644 index 00000000000..e68026f2192 --- /dev/null +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/controller/StatsResponse.java @@ -0,0 +1,61 @@ +// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.vespa.hosted.controller.restapi.controller; + +import com.yahoo.config.provision.zone.ZoneId; +import com.yahoo.restapi.SlimeJsonResponse; +import com.yahoo.slime.Cursor; +import com.yahoo.slime.Slime; +import com.yahoo.vespa.hosted.controller.Controller; +import com.yahoo.vespa.hosted.controller.api.integration.configserver.ApplicationStats; +import com.yahoo.vespa.hosted.controller.api.integration.configserver.Load; +import com.yahoo.vespa.hosted.controller.api.integration.configserver.NodeRepoStats; + +/** + * A response containing statistics about this controller and its zones. + * + * @author bratseth + */ +public class StatsResponse extends SlimeJsonResponse { + + public StatsResponse(Controller controller) { + super(toSlime(controller)); + } + + private static Slime toSlime(Controller controller) { + try { + Slime slime = new Slime(); + Cursor root = slime.setObject(); + Cursor zonesArray = root.setArray("zones"); + for (ZoneId zone : controller.zoneRegistry().zones().all().ids()) { + NodeRepoStats stats = controller.serviceRegistry().configServer().nodeRepository().getStats(zone); + if (stats.applicationStats().isEmpty()) continue; // skip empty zones + Cursor zoneObject = zonesArray.addObject(); + zoneObject.setString("id", zone.toString()); + toSlime(stats.load(), zoneObject.setObject("load")); + toSlime(stats.load(), zoneObject.setObject("activeLoad")); + Cursor applicationsArray = zoneObject.setArray("applications"); + for (var applicationStats : stats.applicationStats()) + toSlime(applicationStats, applicationsArray.addObject()); + } + return slime; + } + catch (Exception e) { + e.printStackTrace(); + throw e; + } + } + + private static void toSlime(ApplicationStats stats, Cursor applicationObject) { + applicationObject.setString("id", stats.id().toFullString()); + toSlime(stats.load(), applicationObject.setObject("load")); + applicationObject.setDouble("cost", stats.cost()); + applicationObject.setDouble("unutilizedCost", stats.unutilizedCost()); + } + + private static void toSlime(Load load, Cursor loadObject) { + loadObject.setDouble("cpu", load.cpu()); + loadObject.setDouble("memory", load.memory()); + loadObject.setDouble("disk", load.disk()); + } + +} diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/integration/NodeRepositoryMock.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/integration/NodeRepositoryMock.java index 85e82bb3fcd..2eabc5dc21b 100644 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/integration/NodeRepositoryMock.java +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/integration/NodeRepositoryMock.java @@ -12,7 +12,10 @@ import com.yahoo.config.provision.TenantName; import com.yahoo.config.provision.zone.ZoneId; import com.yahoo.vespa.hosted.controller.api.identifiers.DeploymentId; import com.yahoo.vespa.hosted.controller.api.integration.configserver.Application; +import com.yahoo.vespa.hosted.controller.api.integration.configserver.ApplicationStats; +import com.yahoo.vespa.hosted.controller.api.integration.configserver.Load; import com.yahoo.vespa.hosted.controller.api.integration.configserver.Node; +import com.yahoo.vespa.hosted.controller.api.integration.configserver.NodeRepoStats; import com.yahoo.vespa.hosted.controller.api.integration.configserver.NodeRepository; import com.yahoo.vespa.hosted.controller.api.integration.configserver.TargetVersions; import com.yahoo.vespa.hosted.controller.api.integration.noderepository.NodeList; @@ -66,6 +69,18 @@ public class NodeRepositoryMock implements NodeRepository { applications.get(zone).put(application.id(), application); } + @Override + public NodeRepoStats getStats(ZoneId zone) { + List applicationStats = + applications.containsKey(zone) + ? applications.get(zone).keySet().stream() + .map(id -> new ApplicationStats(id, Load.zero(), 0, 0)) + .collect(Collectors.toList()) + : List.of(); + + return new NodeRepoStats(Load.zero(), Load.zero(), applicationStats); + } + public Pair getTrafficFraction(ApplicationId application, ZoneId zone) { return trafficFractions.get(new DeploymentId(application, zone)); } diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/controller/ControllerApiTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/controller/ControllerApiTest.java index 5523ce8dd9f..8f6988dbc27 100644 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/controller/ControllerApiTest.java +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/controller/ControllerApiTest.java @@ -8,8 +8,10 @@ import com.yahoo.container.jdisc.HttpRequest; import com.yahoo.test.ManualClock; import com.yahoo.vespa.flags.InMemoryFlagSource; import com.yahoo.vespa.flags.PermanentFlags; +import com.yahoo.vespa.hosted.controller.api.integration.configserver.Application; import com.yahoo.vespa.hosted.controller.api.integration.resource.ResourceSnapshot; import com.yahoo.vespa.hosted.controller.auditlog.AuditLogger; +import com.yahoo.vespa.hosted.controller.integration.NodeRepositoryMock; import com.yahoo.vespa.hosted.controller.restapi.ContainerTester; import com.yahoo.vespa.hosted.controller.restapi.ControllerContainerTest; import org.junit.Before; @@ -49,6 +51,20 @@ public class ControllerApiTest extends ControllerContainerTest { new File("maintenance.json")); } + @Test + public void testStats() { + var mock = (NodeRepositoryMock)tester.controller().serviceRegistry().configServer().nodeRepository(); + mock.putApplication(ZoneId.from("prod", "us-west-1"), + new Application(ApplicationId.fromFullString("t1.a1.i1"), List.of())); + mock.putApplication(ZoneId.from("prod", "us-west-1"), + new Application(ApplicationId.fromFullString("t2.a2.i2"), List.of())); + mock.putApplication(ZoneId.from("prod", "us-east-3"), + new Application(ApplicationId.fromFullString("t1.a1.i1"), List.of())); + + tester.assertResponse(authenticatedRequest("http://localhost:8080/controller/v1/stats", "", Request.Method.GET), + new File("stats.json")); + } + @Test public void testUpgraderApi() { // Get current configuration diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/controller/responses/root.json b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/controller/responses/root.json index 0ff5a8bf443..6d800db303c 100644 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/controller/responses/root.json +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/controller/responses/root.json @@ -3,11 +3,17 @@ { "url": "http://localhost:8080/controller/v1/auditlog/" }, + { + "url": "http://localhost:8080/controller/v1/maintenance/" + }, + { + "url": "http://localhost:8080/controller/v1/stats/" + }, { "url": "http://localhost:8080/controller/v1/jobs/upgrader/" }, { - "url": "http://localhost:8080/controller/v1/maintenance/" + "url": "http://localhost:8080/controller/v1/metering/tenant/" } ] } diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/controller/responses/stats.json b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/controller/responses/stats.json new file mode 100644 index 00000000000..1c9230798dd --- /dev/null +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/controller/responses/stats.json @@ -0,0 +1,64 @@ +{ + "zones": [ + { + "id": "prod.us-east-3", + "load": { + "cpu": 0.0, + "memory": 0.0, + "disk": 0.0 + }, + "activeLoad": { + "cpu": 0.0, + "memory": 0.0, + "disk": 0.0 + }, + "applications": [ + { + "id": "t1.a1.i1", + "load": { + "cpu": 0.0, + "memory": 0.0, + "disk": 0.0 + }, + "cost": 0.0, + "unutilizedCost": 0.0 + } + ] + }, + { + "id": "prod.us-west-1", + "load": { + "cpu": 0.0, + "memory": 0.0, + "disk": 0.0 + }, + "activeLoad": { + "cpu": 0.0, + "memory": 0.0, + "disk": 0.0 + }, + "applications": [ + { + "id": "t1.a1.i1", + "load": { + "cpu": 0.0, + "memory": 0.0, + "disk": 0.0 + }, + "cost": 0.0, + "unutilizedCost": 0.0 + }, + { + "id": "t2.a2.i2", + "load": { + "cpu": 0.0, + "memory": 0.0, + "disk": 0.0 + }, + "cost": 0.0, + "unutilizedCost": 0.0 + } + ] + } + ] +} \ No newline at end of file diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/NodesV2ApiHandler.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/NodesV2ApiHandler.java index 750fe4f0538..9fd23d0d2c2 100644 --- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/NodesV2ApiHandler.java +++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/NodesV2ApiHandler.java @@ -112,7 +112,7 @@ public class NodesV2ApiHandler extends LoggingRequestHandler { private HttpResponse handleGET(HttpRequest request) { Path path = new Path(request.getUri()); String pathS = request.getUri().getPath(); - if (path.matches( "/nodes/v2")) return new ResourceResponse(request.getUri(), "state", "node", "command", "maintenance", "upgrade", "application", "archive", "locks"); + if (path.matches( "/nodes/v2")) return new ResourceResponse(request.getUri(), "node", "state", "acl", "command", "archive", "locks", "maintenance", "upgrade", "capacity", "application", "stats"); if (path.matches( "/nodes/v2/node")) return new NodesResponse(ResponseType.nodeList, request, orchestrator, nodeRepository); if (pathS.startsWith("/nodes/v2/node/")) return new NodesResponse(ResponseType.singleNode, request, orchestrator, nodeRepository); if (path.matches( "/nodes/v2/state")) return new NodesResponse(ResponseType.stateList, request, orchestrator, nodeRepository); @@ -462,7 +462,7 @@ public class NodesV2ApiHandler extends LoggingRequestHandler { toSlime(stats.load(), root.setObject("load")); toSlime(stats.load(), root.setObject("activeLoad")); - Cursor applicationsObject = root.setArray("applicationStats"); + Cursor applicationsObject = root.setArray("applications"); for (int i = 0; i <= 5; i++) { if (i >= stats.applicationStats().size()) break; diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/root.json b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/root.json index 91b513cd9bc..201cc47d66e 100644 --- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/root.json +++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/root.json @@ -1,14 +1,23 @@ { "resources": [ + { + "url": "http://localhost:8080/nodes/v2/node/" + }, { "url": "http://localhost:8080/nodes/v2/state/" }, { - "url": "http://localhost:8080/nodes/v2/node/" + "url": "http://localhost:8080/nodes/v2/acl/" }, { "url": "http://localhost:8080/nodes/v2/command/" }, + { + "url":"http://localhost:8080/nodes/v2/archive/" + }, + { + "url":"http://localhost:8080/nodes/v2/locks/" + }, { "url": "http://localhost:8080/nodes/v2/maintenance/" }, @@ -16,13 +25,13 @@ "url":"http://localhost:8080/nodes/v2/upgrade/" }, { - "url":"http://localhost:8080/nodes/v2/application/" + "url":"http://localhost:8080/nodes/v2/capacity/" }, { - "url":"http://localhost:8080/nodes/v2/archive/" + "url":"http://localhost:8080/nodes/v2/application/" }, { - "url":"http://localhost:8080/nodes/v2/locks/" + "url":"http://localhost:8080/nodes/v2/stats/" } ] } \ No newline at end of file diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/stats.json b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/stats.json index c8e41078a7a..8867520fef6 100644 --- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/stats.json +++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/stats.json @@ -9,7 +9,7 @@ "memory": 0.0, "disk": 0.0 }, - "applicationStats": [ + "applications": [ { "id": "tenant3.application3.instance3", "load": { -- cgit v1.2.3