summaryrefslogtreecommitdiffstats
path: root/controller-server
diff options
context:
space:
mode:
authortoby <smorgrav@yahoo-inc.com>2017-09-29 16:00:57 +0200
committertoby <smorgrav@yahoo-inc.com>2017-10-10 13:39:36 +0200
commit7d5330266fea0669d0c903b525e815c004babb75 (patch)
tree93530e7c709c165fad4cc2ff802e7dcffb06aa73 /controller-server
parent44b4159802098abb76ea6dafd54bfac99458c0d7 (diff)
Serialization take 1 - not finished
Diffstat (limited to 'controller-server')
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/application/ClusterCost.java4
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/application/ClusterInfo.java11
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/application/Deployment.java2
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/ClusterInfoMaintainer.java198
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/ApplicationSerializer.java89
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/persistence/ApplicationSerializerTest.java66
6 files changed, 179 insertions, 191 deletions
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/application/ClusterCost.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/application/ClusterCost.java
index 654c7553248..468d00eaf80 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/application/ClusterCost.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/application/ClusterCost.java
@@ -26,8 +26,8 @@ public class ClusterCost {
this.targetUtilization = new ClusterUtilization(0.7,0.2, 0.7, 0.3);
this.resultUtilization = calculateResultUtilization(systemUtilization, targetUtilization);
- this.tco = clusterInfo.getFlavor().cost() * Math.min(1, this.resultUtilization.getMaxUtilization());
- this.waste = clusterInfo.getFlavor().cost() - tco;
+ this.tco = clusterInfo.getCost() * Math.min(1, this.resultUtilization.getMaxUtilization());
+ this.waste = clusterInfo.getCost() - tco;
}
public double getTco() {
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/application/ClusterInfo.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/application/ClusterInfo.java
index 60f8bcfe3d5..259caa9616d 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/application/ClusterInfo.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/application/ClusterInfo.java
@@ -1,7 +1,6 @@
package com.yahoo.vespa.hosted.controller.application;// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
import com.yahoo.config.provision.ClusterSpec;
-import com.yahoo.config.provision.Flavor;
import java.util.List;
@@ -12,20 +11,24 @@ import java.util.List;
* @author smorgrav
*/
public class ClusterInfo {
- private final Flavor flavor;
+ private final String flavor;
+ private final int cost;
private final ClusterSpec.Type clusterType;
private final List<String> hostnames;
- public ClusterInfo(Flavor flavor, ClusterSpec.Type clusterType, List<String> hostnames) {
+ public ClusterInfo(String flavor, int cost, ClusterSpec.Type clusterType, List<String> hostnames) {
this.flavor = flavor;
+ this.cost = cost;
this.clusterType = clusterType;
this.hostnames = hostnames;
}
- public Flavor getFlavor() {
+ public String getFlavor() {
return flavor;
}
+ public int getCost() { return cost; }
+
public ClusterSpec.Type getClusterType() {
return clusterType;
}
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/application/Deployment.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/application/Deployment.java
index 915f3e81b90..9eb2fb87de2 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/application/Deployment.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/application/Deployment.java
@@ -33,6 +33,8 @@ public class Deployment {
Objects.requireNonNull(revision, "revision cannot be null");
Objects.requireNonNull(version, "version cannot be null");
Objects.requireNonNull(deployTime, "deployTime cannot be null");
+ Objects.requireNonNull(clusterUtils, "deployTime cannot be null");
+ Objects.requireNonNull(clusterInfo, "deployTime cannot be null");
this.zone = zone;
this.revision = revision;
this.version = version;
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/ClusterInfoMaintainer.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/ClusterInfoMaintainer.java
index af512db67f5..5fba945844b 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/ClusterInfoMaintainer.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/ClusterInfoMaintainer.java
@@ -1,13 +1,10 @@
package com.yahoo.vespa.hosted.controller.maintenance;// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.yahoo.config.provision.ApplicationId;
import com.yahoo.config.provision.ClusterSpec;
-import com.yahoo.config.provision.Flavor;
-import com.yahoo.config.provision.NodeFlavors;
import com.yahoo.config.provision.Zone;
import com.yahoo.vespa.hosted.controller.Application;
import com.yahoo.vespa.hosted.controller.Controller;
@@ -17,11 +14,9 @@ import com.yahoo.vespa.hosted.controller.application.Deployment;
import java.io.IOException;
import java.net.URI;
import java.time.Duration;
-import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import java.util.Optional;
import java.util.stream.Collectors;
/**
@@ -38,9 +33,15 @@ public class ClusterInfoMaintainer extends Maintainer {
this.controller = controller;
}
- private Map<ClusterSpec.Id, ClusterInfo> getClusterInfo(NodeRepositoryJsonModel nodes, NodeFlavors flavors) {
+ private static String clusterid(NodeRepositoryJsonModel.Node node) {
+ return node.membership.clusterId;
+
+ }
+
+ private Map<ClusterSpec.Id, ClusterInfo> getClusterInfo(NodeRepositoryJsonModel nodes) {
Map<ClusterSpec.Id, ClusterInfo> infoMap = new HashMap<>();
+ // Group nodes by clusterid
Map<String, List<NodeRepositoryJsonModel.Node>> clusters = nodes.nodes.stream()
.filter(node -> node.membership != null)
.collect(Collectors.groupingBy(ClusterInfoMaintainer::clusterid));
@@ -51,32 +52,24 @@ public class ClusterInfoMaintainer extends Maintainer {
//Assume they are all equal and use first node as a representatitve for the cluster
NodeRepositoryJsonModel.Node node = clusterNodes.get(0);
- Optional<Flavor> flavorOpt = flavors.getFlavor(node.nodeFlavor);
-
- List<String> hostnames = clusterNodes.stream().map(node1 -> { return node1.hostname; }).collect(Collectors.toList());
-
- ClusterInfo inf = new ClusterInfo(flavorOpt.get(), ClusterSpec.Type.from(node.membership.clusterType), hostnames);
-
+ // Add to map
+ List<String> hostnames = clusterNodes.stream().map(node1 -> node1.hostname).collect(Collectors.toList());
+ ClusterInfo inf = new ClusterInfo(node.flavor, node.cost, ClusterSpec.Type.from(node.membership.clusterType), hostnames);
infoMap.put(new ClusterSpec.Id(id), inf);
}
return infoMap;
}
- private static String clusterid(NodeRepositoryJsonModel.Node node) {
- return node.membership.clusterId;
-
- }
-
private NodeRepositoryJsonModel getApplicationNodes(ApplicationId appId, Zone zone) {
NodeRepositoryJsonModel nodesResponse = null;
ObjectMapper mapper = new ObjectMapper();
- for (URI uri : controller.getConfigServerUris(null, null)) {
+ for (URI uri : controller.getConfigServerUris(zone.environment(), zone.region())) {
try {
nodesResponse = mapper.readValue(uri.toURL(), NodeRepositoryJsonModel.class);
break;
} catch (IOException ioe) {
-
+ //TODO
}
}
return nodesResponse;
@@ -86,14 +79,9 @@ public class ClusterInfoMaintainer extends Maintainer {
protected void maintain() {
for (Application application : controller().applications().asList()) {
for (Deployment deployment : application.deployments().values()) {
- Zone zone = deployment.zone();
- if (zone.nodeFlavors().isPresent()) {
- NodeFlavors flavors = zone.nodeFlavors().get();
- NodeRepositoryJsonModel appNodes = getApplicationNodes(application.id(), zone);
-
- Map<ClusterSpec.Id, ClusterInfo> clusterInfo = getClusterInfo(appNodes, flavors);
- application.with(deployment.withClusterInfo(clusterInfo));
- }
+ NodeRepositoryJsonModel appNodes = getApplicationNodes(application.id(), deployment.zone());
+ Map<ClusterSpec.Id, ClusterInfo> clusterInfo = getClusterInfo(appNodes);
+ application.with(deployment.withClusterInfo(clusterInfo));
}
}
}
@@ -101,150 +89,26 @@ public class ClusterInfoMaintainer extends Maintainer {
@JsonIgnoreProperties(ignoreUnknown = true)
public static class NodeRepositoryJsonModel {
- public final List<Node> nodes;
-
- @JsonCreator
- public NodeRepositoryJsonModel(@JsonProperty("nodes") List<Node> nodes) {
- this.nodes = Collections.unmodifiableList(nodes);
- }
+ @JsonProperty("nodes")
+ public List<Node> nodes;
@JsonIgnoreProperties(ignoreUnknown = true)
public static class Node {
-
- public final String hostname;
- public final String wantedDockerImage;
- public final String currentDockerImage;
- public final String nodeState;
- public final String nodeType;
- public final String nodeFlavor;
- public final String nodeCanonicalFlavor;
- public final String wantedVespaVersion;
- public final String vespaVersion;
- public final Owner owner;
- public final Membership membership;
- public final Long wantedRestartGeneration;
- public final Long currentRestartGeneration;
- public final Long wantedRebootGeneration;
- public final Long currentRebootGeneration;
- public final Double minCpuCores;
- public final Double minMainMemoryAvailableGb;
- public final Double minDiskAvailableGb;
-
- @JsonCreator
- public Node(@JsonProperty("id") String hostname,
- @JsonProperty("wantedDockerImage") String wantedDockerImage,
- @JsonProperty("currentDockerImage") String currentDockerImage,
- @JsonProperty("state") String nodeState,
- @JsonProperty("type") String nodeType,
- @JsonProperty("flavor") String nodeFlavor,
- @JsonProperty("canonicalFlavor") String nodeCanonicalFlavor,
- @JsonProperty("wantedVespaVersion") String wantedVespaVersion,
- @JsonProperty("vespaVersion") String vespaVersion,
- @JsonProperty("owner") Owner owner,
- @JsonProperty("membership") Membership membership,
- @JsonProperty("restartGeneration") Long wantedRestartGeneration,
- @JsonProperty("currentRestartGeneration") Long currentRestartGeneration,
- @JsonProperty("rebootGeneration") Long wantedRebootGeneration,
- @JsonProperty("currentRebootGeneration") Long currentRebootGeneration,
- @JsonProperty("minCpuCores") Double minCpuCores,
- @JsonProperty("minMainMemoryAvailableGb") Double minMainMemoryAvailableGb,
- @JsonProperty("minDiskAvailableGb") Double minDiskAvailableGb) {
- this.hostname = hostname;
- this.wantedDockerImage = wantedDockerImage;
- this.currentDockerImage = currentDockerImage;
- this.nodeState = nodeState;
- this.nodeType = nodeType;
- this.nodeFlavor = nodeFlavor;
- this.nodeCanonicalFlavor = nodeCanonicalFlavor;
- this.wantedVespaVersion = wantedVespaVersion;
- this.vespaVersion = vespaVersion;
- this.owner = owner;
- this.membership = membership;
- this.wantedRestartGeneration = wantedRestartGeneration;
- this.currentRestartGeneration = currentRestartGeneration;
- this.wantedRebootGeneration = wantedRebootGeneration;
- this.currentRebootGeneration = currentRebootGeneration;
- this.minCpuCores = minCpuCores;
- this.minMainMemoryAvailableGb = minMainMemoryAvailableGb;
- this.minDiskAvailableGb = minDiskAvailableGb;
- }
-
- public String toString() {
- return "Node {"
- + " containerHostname = " + hostname
- + " wantedDockerImage = " + wantedDockerImage
- + " currentDockerImage = " + currentDockerImage
- + " nodeState = " + nodeState
- + " nodeType = " + nodeType
- + " nodeFlavor = " + nodeFlavor
- + " wantedVespaVersion = " + wantedVespaVersion
- + " vespaVersion = " + vespaVersion
- + " owner = " + owner
- + " membership = " + membership
- + " wantedRestartGeneration = " + wantedRestartGeneration
- + " currentRestartGeneration = " + currentRestartGeneration
- + " wantedRebootGeneration = " + wantedRebootGeneration
- + " currentRebootGeneration = " + currentRebootGeneration
- + " minCpuCores = " + minCpuCores
- + " minMainMemoryAvailableGb = " + minMainMemoryAvailableGb
- + " minDiskAvailableGb = " + minDiskAvailableGb
- + " }";
- }
-
-
- public static class Owner {
- public final String tenant;
- public final String application;
- public final String instance;
-
- public Owner(
- @JsonProperty("tenant") String tenant,
- @JsonProperty("application") String application,
- @JsonProperty("instance") String instance) {
- this.tenant = tenant;
- this.application = application;
- this.instance = instance;
- }
-
- public String toString() {
- return "Owner {" +
- " tenant = " + tenant +
- " application = " + application +
- " instance = " + instance +
- " }";
- }
- }
-
+ @JsonProperty("hostname")
+ public String hostname;
+ @JsonProperty("flavor")
+ public String flavor;
+ @JsonProperty("membership")
+ public Membership membership;
+ @JsonProperty("cost")
+ public int cost;
+
+ @JsonIgnoreProperties(ignoreUnknown = true)
public static class Membership {
- public final String clusterType;
- public final String clusterId;
- public final String group;
- public final int index;
- public final boolean retired;
-
- public Membership(
- @JsonProperty("clustertype") String clusterType,
- @JsonProperty("clusterid") String clusterId,
- @JsonProperty("group") String group,
- @JsonProperty("index") int index,
- @JsonProperty("retired") boolean retired) {
- this.clusterType = clusterType;
- this.clusterId = clusterId;
- this.group = group;
- this.index = index;
- this.retired = retired;
- }
-
- @Override
- public String toString() {
- return "Membership {" +
- " clusterType = " + clusterType +
- " clusterId = " + clusterId +
- " group = " + group +
- " index = " + index +
- " retired = " + retired +
- " }";
- }
+ @JsonProperty("clustertype")
+ public String clusterType;
+ @JsonProperty("clusterid")
+ public String clusterId;
}
}
}
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/ApplicationSerializer.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/ApplicationSerializer.java
index 76e0d3bf6db..9266249f487 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/ApplicationSerializer.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/ApplicationSerializer.java
@@ -5,6 +5,7 @@ import com.yahoo.component.Version;
import com.yahoo.config.application.api.DeploymentSpec;
import com.yahoo.config.application.api.ValidationOverrides;
import com.yahoo.config.provision.ApplicationId;
+import com.yahoo.config.provision.ClusterSpec;
import com.yahoo.config.provision.Environment;
import com.yahoo.config.provision.RegionName;
import com.yahoo.config.provision.Zone;
@@ -16,6 +17,8 @@ import com.yahoo.vespa.config.SlimeUtils;
import com.yahoo.vespa.hosted.controller.Application;
import com.yahoo.vespa.hosted.controller.application.ApplicationRevision;
import com.yahoo.vespa.hosted.controller.application.Change;
+import com.yahoo.vespa.hosted.controller.application.ClusterInfo;
+import com.yahoo.vespa.hosted.controller.application.ClusterUtilization;
import com.yahoo.vespa.hosted.controller.application.Deployment;
import com.yahoo.vespa.hosted.controller.application.DeploymentJobs;
import com.yahoo.vespa.hosted.controller.application.DeploymentJobs.JobError;
@@ -27,6 +30,7 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import java.util.Optional;
/**
@@ -76,6 +80,21 @@ public class ApplicationSerializer {
private final String revisionField = "revision";
private final String atField = "at";
private final String upgradeField = "upgrade";
+
+ // ClusterInfo fields
+ private final String clusterInfoField = "clusterInfo";
+ private final String clusterInfoFlavorField = "flavor";
+ private final String clusterInfoCostField = "cost";
+ private final String clusterInfoTypeField = "clusterType";
+ private final String clusterInfoHostnamesField = "hostnames";
+
+ // ClusterUtils fields
+ private final String clusterUtilsField = "clusterUtils";
+ private final String clusterUtilsCpuField = "cpu";
+ private final String clusterUtilsMemField = "mem";
+ private final String clusterUtilsDiskField = "disk";
+ private final String clusterUtilsDiskBusyField = "diskbusy";
+
// ------------------ Serialization
@@ -102,8 +121,43 @@ public class ApplicationSerializer {
object.setString(versionField, deployment.version().toString());
object.setLong(deployTimeField, deployment.at().toEpochMilli());
toSlime(deployment.revision(), object.setObject(applicationPackageRevisionField));
+ clusterInfoToSlime(deployment.clusterInfo(), object);
+ clusterUtilsToSlime(deployment.clusterUtils(), object);
}
-
+
+ private void clusterInfoToSlime(Map<ClusterSpec.Id, ClusterInfo> clusters, Cursor object) {
+ Cursor array = object.setArray(clusterInfoField);
+ for (Map.Entry<ClusterSpec.Id, ClusterInfo> entry : clusters.entrySet()) {
+ toSlime(entry.getValue(), array.addObject(), entry.getKey().value());
+ }
+ }
+
+ private void toSlime(ClusterInfo info, Cursor object, String key) {
+ object = object.setObject(key);
+ object.setString(clusterInfoFlavorField, info.getFlavor());
+ object.setLong(clusterInfoCostField, info.getCost());
+ object.setString(clusterInfoTypeField, info.getClusterType().name());
+ Cursor array = object.setArray(clusterInfoHostnamesField);
+ for (String host : info.getHostnames()) {
+ array.addString(host);
+ }
+ }
+
+ private void clusterUtilsToSlime(Map<ClusterSpec.Id, ClusterUtilization> clusters, Cursor object) {
+ Cursor array = object.setArray(clusterUtilsField);
+ for (Map.Entry<ClusterSpec.Id, ClusterUtilization> entry : clusters.entrySet()) {
+ toSlime(entry.getValue(), array.addObject(), entry.getKey().value());
+ }
+ }
+
+ private void toSlime(ClusterUtilization utils, Cursor object, String key) {
+ object = object.setObject(key);
+ object.setDouble(clusterUtilsCpuField, utils.getCpu());
+ object.setDouble(clusterUtilsMemField, utils.getMemory());
+ object.setDouble(clusterUtilsDiskField, utils.getDisk());
+ object.setDouble(clusterUtilsDiskBusyField, utils.getDiskBusy());
+ }
+
private void zoneToSlime(Zone zone, Cursor object) {
object.setString(environmentField, zone.environment().value());
object.setString(regionField, zone.region().value());
@@ -193,9 +247,38 @@ public class ApplicationSerializer {
applicationRevisionFromSlime(deploymentObject.field(applicationPackageRevisionField)).get(),
Version.fromString(deploymentObject.field(versionField).asString()),
Instant.ofEpochMilli(deploymentObject.field(deployTimeField).asLong()),
- new HashMap<>(), new HashMap<>()); //TODO
+ clusterUtilsMapFromSlime(deploymentObject.field(clusterUtilsField)),
+ clusterInfoMapFromSlime(deploymentObject.field(clusterInfoField)));
}
-
+
+ private Map<ClusterSpec.Id, ClusterInfo> clusterInfoMapFromSlime(Inspector object) {
+ Map<ClusterSpec.Id, ClusterInfo> map = new HashMap<>();
+ object.traverse((String name, Inspector obect) -> map.put(new ClusterSpec.Id(name), clusterInfoFromSlime(obect)));
+ return map;
+ }
+
+ private Map<ClusterSpec.Id, ClusterUtilization> clusterUtilsMapFromSlime(Inspector object) {
+ Map<ClusterSpec.Id, ClusterUtilization> map = new HashMap<>();
+ object.traverse((String name, Inspector obect) -> map.put(new ClusterSpec.Id(name), clusterUtililzationFromSlime(obect)));
+ return map;
+ }
+
+ private ClusterUtilization clusterUtililzationFromSlime(Inspector object) {
+ double cpu = object.field(clusterUtilsCpuField).asDouble();
+ double mem = object.field(clusterUtilsMemField).asDouble();
+ double disk = object.field(clusterUtilsDiskField).asDouble();
+ double diskBusy = object.field(clusterUtilsDiskBusyField).asDouble();
+
+ return new ClusterUtilization(mem, cpu, disk, diskBusy);
+ }
+
+ private ClusterInfo clusterInfoFromSlime(Inspector inspector) {
+ String flavor = inspector.field(clusterInfoFlavorField).asString();
+ int cost = (int)inspector.field(clusterInfoCostField).asLong();
+ String type = inspector.field(clusterInfoTypeField).asString();
+ return new ClusterInfo(flavor, cost, ClusterSpec.Type.from(type), new ArrayList<>());
+ }
+
private Zone zoneFromSlime(Inspector object) {
return new Zone(Environment.from(object.field(environmentField).asString()),
RegionName.from(object.field(regionField).asString()));
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/persistence/ApplicationSerializerTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/persistence/ApplicationSerializerTest.java
index 4df7f343522..a41437d1c39 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/persistence/ApplicationSerializerTest.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/persistence/ApplicationSerializerTest.java
@@ -5,6 +5,7 @@ import com.yahoo.component.Version;
import com.yahoo.config.application.api.DeploymentSpec;
import com.yahoo.config.application.api.ValidationOverrides;
import com.yahoo.config.provision.ApplicationId;
+import com.yahoo.config.provision.ClusterSpec;
import com.yahoo.config.provision.Environment;
import com.yahoo.config.provision.RegionName;
import com.yahoo.config.provision.Zone;
@@ -14,6 +15,8 @@ import com.yahoo.vespa.hosted.controller.Application;
import com.yahoo.vespa.hosted.controller.ControllerTester;
import com.yahoo.vespa.hosted.controller.application.ApplicationRevision;
import com.yahoo.vespa.hosted.controller.application.Change;
+import com.yahoo.vespa.hosted.controller.application.ClusterInfo;
+import com.yahoo.vespa.hosted.controller.application.ClusterUtilization;
import com.yahoo.vespa.hosted.controller.application.Deployment;
import com.yahoo.vespa.hosted.controller.application.DeploymentJobs;
import com.yahoo.vespa.hosted.controller.application.DeploymentJobs.JobError;
@@ -25,7 +28,10 @@ import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.time.Instant;
import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import java.util.Optional;
import static org.junit.Assert.assertEquals;
@@ -37,10 +43,10 @@ import static org.junit.Assert.assertFalse;
public class ApplicationSerializerTest {
private static final ApplicationSerializer applicationSerializer = new ApplicationSerializer();
-
+
private static final Zone zone1 = new Zone(Environment.from("prod"), RegionName.from("us-west-1"));
private static final Zone zone2 = new Zone(Environment.from("prod"), RegionName.from("us-east-3"));
-
+
@Test
public void testSerialization() {
ControllerTester tester = new ControllerTester();
@@ -50,12 +56,13 @@ public class ApplicationSerializerTest {
ValidationOverrides validationOverrides = ValidationOverrides.fromXml("<validation-overrides version='1.0'>" +
" <allow until='2017-06-15'>deployment-removal</allow>" +
"</validation-overrides>");
-
+
List<Deployment> deployments = new ArrayList<>();
ApplicationRevision revision1 = ApplicationRevision.from("appHash1");
ApplicationRevision revision2 = ApplicationRevision.from("appHash2", new SourceRevision("repo1", "branch1", "commit1"));
- deployments.add(new Deployment(zone1, revision1, Version.fromString("1.2.3"), Instant.ofEpochMilli(3)));
- deployments.add(new Deployment(zone2, revision2, Version.fromString("1.2.3"), Instant.ofEpochMilli(5)));
+ deployments.add(new Deployment(zone1, revision1, Version.fromString("1.2.3"), Instant.ofEpochMilli(3))); // One deployment without cluster info and utils
+ deployments.add(new Deployment(zone2, revision2, Version.fromString("1.2.3"), Instant.ofEpochMilli(5),
+ createClusterUtils(3, 0.2), createClusterInfo(3, 4)));
Optional<Long> projectId = Optional.of(123L);
List<JobStatus> statusList = new ArrayList<>();
@@ -69,20 +76,20 @@ public class ApplicationSerializerTest {
DeploymentJobs deploymentJobs = new DeploymentJobs(projectId, statusList, Optional.empty());
- Application original = new Application(ApplicationId.from("t1", "a1", "i1"),
- deploymentSpec,
+ Application original = new Application(ApplicationId.from("t1", "a1", "i1"),
+ deploymentSpec,
validationOverrides,
- deployments, deploymentJobs,
- Optional.of(new Change.VersionChange(Version.fromString("6.7"))),
+ deployments, deploymentJobs,
+ Optional.of(new Change.VersionChange(Version.fromString("6.7"))),
true);
Application serialized = applicationSerializer.fromSlime(applicationSerializer.toSlime(original));
-
+
assertEquals(original.id(), serialized.id());
-
+
assertEquals(original.deploymentSpec().xmlForm(), serialized.deploymentSpec().xmlForm());
assertEquals(original.validationOverrides().xmlForm(), serialized.validationOverrides().xmlForm());
-
+
assertEquals(2, serialized.deployments().size());
assertEquals(original.deployments().get(zone1).revision(), serialized.deployments().get(zone1).revision());
assertEquals(original.deployments().get(zone2).revision(), serialized.deployments().get(zone2).revision());
@@ -98,9 +105,9 @@ public class ApplicationSerializerTest {
assertEquals( original.deploymentJobs().jobStatus().get(DeploymentJobs.JobType.stagingTest),
serialized.deploymentJobs().jobStatus().get(DeploymentJobs.JobType.stagingTest));
assertEquals(original.deploymentJobs().failingSince(), serialized.deploymentJobs().failingSince());
-
+
assertEquals(original.hasOutstandingChange(), serialized.hasOutstandingChange());
-
+
assertEquals(original.deploying(), serialized.deploying());
{ // test more deployment serialization cases
@@ -123,6 +130,36 @@ public class ApplicationSerializerTest {
}
}
+ private Map<ClusterSpec.Id, ClusterInfo> createClusterInfo(int clusters, int hosts) {
+ Map<ClusterSpec.Id, ClusterInfo> result = new HashMap<>();
+
+ for (int cluster = 0; cluster < clusters; cluster++) {
+ List<String> hostnames = new ArrayList<>();
+ for (int host = 0; host < hosts; host++) {
+ hostnames.add("hostname" + cluster*host + host);
+ }
+
+ result.put(ClusterSpec.Id.from("id" + cluster), new ClusterInfo("flavor" + cluster, 10,
+ ClusterSpec.Type.content, Collections.singletonList("hostname1")));
+ }
+ return result;
+ }
+
+ private Map<ClusterSpec.Id, ClusterUtilization> createClusterUtils(int clusters, double inc) {
+ Map<ClusterSpec.Id, ClusterUtilization> result = new HashMap<>();
+
+ ClusterUtilization util = new ClusterUtilization(0,0,0,0);
+ for (int cluster = 0; cluster < clusters; cluster++) {
+ double agg = cluster*inc;
+ result.put(ClusterSpec.Id.from("id" + cluster), new ClusterUtilization(
+ util.getMemory()+ agg,
+ util.getCpu()+ agg,
+ util.getDisk() + agg,
+ util.getDiskBusy() + agg));
+ }
+ return result;
+ }
+
@Test
public void testLegacySerialization() throws IOException {
Application applicationWithSuccessfulJob = applicationSerializer.fromSlime(applicationSlime(false));
@@ -183,5 +220,4 @@ public class ApplicationSerializerTest {
" }\n" +
"}\n";
}
-
}