aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJon Bratseth <bratseth@gmail.com>2023-01-02 16:55:03 +0100
committerJon Bratseth <bratseth@gmail.com>2023-01-02 16:55:03 +0100
commit20a6b5041b179a382a90ca37382a0b6ba3f963f7 (patch)
tree08997145ac9497279caacf295b0b09261cdce1de
parente5d908c70f1063b05c965e989af1da8c4cb393b1 (diff)
Output load in target/suggested block
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/Cluster.java149
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/Load.java12
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/noderepository/AutoscalingData.java44
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/noderepository/ClusterData.java24
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/noderepository/ClusterResourcesData.java1
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/noderepository/ClusterUtilizationData.java37
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java48
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/application/response/application.json35
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/integration/ConfigServerMock.java16
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/application-clusters.json43
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/Autoscaling.java8
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/ApplicationSerializer.java30
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/application1.json76
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/application2.json23
14 files changed, 346 insertions, 200 deletions
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 d2b1f6a0803..b7a71cc7b91 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
@@ -20,12 +20,9 @@ public class Cluster {
private final ClusterResources min;
private final ClusterResources max;
private final ClusterResources current;
- private final Optional<ClusterResources> target;
- private final Optional<ClusterResources> suggested;
- private final Utilization utilization;
+ private final Autoscaling target;
+ private final Autoscaling suggested;
private final List<ScalingEvent> scalingEvents;
- private final String autoscalingStatusCode;
- private final String autoscalingStatus;
private final Duration scalingDuration;
public Cluster(ClusterSpec.Id id,
@@ -33,12 +30,9 @@ public class Cluster {
ClusterResources min,
ClusterResources max,
ClusterResources current,
- Optional<ClusterResources> target,
- Optional<ClusterResources> suggested,
- Utilization utilization,
+ Autoscaling target,
+ Autoscaling suggested,
List<ScalingEvent> scalingEvents,
- String autoscalingStatusCode,
- String autoscalingStatus,
Duration scalingDuration) {
this.id = id;
this.type = type;
@@ -47,24 +41,26 @@ public class Cluster {
this.current = current;
this.target = target;
this.suggested = suggested;
- this.utilization = utilization;
this.scalingEvents = scalingEvents;
- this.autoscalingStatusCode = autoscalingStatusCode;
- this.autoscalingStatus = autoscalingStatus;
this.scalingDuration = scalingDuration;
}
public ClusterSpec.Id id() { return id; }
+
public ClusterSpec.Type type() { return type; }
+
public ClusterResources min() { return min; }
+
public ClusterResources max() { return max; }
+
public ClusterResources current() { return current; }
- public Optional<ClusterResources> target() { return target; }
- public Optional<ClusterResources> suggested() { return suggested; }
- public Utilization utilization() { return utilization; }
+
+ public Autoscaling target() { return target; }
+
+ public Autoscaling suggested() { return suggested; }
+
public List<ScalingEvent> scalingEvents() { return scalingEvents; }
- public String autoscalingStatusCode() { return autoscalingStatusCode; }
- public String autoscalingStatus() { return autoscalingStatus; }
+
public Duration scalingDuration() { return scalingDuration; }
@Override
@@ -72,40 +68,6 @@ public class Cluster {
return "cluster '" + id + "'";
}
- public static class Utilization {
-
- private final double idealCpu, peakCpu;
- private final double idealMemory, peakMemory;
- private final double idealDisk, peakDisk;
-
- public Utilization(double idealCpu, double peakCpu,
- double idealMemory, double peakMemory,
- double idealDisk, double peakDisk) {
- this.idealCpu = idealCpu;
- this.peakCpu = peakCpu;
-
- this.idealMemory = idealMemory;
- this.peakMemory = peakMemory;
-
- this.idealDisk = idealDisk;
- this.peakDisk = peakDisk;
- }
-
- public double idealCpu() { return idealCpu; }
- public double peakCpu() { return peakCpu; }
-
- public double idealMemory() { return idealMemory; }
- public double peakMemory() { return peakMemory; }
-
- public double idealDisk() { return idealDisk; }
- public double peakDisk() { return peakDisk; }
-
- public static Utilization empty() { return new Utilization(0, 0,
- 0, 0,
- 0, 0); }
-
- }
-
public static class ScalingEvent {
private final ClusterResources from, to;
@@ -119,10 +81,13 @@ public class Cluster {
this.completion = completion;
}
- public ClusterResources from() { return from; }
- public ClusterResources to() { return to; }
- public Instant at() { return at; }
- public Optional<Instant> completion() { return completion; }
+ public ClusterResources from() {return from;}
+
+ public ClusterResources to() {return to;}
+
+ public Instant at() {return at;}
+
+ public Optional<Instant> completion() {return completion;}
@Override
public boolean equals(Object o) {
@@ -140,12 +105,74 @@ public class Cluster {
@Override
public String toString() {
return "ScalingEvent{" +
- "from=" + from +
- ", to=" + to +
- ", at=" + at +
- ", completion=" + completion +
- '}';
+ "from=" + from +
+ ", to=" + to +
+ ", at=" + at +
+ ", completion=" + completion +
+ '}';
}
}
+ public static class Autoscaling {
+
+ private final String status;
+ private final String description;
+ private final Optional<ClusterResources> resources;
+ private final Instant at;
+ private final Load peak;
+ private final Load ideal;
+
+ public Autoscaling(String status, String description, Optional<ClusterResources> resources, Instant at,
+ Load peak, Load ideal) {
+ this.status = status;
+ this.description = description;
+ this.resources = resources;
+ this.at = at;
+ this.peak = peak;
+ this.ideal = ideal;
+ }
+
+ public String status() {return status;}
+ public String description() {return description;}
+ public Optional<ClusterResources> resources() {
+ return resources;
+ }
+ public Instant at() {return at;}
+ public Load peak() {return peak;}
+ public Load ideal() {return ideal;}
+
+ @Override
+ public boolean equals(Object o) {
+ if (!(o instanceof Autoscaling other)) return false;
+ if (!this.status.equals(other.status)) return false;
+ if (!this.description.equals(other.description)) return false;
+ if (!this.resources.equals(other.resources)) return false;
+ if (!this.at.equals(other.at)) return false;
+ if (!this.peak.equals(other.peak)) return false;
+ if (!this.ideal.equals(other.ideal)) return false;
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(status, description, at, peak, ideal);
+ }
+
+ @Override
+ public String toString() {
+ return (resources.isPresent() ? "Autoscaling to " + resources : "Don't autoscale") +
+ (description.isEmpty() ? "" : ": " + description);
+ }
+
+ public static Autoscaling empty() {
+ return new Autoscaling("unavailable",
+ "",
+ Optional.empty(),
+ Instant.EPOCH,
+ Load.zero(),
+ Load.zero());
+ }
+
+ }
+
}
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 548fac7d11b..f954d0c8392 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
@@ -1,6 +1,8 @@
// Copyright Yahoo. 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.Objects;
+
/**
* @author bratseth
*/
@@ -20,10 +22,20 @@ public class Load {
public double memory() { return memory; }
public double disk() { return disk; }
+ @Override
public String toString() {
return "load: cpu " + cpu + ", memory " + memory + ", disk " + disk;
}
+ @Override
+ public int hashCode() { return Objects.hash(cpu, memory, disk); }
+
+ @Override
+ public boolean equals(Object o) {
+ if ( ! (o instanceof Load other)) return false;
+ return cpu == other.cpu && memory == other.memory && disk == other.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/noderepository/AutoscalingData.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/noderepository/AutoscalingData.java
new file mode 100644
index 00000000000..3541799b0d0
--- /dev/null
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/noderepository/AutoscalingData.java
@@ -0,0 +1,44 @@
+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.Cluster;
+import com.yahoo.vespa.hosted.controller.api.integration.configserver.Load;
+
+import java.time.Duration;
+import java.time.Instant;
+import java.util.Optional;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class AutoscalingData {
+
+ @JsonProperty("status")
+ public String status;
+
+ @JsonProperty("description")
+ public String description;
+
+ @JsonProperty("resources")
+ public ClusterResourcesData resources;
+
+ @JsonProperty("at")
+ public Long at;
+
+ @JsonProperty("peak")
+ public LoadData peak;
+
+ @JsonProperty("ideal")
+ public LoadData ideal;
+
+ public Cluster.Autoscaling toAutoscaling() {
+ return new Cluster.Autoscaling(status == null ? "" : status,
+ description == null ? "" : description,
+ resources == null ? Optional.empty() : Optional.ofNullable(resources.toClusterResources()),
+ at == null ? Instant.EPOCH : Instant.ofEpochMilli(at),
+ peak == null ? Load.zero() : peak.toLoad(),
+ ideal == null ? Load.zero() : ideal.toLoad());
+ }
+
+}
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/noderepository/ClusterData.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/noderepository/ClusterData.java
index 574b6149508..539f0545c88 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/noderepository/ClusterData.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/noderepository/ClusterData.java
@@ -21,24 +21,25 @@ public class ClusterData {
@JsonProperty("type")
public String type;
+
@JsonProperty("min")
public ClusterResourcesData min;
+
@JsonProperty("max")
public ClusterResourcesData max;
+
@JsonProperty("current")
public ClusterResourcesData current;
+
@JsonProperty("suggested")
- public ClusterResourcesData suggested;
+ public AutoscalingData suggested;
+
@JsonProperty("target")
- public ClusterResourcesData target;
- @JsonProperty("utilization")
- public ClusterUtilizationData utilization;
+ public AutoscalingData target;
+
@JsonProperty("scalingEvents")
public List<ScalingEventData> scalingEvents;
- @JsonProperty("autoscalingStatusCode")
- public String autoscalingStatusCode;
- @JsonProperty("autoscalingStatus")
- public String autoscalingStatus;
+
@JsonProperty("scalingDuration")
public Long scalingDuration;
@@ -48,13 +49,10 @@ public class ClusterData {
min.toClusterResources(),
max.toClusterResources(),
current.toClusterResources(),
- target == null ? Optional.empty() : Optional.of(target.toClusterResources()),
- suggested == null ? Optional.empty() : Optional.of(suggested.toClusterResources()),
- utilization == null ? Cluster.Utilization.empty() : utilization.toClusterUtilization(),
+ target == null ? Cluster.Autoscaling.empty() : target.toAutoscaling(),
+ suggested == null ? Cluster.Autoscaling.empty() : suggested.toAutoscaling(),
scalingEvents == null ? List.of()
: scalingEvents.stream().map(data -> data.toScalingEvent()).toList(),
- autoscalingStatusCode,
- autoscalingStatus,
scalingDuration == null ? Duration.ofMillis(0) : Duration.ofMillis(scalingDuration));
}
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/noderepository/ClusterResourcesData.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/noderepository/ClusterResourcesData.java
index 801ee4ee853..2a9ab1e3a55 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/noderepository/ClusterResourcesData.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/noderepository/ClusterResourcesData.java
@@ -23,6 +23,7 @@ public class ClusterResourcesData {
public NodeResources resources;
public ClusterResources toClusterResources() {
+ if (resources == null) return null; // TODO: Compatibility, remove after January 2023
return new ClusterResources(nodes, groups, resources.toNodeResources());
}
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/noderepository/ClusterUtilizationData.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/noderepository/ClusterUtilizationData.java
deleted file mode 100644
index b4fee25d1ad..00000000000
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/noderepository/ClusterUtilizationData.java
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright Yahoo. 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.Cluster;
-
-/**
- * Utilization ratios
- *
- * @author bratseth
- */
-@JsonIgnoreProperties(ignoreUnknown = true)
-@JsonInclude(JsonInclude.Include.NON_NULL)
-public class ClusterUtilizationData {
-
- @JsonProperty("idealCpu")
- public Double idealCpu;
- @JsonProperty("peakCpu")
- public Double peakCpu;
-
- @JsonProperty("idealMemory")
- public Double idealMemory;
- @JsonProperty("peakMemory")
- public Double peakMemory;
-
- @JsonProperty("idealDisk")
- public Double idealDisk;
- @JsonProperty("peakDisk")
- public Double peakDisk;
-
- public Cluster.Utilization toClusterUtilization() {
- return new Cluster.Utilization(idealCpu, peakCpu, idealMemory, peakMemory, idealDisk, peakDisk);
- }
-
-}
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 fcf7aaf0a82..c8597cff405 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
@@ -64,6 +64,7 @@ import com.yahoo.vespa.hosted.controller.api.integration.configserver.Cluster;
import com.yahoo.vespa.hosted.controller.api.integration.configserver.ConfigServerException;
import com.yahoo.vespa.hosted.controller.api.integration.configserver.DeploymentResult;
import com.yahoo.vespa.hosted.controller.api.integration.configserver.DeploymentResult.LogEntry;
+import com.yahoo.vespa.hosted.controller.api.integration.configserver.Load;
import com.yahoo.vespa.hosted.controller.api.integration.configserver.LoadBalancer;
import com.yahoo.vespa.hosted.controller.api.integration.configserver.Node;
import com.yahoo.vespa.hosted.controller.api.integration.configserver.NodeFilter;
@@ -74,7 +75,6 @@ import com.yahoo.vespa.hosted.controller.api.integration.deployment.JobType;
import com.yahoo.vespa.hosted.controller.api.integration.deployment.RevisionId;
import com.yahoo.vespa.hosted.controller.api.integration.deployment.RunId;
import com.yahoo.vespa.hosted.controller.api.integration.deployment.SourceRevision;
-import com.yahoo.vespa.hosted.controller.api.integration.dns.VpcEndpointService.VpcEndpoint;
import com.yahoo.vespa.hosted.controller.api.integration.noderepository.RestartFilter;
import com.yahoo.vespa.hosted.controller.api.integration.secrets.TenantSecretStore;
import com.yahoo.vespa.hosted.controller.api.role.Role;
@@ -1348,14 +1348,12 @@ public class ApplicationApiHandler extends AuditLoggingRequestHandler {
toSlime(cluster.min(), clusterObject.setObject("min"));
toSlime(cluster.max(), clusterObject.setObject("max"));
toSlime(cluster.current(), clusterObject.setObject("current"));
- if (cluster.target().isPresent()
- && ! cluster.target().get().justNumbers().equals(cluster.current().justNumbers()))
- toSlime(cluster.target().get(), clusterObject.setObject("target"));
- cluster.suggested().ifPresent(suggested -> toSlime(suggested, clusterObject.setObject("suggested")));
- utilizationToSlime(cluster.utilization(), clusterObject.setObject("utilization"));
+ toSlime(cluster.target(), cluster, clusterObject.setObject("target"));
+ toSlime(cluster.suggested(), cluster, clusterObject.setObject("suggested"));
+ legacyUtilizationToSlime(cluster.target().peak(), cluster.target().ideal(), clusterObject.setObject("utilization")); // TODO: Remove after January 2023
scalingEventsToSlime(cluster.scalingEvents(), clusterObject.setArray("scalingEvents"));
- clusterObject.setString("autoscalingStatusCode", cluster.autoscalingStatusCode());
- clusterObject.setString("autoscalingStatus", cluster.autoscalingStatus());
+ clusterObject.setString("autoscalingStatusCode", cluster.target().status()); // TODO: Remove after January 2023
+ clusterObject.setString("autoscalingStatus", cluster.target().description()); // TODO: Remove after January 2023
clusterObject.setLong("scalingDuration", cluster.scalingDuration().toMillis());
}
return new SlimeJsonResponse(slime);
@@ -2702,15 +2700,35 @@ public class ApplicationApiHandler extends AuditLoggingRequestHandler {
object.setDouble("cost", cost);
}
- private void utilizationToSlime(Cluster.Utilization utilization, Cursor utilizationObject) {
- utilizationObject.setDouble("idealCpu", utilization.idealCpu());
- utilizationObject.setDouble("peakCpu", utilization.peakCpu());
+ private void toSlime(Cluster.Autoscaling autoscaling, Cluster cluster, Cursor autoscalingObject) {
+ // TODO: Remove after January 2023
+ if (autoscaling.resources().isPresent()
+ && ! autoscaling.resources().get().justNumbers().equals(cluster.current().justNumbers()))
+ toSlime(autoscaling.resources().get(), autoscalingObject);
- utilizationObject.setDouble("idealMemory", utilization.idealMemory());
- utilizationObject.setDouble("peakMemory", utilization.peakMemory());
+ autoscalingObject.setString("status", autoscaling.status());
+ autoscalingObject.setString("description", autoscaling.description());
+ autoscaling.resources().ifPresent(resources -> toSlime(resources, autoscalingObject.setObject("resources")));
+ autoscalingObject.setLong("at", autoscaling.at().toEpochMilli());
+ toSlime(autoscaling.peak(), autoscalingObject.setObject("peak"));
+ toSlime(autoscaling.ideal(), autoscalingObject.setObject("ideal"));
+ }
+
+ private void toSlime(Load load, Cursor loadObject) {
+ loadObject.setDouble("cpu", load.cpu());
+ loadObject.setDouble("memory", load.memory());
+ loadObject.setDouble("disk", load.disk());
+ }
+
+ private void legacyUtilizationToSlime(Load peak, Load ideal, Cursor utilizationObject) {
+ utilizationObject.setDouble("idealCpu", ideal.cpu());
+ utilizationObject.setDouble("peakCpu", peak.cpu());
+
+ utilizationObject.setDouble("idealMemory", ideal.memory());
+ utilizationObject.setDouble("peakMemory", peak.memory());
- utilizationObject.setDouble("idealDisk", utilization.idealDisk());
- utilizationObject.setDouble("peakDisk", utilization.peakDisk());
+ utilizationObject.setDouble("idealDisk", ideal.disk());
+ utilizationObject.setDouble("peakDisk", peak.disk());
}
private void scalingEventsToSlime(List<Cluster.ScalingEvent> scalingEvents, Cursor scalingEventsArray) {
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/application/response/application.json b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/application/response/application.json
index 4cc2ac8c47f..37da498b6ec 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/application/response/application.json
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/application/response/application.json
@@ -100,16 +100,31 @@
}
},
"suggested": {
- "nodes": 2,
- "groups": 1,
- "resources": {
- "vcpu": 2.0,
- "memoryGb": 4.0,
- "diskGb": 50.0,
- "bandwidthGbps": 0.3,
- "diskSpeed": "fast",
- "storageType": "local",
- "architecture": "x86_64"
+ "status" : "unavailable",
+ "description" : "",
+ "resources" : {
+ "nodes": 2,
+ "groups": 1,
+ "resources": {
+ "vcpu": 2.0,
+ "memoryGb": 4.0,
+ "diskGb": 50.0,
+ "bandwidthGbps": 0.3,
+ "diskSpeed": "fast",
+ "storageType": "local",
+ "architecture": "x86_64"
+ },
+ "at" : 123,
+ "peak" : {
+ "cpu" : 0.1,
+ "memory" : 0.2,
+ "disk" : 0.3
+ },
+ "ideal" : {
+ "cpu" : 0.4,
+ "memory" : 0.5,
+ "disk" : 0.6
+ }
}
},
"scalingDuration": 90000
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/integration/ConfigServerMock.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/integration/ConfigServerMock.java
index badf7832ccb..448bb9ac15f 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/integration/ConfigServerMock.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/integration/ConfigServerMock.java
@@ -30,6 +30,7 @@ import com.yahoo.vespa.hosted.controller.api.integration.configserver.Cluster;
import com.yahoo.vespa.hosted.controller.api.integration.configserver.ConfigServer;
import com.yahoo.vespa.hosted.controller.api.integration.configserver.ContainerEndpoint;
import com.yahoo.vespa.hosted.controller.api.integration.configserver.DeploymentResult;
+import com.yahoo.vespa.hosted.controller.api.integration.configserver.Load;
import com.yahoo.vespa.hosted.controller.api.integration.configserver.LoadBalancer;
import com.yahoo.vespa.hosted.controller.api.integration.configserver.LoadBalancer.PrivateServiceInfo;
import com.yahoo.vespa.hosted.controller.api.integration.configserver.Node;
@@ -43,7 +44,6 @@ import com.yahoo.vespa.hosted.controller.api.integration.noderepository.RestartF
import com.yahoo.vespa.hosted.controller.api.integration.secrets.TenantSecretStore;
import com.yahoo.vespa.hosted.controller.application.SystemApplication;
import com.yahoo.vespa.hosted.controller.application.pkg.ApplicationPackage;
-import wiremock.org.checkerframework.checker.units.qual.A;
import java.io.ByteArrayInputStream;
import java.io.IOException;
@@ -116,17 +116,17 @@ public class ConfigServerMock extends AbstractComponent implements ConfigServer
new ClusterResources(2, 1, new NodeResources(1, 4, 20, 1, slow, remote)),
new ClusterResources(2, 1, new NodeResources(4, 16, 90, 1, slow, remote)),
current,
- Optional.of(new ClusterResources(2, 1, new NodeResources(3, 8, 50, 1, slow, remote))),
- Optional.empty(),
- new Cluster.Utilization(0.2, 0.35,
- 0.5, 0.65,
- 0.8, 1.0),
+ new Cluster.Autoscaling("ideal",
+ "Cluster is ideally scaled",
+ Optional.of(new ClusterResources(2, 1, new NodeResources(3, 8, 50, 1, slow, remote))),
+ Instant.ofEpochMilli(123),
+ new Load(0.35, 0.65, 1.0),
+ new Load(0.2, 0.5, 0.8)),
+ Cluster.Autoscaling.empty(),
List.of(new Cluster.ScalingEvent(new ClusterResources(0, 0, NodeResources.unspecified()),
current,
Instant.ofEpochMilli(1234),
Optional.of(Instant.ofEpochMilli(2234)))),
- "ideal",
- "Cluster is ideally scaled",
Duration.ofMinutes(6));
nodeRepository.putApplication(zone,
new com.yahoo.vespa.hosted.controller.api.integration.configserver.Application(application,
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/application-clusters.json b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/application-clusters.json
index 238368260eb..c013ccb00fe 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/application-clusters.json
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/application-clusters.json
@@ -52,7 +52,48 @@
"diskSpeed": "slow",
"storageType": "remote"
},
- "cost": 0.29
+ "cost": 0.29,
+ "status": "ideal",
+ "description": "Cluster is ideally scaled",
+ "resources": {
+ "nodes": 2,
+ "groups": 1,
+ "nodeResources": {
+ "vcpu": 3.0,
+ "memoryGb": 8.0,
+ "diskGb": 50.0,
+ "bandwidthGbps": 1.0,
+ "diskSpeed": "slow",
+ "storageType": "remote"
+ },
+ "cost": 0.29
+ },
+ "at" : 123,
+ "peak": {
+ "cpu": 0.35,
+ "memory": 0.65,
+ "disk": 1.0
+ },
+ "ideal": {
+ "cpu": 0.2,
+ "memory": 0.5,
+ "disk": 0.8
+ }
+ },
+ "suggested": {
+ "status": "unavailable",
+ "description": "",
+ "at": 0,
+ "peak": {
+ "cpu": 0.0,
+ "memory": 0.0,
+ "disk": 0.0
+ },
+ "ideal": {
+ "cpu": 0.0,
+ "memory": 0.0,
+ "disk": 0.0
+ }
},
"utilization": {
"idealCpu": 0.2,
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/Autoscaling.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/Autoscaling.java
index 579f9c2514f..2989d675daa 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/Autoscaling.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/Autoscaling.java
@@ -30,15 +30,15 @@ public class Autoscaling {
this.ideal = ideal;
}
+ public Status status() { return status; }
+
+ public String description() { return description; }
+
/** Returns the resource target of this, or empty if none (meaning keep the current allocation). */
public Optional<ClusterResources> resources() {
return resources;
}
- public Status status() { return status; }
-
- public String description() { return description; }
-
/** Returns the time this was decided. */
public Instant at() { return at; }
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/ApplicationSerializer.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/ApplicationSerializer.java
index eac49a705b1..cb927c72eb5 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/ApplicationSerializer.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/ApplicationSerializer.java
@@ -9,6 +9,7 @@ import com.yahoo.vespa.hosted.provision.NodeRepository;
import com.yahoo.vespa.hosted.provision.applications.Application;
import com.yahoo.vespa.hosted.provision.applications.Cluster;
import com.yahoo.vespa.hosted.provision.applications.ScalingEvent;
+import com.yahoo.vespa.hosted.provision.autoscale.Autoscaling;
import com.yahoo.vespa.hosted.provision.autoscale.Limits;
import com.yahoo.vespa.hosted.provision.autoscale.Load;
@@ -63,30 +64,31 @@ public class ApplicationSerializer {
toSlime(limits.max(), clusterObject.setObject("max"));
toSlime(currentResources, clusterObject.setObject("current"));
if (cluster.shouldSuggestResources(currentResources))
- cluster.suggested().resources().ifPresent(suggested -> toSlime(suggested, clusterObject.setObject("suggested")));
- cluster.target().resources().ifPresent(target -> toSlime(target, clusterObject.setObject("target")));
- clusterUtilizationToSlime(cluster.target().ideal(), cluster.target().peak(), clusterObject.setObject("utilization"));
+ toSlime(cluster.suggested(), clusterObject.setObject("suggested"));
+ toSlime(cluster.target(), clusterObject.setObject("target"));
scalingEventsToSlime(cluster.scalingEvents(), clusterObject.setArray("scalingEvents"));
- clusterObject.setString("autoscalingStatusCode", cluster.target().status().name());
- clusterObject.setString("autoscalingStatus", cluster.target().description());
clusterObject.setLong("scalingDuration", cluster.scalingDuration(nodes.clusterSpec()).toMillis());
}
+ private static void toSlime(Autoscaling autoscaling, Cursor autoscalingObject) {
+ autoscalingObject.setString("status", autoscaling.status().name());
+ autoscalingObject.setString("description", autoscaling.description());
+ autoscaling.resources().ifPresent(resources -> toSlime(resources, autoscalingObject.setObject("resources")));
+ autoscalingObject.setLong("at", autoscaling.at().toEpochMilli());
+ toSlime(autoscaling.peak(), autoscalingObject.setObject("peak"));
+ toSlime(autoscaling.ideal(), autoscalingObject.setObject("ideal"));
+ }
+
private static void toSlime(ClusterResources resources, Cursor clusterResourcesObject) {
clusterResourcesObject.setLong("nodes", resources.nodes());
clusterResourcesObject.setLong("groups", resources.groups());
NodeResourcesSerializer.toSlime(resources.nodeResources(), clusterResourcesObject.setObject("resources"));
}
- private static void clusterUtilizationToSlime(Load idealLoad, Load peakLoad, Cursor utilizationObject) {
- utilizationObject.setDouble("idealCpu", idealLoad.cpu());
- utilizationObject.setDouble("peakCpu", peakLoad.cpu());
-
- utilizationObject.setDouble("idealMemory", idealLoad.memory());
- utilizationObject.setDouble("peakMemory", peakLoad.memory());
-
- utilizationObject.setDouble("idealDisk", idealLoad.disk());
- utilizationObject.setDouble("peakDisk", peakLoad.disk());
+ private static void toSlime(Load load, Cursor utilizationObject) {
+ utilizationObject.setDouble("cpu", load.cpu());
+ utilizationObject.setDouble("memory", load.memory());
+ utilizationObject.setDouble("disk", load.disk());
}
private static void scalingEventsToSlime(List<ScalingEvent> scalingEvents, Cursor scalingEventsArray) {
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/application1.json b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/application1.json
index 18f2422e081..ead4e5fd06a 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/application1.json
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/application1.json
@@ -44,39 +44,61 @@
}
},
"suggested" : {
- "nodes" : 6,
- "groups" : 2,
+ "status" : "unavailable",
+ "description" : "",
"resources" : {
- "vcpu" : 3.0,
- "memoryGb" : 20.0,
- "diskGb" : 100.0,
- "bandwidthGbps" : 1.0,
- "diskSpeed" : "fast",
- "storageType" : "any",
- "architecture":"x86_64"
+ "nodes": 6,
+ "groups": 2,
+ "resources": {
+ "vcpu": 3.0,
+ "memoryGb": 20.0,
+ "diskGb": 100.0,
+ "bandwidthGbps": 1.0,
+ "diskSpeed": "fast",
+ "storageType": "any",
+ "architecture": "x86_64"
+ }
+ },
+ "at" : 123,
+ "peak" : {
+ "cpu" : 0.0,
+ "memory" : 0.0,
+ "disk" : 0.0
+ },
+ "ideal" : {
+ "cpu" : 0.0,
+ "memory" : 0.0,
+ "disk" : 0.0
}
},
"target" : {
- "nodes" : 4,
- "groups" : 1,
+ "status" : "unavailable",
+ "description" : "",
"resources" : {
- "vcpu" : 3.0,
- "memoryGb" : 16.0,
- "diskGb" : 100.0,
- "bandwidthGbps" : 1.0,
- "diskSpeed" : "fast",
- "storageType" : "any",
- "architecture":"x86_64"
+ "nodes" : 4,
+ "groups" : 1,
+ "resources" : {
+ "vcpu": 3.0,
+ "memoryGb": 16.0,
+ "diskGb": 100.0,
+ "bandwidthGbps": 1.0,
+ "diskSpeed": "fast",
+ "storageType": "any",
+ "architecture": "x86_64"
+ }
+ },
+ "at" : 123,
+ "peak" : {
+ "cpu" : 0.0,
+ "memory" : 0.0,
+ "disk" : 0.0
+ },
+ "ideal" : {
+ "cpu" : 0.0,
+ "memory" : 0.0,
+ "disk" : 0.0
}
},
- "utilization" : {
- "idealCpu": 0.0,
- "peakCpu": 0.0,
- "idealMemory": 0.0,
- "peakMemory": 0.0,
- "idealDisk": 0.0,
- "peakDisk": 0.0
- },
"scalingEvents" : [
{
"from": {
@@ -108,8 +130,6 @@
"at" : 123
}
],
- "autoscalingStatusCode": "unavailable",
- "autoscalingStatus": "",
"scalingDuration": 600000
}
}
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/application2.json b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/application2.json
index 03b93c897b9..f60fdf3e602 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/application2.json
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/application2.json
@@ -43,13 +43,20 @@
"architecture":"x86_64"
}
},
- "utilization" : {
- "idealCpu": 0.0,
- "peakCpu": 0.0,
- "idealMemory": 0.0,
- "peakMemory": 0.0,
- "idealDisk": 0.0,
- "peakDisk": 0.0
+ "target" : {
+ "status" : "unavailable",
+ "description" : "",
+ "at" : 0,
+ "peak" : {
+ "cpu" : 0.0,
+ "memory" : 0.0,
+ "disk" : 0.0
+ },
+ "ideal" : {
+ "cpu" : 0.0,
+ "memory" : 0.0,
+ "disk" : 0.0
+ }
},
"scalingEvents" : [
{
@@ -82,8 +89,6 @@
"at" : 123
}
],
- "autoscalingStatusCode": "unavailable",
- "autoscalingStatus" : "",
"scalingDuration": 43200000
}
}