summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Polden <mpolden@mpolden.no>2021-07-13 18:09:55 +0200
committerMartin Polden <mpolden@mpolden.no>2021-07-14 13:55:42 +0200
commit3f5ae1a97891afda12a214ff3f86b716c6a08ef8 (patch)
tree1ae047d2011ad0e2b81eda96b6c8577390e7ca95
parent7af0a1695d43836dcf83e26710f5db5092f8e4ab (diff)
Do not use serializable NodeRepositoryNode internally in controller
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/Node.java348
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/NodeRepository.java154
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/repair/RepairTicketReport.java5
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/vcmr/VCMRReport.java5
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/ChangeManagementAssessor.java58
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/VCMRMaintainer.java3
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java2
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/deployment/InternalStepRunnerTest.java8
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/integration/ConfigServerMock.java67
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/integration/NodeRepositoryMock.java252
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/ChangeManagementAssessorTest.java90
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/CloudEventReporterTest.java8
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/CostReportMaintainerTest.java2
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/HostInfoUpdaterTest.java12
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/MetricsReporterTest.java3
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/OsUpgraderTest.java8
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/ResourceMeterMaintainerTest.java34
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/ResourceTagMaintainerTest.java39
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/SystemUpgraderTest.java4
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/VCMRMaintainerTest.java32
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/changemanagement/ChangeManagementApiHandlerTest.java82
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/os/OsApiTest.java2
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/versions/VersionStatusTest.java4
23 files changed, 592 insertions, 630 deletions
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/Node.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/Node.java
index 5f46b949844..25357ad7f98 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/Node.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/Node.java
@@ -1,7 +1,6 @@
// Copyright 2018 Yahoo Holdings. 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.fasterxml.jackson.databind.JsonNode;
import com.yahoo.component.Version;
import com.yahoo.config.provision.ApplicationId;
import com.yahoo.config.provision.DockerImage;
@@ -9,26 +8,29 @@ import com.yahoo.config.provision.HostName;
import com.yahoo.config.provision.NodeResources;
import com.yahoo.config.provision.NodeType;
import com.yahoo.config.provision.TenantName;
-import com.yahoo.vespa.hosted.controller.api.integration.noderepository.NodeHistory;
import java.time.Instant;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
+import java.util.UUID;
/**
* A node in hosted Vespa.
*
+ * This is immutable and all fields are guaranteed to be non-null. This should never leak any wire format types or
+ * types from third-party libraries.
+ *
+ * Use {@link Node#builder()} or {@link Node#builder(Node)} to create instances of this.
+ *
* @author mpolden
* @author jonmv
*/
public class Node {
+ private final String id;
private final HostName hostname;
private final Optional<HostName> parentHostname;
private final State state;
@@ -50,204 +52,278 @@ public class Node {
private final long rebootGeneration;
private final long wantedRebootGeneration;
private final int cost;
+ private final int failCount;
private final String flavor;
private final String clusterId;
private final ClusterType clusterType;
+ private final String group;
private final boolean retired;
private final boolean wantToRetire;
private final boolean wantToDeprovision;
private final boolean wantToRebuild;
private final Optional<TenantName> reservedTo;
private final Optional<ApplicationId> exclusiveTo;
- private final Map<String, JsonNode> reports;
- private final List<NodeHistory> history;
+ private final Map<String, String> reports;
+ private final List<Event> history;
+ private final Set<String> ipAddresses;
private final Set<String> additionalIpAddresses;
- private final String openStackId;
+ private final Set<String> additionalHostnames;
private final Optional<String> switchHostname;
private final Optional<String> modelName;
-
- public Node(HostName hostname, Optional<HostName> parentHostname, State state, NodeType type, NodeResources resources, Optional<ApplicationId> owner,
- Version currentVersion, Version wantedVersion, Version currentOsVersion, Version wantedOsVersion,
- Optional<Instant> currentFirmwareCheck, Optional<Instant> wantedFirmwareCheck, ServiceState serviceState,
- Optional<Instant> suspendedSince, long restartGeneration, long wantedRestartGeneration, long rebootGeneration, long wantedRebootGeneration,
- int cost, String flavor, String clusterId, ClusterType clusterType, boolean retired, boolean wantToRetire, boolean wantToDeprovision,
- boolean wantToRebuild, Optional<TenantName> reservedTo, Optional<ApplicationId> exclusiveTo,
- DockerImage wantedDockerImage, DockerImage currentDockerImage, Map<String, JsonNode> reports, List<NodeHistory> history,
- Set<String> additionalIpAddresses, String openStackId, Optional<String> switchHostname, Optional<String> modelName) {
- this.hostname = hostname;
- this.parentHostname = parentHostname;
- this.state = state;
- this.type = type;
- this.resources = resources;
- this.owner = owner;
- this.currentVersion = currentVersion;
- this.wantedVersion = wantedVersion;
- this.currentOsVersion = currentOsVersion;
- this.wantedOsVersion = wantedOsVersion;
- this.currentFirmwareCheck = currentFirmwareCheck;
- this.wantedFirmwareCheck = wantedFirmwareCheck;
- this.serviceState = serviceState;
- this.suspendedSince = suspendedSince;
+ private final Environment environment;
+
+ private Node(String id, HostName hostname, Optional<HostName> parentHostname, State state, NodeType type,
+ NodeResources resources, Optional<ApplicationId> owner, Version currentVersion, Version wantedVersion,
+ Version currentOsVersion, Version wantedOsVersion, Optional<Instant> currentFirmwareCheck,
+ Optional<Instant> wantedFirmwareCheck, ServiceState serviceState, Optional<Instant> suspendedSince,
+ long restartGeneration, long wantedRestartGeneration, long rebootGeneration,
+ long wantedRebootGeneration, int cost, int failCount, String flavor, String clusterId,
+ ClusterType clusterType, String group, boolean retired, boolean wantToRetire, boolean wantToDeprovision,
+ boolean wantToRebuild, Optional<TenantName> reservedTo, Optional<ApplicationId> exclusiveTo,
+ DockerImage wantedDockerImage, DockerImage currentDockerImage, Map<String, String> reports,
+ List<Event> history, Set<String> ipAddresses, Set<String> additionalIpAddresses,
+ Set<String> additionalHostnames, Optional<String> switchHostname,
+ Optional<String> modelName, Environment environment) {
+ this.id = Objects.requireNonNull(id, "id must be non-null");
+ this.hostname = Objects.requireNonNull(hostname, "hostname must be non-null");
+ this.parentHostname = Objects.requireNonNull(parentHostname, "parentHostname must be non-null");
+ this.state = Objects.requireNonNull(state, "state must be non-null");
+ this.type = Objects.requireNonNull(type, "type must be non-null");
+ this.resources = Objects.requireNonNull(resources, "resources must be non-null");
+ this.owner = Objects.requireNonNull(owner, "owner must be non-null");
+ this.currentVersion = Objects.requireNonNull(currentVersion, "currentVersion must be non-null");
+ this.wantedVersion = Objects.requireNonNull(wantedVersion, "wantedVersion must be non-null");
+ this.currentOsVersion = Objects.requireNonNull(currentOsVersion, "currentOsVersion must be non-null");
+ this.wantedOsVersion = Objects.requireNonNull(wantedOsVersion, "wantedOsVersion must be non-null");
+ this.currentFirmwareCheck = Objects.requireNonNull(currentFirmwareCheck, "currentFirmwareCheck must be non-null");
+ this.wantedFirmwareCheck = Objects.requireNonNull(wantedFirmwareCheck, "wantedFirmwareCheck must be non-null");
+ this.serviceState = Objects.requireNonNull(serviceState, "serviceState must be non-null");
+ this.suspendedSince = Objects.requireNonNull(suspendedSince, "suspendedSince must be non-null");
this.restartGeneration = restartGeneration;
this.wantedRestartGeneration = wantedRestartGeneration;
this.rebootGeneration = rebootGeneration;
this.wantedRebootGeneration = wantedRebootGeneration;
this.cost = cost;
- this.flavor = flavor;
- this.clusterId = clusterId;
- this.clusterType = clusterType;
+ this.failCount = failCount;
+ this.flavor = Objects.requireNonNull(flavor, "flavor must be non-null");
+ this.clusterId = Objects.requireNonNull(clusterId, "clusterId must be non-null");
+ this.clusterType = Objects.requireNonNull(clusterType, "clusterType must be non-null");
this.retired = retired;
+ this.group = Objects.requireNonNull(group, "group must be non-null");
this.wantToRetire = wantToRetire;
this.wantToDeprovision = wantToDeprovision;
- this.reservedTo = reservedTo;
- this.exclusiveTo = exclusiveTo;
- this.wantedDockerImage = wantedDockerImage;
- this.currentDockerImage = currentDockerImage;
+ this.reservedTo = Objects.requireNonNull(reservedTo, "reservedTo must be non-null");
+ this.exclusiveTo = Objects.requireNonNull(exclusiveTo, "exclusiveTo must be non-null");
+ this.wantedDockerImage = Objects.requireNonNull(wantedDockerImage, "wantedDockerImage must be non-null");
+ this.currentDockerImage = Objects.requireNonNull(currentDockerImage, "currentDockerImage must be non-null");
this.wantToRebuild = wantToRebuild;
- this.reports = reports;
- this.history = history;
- this.openStackId = openStackId;
- this.additionalIpAddresses = additionalIpAddresses;
- this.switchHostname = switchHostname;
- this.modelName = modelName;
+ this.reports = Map.copyOf(Objects.requireNonNull(reports, "reports must be non-null"));
+ this.history = List.copyOf(Objects.requireNonNull(history, "history must be non-null"));
+ this.ipAddresses = Set.copyOf(Objects.requireNonNull(ipAddresses, "ipAddresses must be non-null"));
+ this.additionalIpAddresses = Set.copyOf(Objects.requireNonNull(additionalIpAddresses, "additionalIpAddresses must be non-null"));
+ this.additionalHostnames = Set.copyOf(Objects.requireNonNull(additionalHostnames, "additionalHostnames must be non-null"));
+ this.switchHostname = Objects.requireNonNull(switchHostname, "switchHostname must be non-null");
+ this.modelName = Objects.requireNonNull(modelName, "modelName must be non-null");
+ this.environment = Objects.requireNonNull(environment, "environment must be non-ull");
}
+ /** The cloud provider's unique ID for this */
+ public String id() {
+ return id;
+ }
+
+ /** The hostname of this */
public HostName hostname() {
return hostname;
}
+ /** The parent hostname of this, if any */
public Optional<HostName> parentHostname() {
return parentHostname;
}
+ /** Current state of this */
public State state() { return state; }
+ /** The node type of this */
public NodeType type() {
return type;
}
+ /** Resources, such as CPU and memory, of this */
public NodeResources resources() {
return resources;
}
+ /** The application owning this, if any */
public Optional<ApplicationId> owner() {
return owner;
}
+ /** The Vespa version this is currently running */
public Version currentVersion() {
return currentVersion;
}
+ /** The wanted Vespa version */
public Version wantedVersion() {
return wantedVersion;
}
+ /** The OS version this is currently running */
public Version currentOsVersion() {
return currentOsVersion;
}
+ /** The wanted OS version */
public Version wantedOsVersion() {
return wantedOsVersion;
}
+ /** The container image of this is currently running */
public DockerImage currentDockerImage() {
return currentDockerImage;
}
+ /** The wanted Docker image */
public DockerImage wantedDockerImage() {
return wantedDockerImage;
}
+ /** The last time this checked for a firmware update */
public Optional<Instant> currentFirmwareCheck() {
return currentFirmwareCheck;
}
+ /** The wanted time this should check for a firmware update */
public Optional<Instant> wantedFirmwareCheck() {
return wantedFirmwareCheck;
}
+ /** The current service state of this */
public ServiceState serviceState() {
return serviceState;
}
+ /** The most recent time this suspended, if any */
public Optional<Instant> suspendedSince() {
return suspendedSince;
}
+ /** The current restart generation */
public long restartGeneration() {
return restartGeneration;
}
+ /** The wanted restart generation */
public long wantedRestartGeneration() {
return wantedRestartGeneration;
}
+ /** The current reboot generation */
public long rebootGeneration() {
return rebootGeneration;
}
+ /** The wanted reboot generation */
public long wantedRebootGeneration() {
return wantedRebootGeneration;
}
+ /** A number representing the cost of this */
public int cost() {
return cost;
}
+ /** How many times this has failed */
+ public int failCount() {
+ return failCount;
+ }
+
+ /** The flavor of this */
public String flavor() {
return flavor;
}
+ /** The cluster ID of this, empty string if unallocated */
public String clusterId() {
return clusterId;
}
+ /** The cluster type of this */
public ClusterType clusterType() {
return clusterType;
}
+ /** Whether this is retired */
public boolean retired() {
return retired;
}
+ /** The group of this node, empty string if unallocated */
+ public String group() {
+ return group;
+ }
+
+ /** Whether this node has been requested to retire */
public boolean wantToRetire() {
return wantToRetire;
}
+ /** Whether this node has been requested to deprovision */
public boolean wantToDeprovision() {
return wantToDeprovision;
}
+ /** Whether this node has been requested to rebuild */
public boolean wantToRebuild() {
return wantToRebuild;
}
+ /** The tenant this has been reserved to, if any */
public Optional<TenantName> reservedTo() { return reservedTo; }
+ /** The application this has been provisioned exclusively for, if any */
public Optional<ApplicationId> exclusiveTo() { return exclusiveTo; }
- public Map<String, JsonNode> reports() {
+ /** Returns the reports of this node. Key is the report ID. Value is untyped, but is typically a JSON string */
+ public Map<String, String> reports() {
return reports;
}
- public List<NodeHistory> history() {
+ /** History of events affecting this */
+ public List<Event> history() {
return history;
}
+ /** IP addresses of this */
+ public Set<String> ipAddresses() {
+ return ipAddresses;
+ }
+
+ /** Additional IP addresses available on this, usable by child nodes */
public Set<String> additionalIpAddresses() {
return additionalIpAddresses;
}
- public String openStackId() {
- return openStackId;
+ /** Additional hostnames available on this, usable by child nodes */
+ public Set<String> additionalHostnames() {
+ return additionalHostnames;
}
+ /** Hostname of the switch this is connected to, if any */
public Optional<String> switchHostname() {
return switchHostname;
}
+ /** The server model of this, if any */
public Optional<String> modelName() { return modelName; }
+ /** The environment this runs in */
+ public Environment environment() {
+ return environment;
+ }
+
@Override
public boolean equals(Object o) {
if (this == o) return true;
@@ -293,48 +369,106 @@ public class Node {
combined,
unknown
}
+
+ /** Known nope environments */
+ public enum Environment {
+ bareMetal,
+ virtualMachine,
+ dockerContainer,
+ }
+
+ /** A node event */
+ public static class Event {
+
+ private final Instant at;
+ private final String agent;
+ private final String name;
+
+ public Event(Instant at, String agent, String name) {
+ this.at = Objects.requireNonNull(at);
+ this.agent = Objects.requireNonNull(agent);
+ this.name = Objects.requireNonNull(name);
+ }
+
+ /** The time this occurred */
+ public Instant at() {
+ return at;
+ }
+
+ /** The agent responsible for this */
+ public String agent() {
+ return agent;
+ }
+
+ /** Name of the event */
+ public String name() {
+ return name;
+ }
+
+ }
+
+ public static Builder builder() {
+ return new Builder();
+ }
+ public static Builder builder(Node node) {
+ return new Builder(node);
+ }
+
+ /**
+ * Builder for a {@link Node}.
+ *
+ * The appropriate builder method must be called for any field that does not have a default value.
+ */
public static class Builder {
+
private HostName hostname;
+
+ private String id = UUID.randomUUID().toString();
private Optional<HostName> parentHostname = Optional.empty();
- private State state;
- private NodeType type;
- private NodeResources resources;
+ private State state = State.active;
+ private NodeType type = NodeType.host;
+ private NodeResources resources = NodeResources.unspecified();
private Optional<ApplicationId> owner = Optional.empty();
- private Version currentVersion;
- private Version wantedVersion;
- private Version currentOsVersion;
- private Version wantedOsVersion;
- private DockerImage currentDockerImage;
- private DockerImage wantedDockerImage;
+ private Version currentVersion = Version.emptyVersion;
+ private Version wantedVersion = Version.emptyVersion;
+ private Version currentOsVersion = Version.emptyVersion;
+ private Version wantedOsVersion = Version.emptyVersion;
+ private DockerImage currentDockerImage = DockerImage.EMPTY;
+ private DockerImage wantedDockerImage = DockerImage.EMPTY;
private Optional<Instant> currentFirmwareCheck = Optional.empty();
private Optional<Instant> wantedFirmwareCheck = Optional.empty();
- private ServiceState serviceState;
+ private ServiceState serviceState = ServiceState.unknown;
private Optional<Instant> suspendedSince = Optional.empty();
- private long restartGeneration;
- private long wantedRestartGeneration;
- private long rebootGeneration;
- private long wantedRebootGeneration;
- private int cost;
- private String flavor;
- private String clusterId;
- private ClusterType clusterType;
- private boolean retired;
- private boolean wantToRetire;
- private boolean wantToDeprovision;
- private boolean wantToRebuild;
+ private long restartGeneration = 0;
+ private long wantedRestartGeneration = 0;
+ private long rebootGeneration = 0;
+ private long wantedRebootGeneration = 0;
+ private int cost = 0;
+ private int failCount = 0;
+ private String flavor = "default";
+ private String clusterId = "";
+ private ClusterType clusterType = ClusterType.unknown;
+ private String group = "";
+ private boolean retired = false;
+ private boolean wantToRetire = false;
+ private boolean wantToDeprovision = false;
+ private boolean wantToRebuild = false;
private Optional<TenantName> reservedTo = Optional.empty();
private Optional<ApplicationId> exclusiveTo = Optional.empty();
- private Map<String, JsonNode> reports = new HashMap<>();
- private List<NodeHistory> history = new ArrayList<>();
- private Set<String> additionalIpAddresses = new HashSet<>();
- private String openStackId;
+ private Map<String, String> reports = Map.of();
+ private List<Event> history = List.of();
+ private Set<String> ipAddresses = Set.of();
+ private Set<String> additionalIpAddresses = Set.of();
+ private Set<String> additionalHostnames = Set.of();
private Optional<String> switchHostname = Optional.empty();
private Optional<String> modelName = Optional.empty();
+ private Environment environment = Environment.bareMetal;
- public Builder() { }
+ private Builder() {}
- public Builder(Node node) {
+ private Builder(Node node) {
+ this.id = node.id;
this.hostname = node.hostname;
this.parentHostname = node.parentHostname;
this.state = node.state;
@@ -347,18 +481,20 @@ public class Node {
this.wantedOsVersion = node.wantedOsVersion;
this.currentDockerImage = node.currentDockerImage;
this.wantedDockerImage = node.wantedDockerImage;
- this.currentFirmwareCheck = node.currentFirmwareCheck;
- this.wantedFirmwareCheck = node.wantedFirmwareCheck;
this.serviceState = node.serviceState;
this.suspendedSince = node.suspendedSince;
+ this.currentFirmwareCheck = node.currentFirmwareCheck;
+ this.wantedFirmwareCheck = node.wantedFirmwareCheck;
this.restartGeneration = node.restartGeneration;
this.wantedRestartGeneration = node.wantedRestartGeneration;
this.rebootGeneration = node.rebootGeneration;
this.wantedRebootGeneration = node.wantedRebootGeneration;
this.cost = node.cost;
+ this.failCount = node.failCount;
this.flavor = node.flavor;
this.clusterId = node.clusterId;
this.clusterType = node.clusterType;
+ this.group = node.group;
this.retired = node.retired;
this.wantToRetire = node.wantToRetire;
this.wantToDeprovision = node.wantToDeprovision;
@@ -367,10 +503,21 @@ public class Node {
this.exclusiveTo = node.exclusiveTo;
this.reports = node.reports;
this.history = node.history;
+ this.ipAddresses = node.ipAddresses;
this.additionalIpAddresses = node.additionalIpAddresses;
- this.openStackId = node.openStackId;
+ this.additionalHostnames = node.additionalHostnames;
this.switchHostname = node.switchHostname;
this.modelName = node.modelName;
+ this.environment = node.environment;
+ }
+
+ public Builder id(String id) {
+ this.id = id;
+ return this;
+ }
+
+ public Builder hostname(String hostname) {
+ return hostname(HostName.from(hostname));
}
public Builder hostname(HostName hostname) {
@@ -378,6 +525,10 @@ public class Node {
return this;
}
+ public Builder parentHostname(String parentHostname) {
+ return parentHostname(HostName.from(parentHostname));
+ }
+
public Builder parentHostname(HostName parentHostname) {
this.parentHostname = Optional.ofNullable(parentHostname);
return this;
@@ -478,6 +629,11 @@ public class Node {
return this;
}
+ public Builder failCount(int failCount) {
+ this.failCount = failCount;
+ return this;
+ }
+
public Builder flavor(String flavor) {
this.flavor = flavor;
return this;
@@ -493,6 +649,11 @@ public class Node {
return this;
}
+ public Builder group(String group) {
+ this.group = group;
+ return this;
+ }
+
public Builder retired(boolean retired) {
this.retired = retired;
return this;
@@ -523,18 +684,23 @@ public class Node {
return this;
}
- public Builder history(List<NodeHistory> history) {
+ public Builder history(List<Event> history) {
this.history = history;
return this;
}
+ public Builder ipAddresses(Set<String> ipAdresses) {
+ this.ipAddresses = ipAdresses;
+ return this;
+ }
+
public Builder additionalIpAddresses(Set<String> additionalIpAddresses) {
this.additionalIpAddresses = additionalIpAddresses;
return this;
}
- public Builder openStackId(String openStackId) {
- this.openStackId = openStackId;
+ public Builder additionalHostnames(Set<String> additionalHostnames) {
+ this.additionalHostnames = additionalHostnames;
return this;
}
@@ -548,18 +714,26 @@ public class Node {
return this;
}
- public Builder reports(Map<String, JsonNode> reports) {
+ public Builder reports(Map<String, String> reports) {
this.reports = reports;
return this;
}
+ public Builder environment(Environment environment) {
+ this.environment = environment;
+ return this;
+ }
+
public Node build() {
- return new Node(hostname, parentHostname, state, type, resources, owner, currentVersion, wantedVersion,
+ return new Node(id, hostname, parentHostname, state, type, resources, owner, currentVersion, wantedVersion,
currentOsVersion, wantedOsVersion, currentFirmwareCheck, wantedFirmwareCheck, serviceState,
- suspendedSince, restartGeneration, wantedRestartGeneration, rebootGeneration, wantedRebootGeneration,
- cost, flavor, clusterId, clusterType, retired, wantToRetire, wantToDeprovision, wantToRebuild, reservedTo, exclusiveTo,
- wantedDockerImage, currentDockerImage, reports, history, additionalIpAddresses, openStackId, switchHostname, modelName);
+ suspendedSince, restartGeneration, wantedRestartGeneration, rebootGeneration,
+ wantedRebootGeneration, cost, failCount, flavor, clusterId, clusterType, group, retired,
+ wantToRetire, wantToDeprovision, wantToRebuild, reservedTo, exclusiveTo, wantedDockerImage,
+ currentDockerImage, reports, history, ipAddresses, additionalIpAddresses,
+ additionalHostnames, switchHostname, modelName, environment);
}
}
+
}
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 ac4ff0a80a0..3c16eac06c7 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
@@ -3,21 +3,15 @@ package com.yahoo.vespa.hosted.controller.api.integration.configserver;
import com.yahoo.component.Version;
import com.yahoo.config.provision.ApplicationId;
-import com.yahoo.config.provision.DockerImage;
import com.yahoo.config.provision.HostName;
-import com.yahoo.config.provision.NodeResources;
import com.yahoo.config.provision.NodeType;
import com.yahoo.config.provision.TenantName;
import com.yahoo.config.provision.zone.ZoneId;
-import com.yahoo.vespa.hosted.controller.api.integration.noderepository.NodeList;
-import com.yahoo.vespa.hosted.controller.api.integration.noderepository.NodeMembership;
import com.yahoo.vespa.hosted.controller.api.integration.noderepository.NodeRepositoryNode;
import com.yahoo.vespa.hosted.controller.api.integration.noderepository.NodeState;
-import com.yahoo.vespa.hosted.controller.api.integration.noderepository.OrchestratorStatus;
import java.net.URI;
import java.time.Duration;
-import java.time.Instant;
import java.util.Collection;
import java.util.List;
import java.util.Map;
@@ -26,7 +20,7 @@ import java.util.Set;
import java.util.stream.Collectors;
/**
- * A minimal interface to the node repository, providing only the operations used by the controller.
+ * Node repository interface intended for use by the controller.
*
* @author mpolden
*/
@@ -38,10 +32,7 @@ public interface NodeRepository {
void setState(ZoneId zone, NodeState nodeState, String hostname);
- NodeRepositoryNode getNode(ZoneId zone, String hostname);
-
- // TODO: Migrate any callers to list() and remove this method
- NodeList listNodes(ZoneId zone);
+ Node getNode(ZoneId zone, String hostname);
/** List all nodes in given zone */
List<Node> list(ZoneId zone, boolean includeDeprovisioned);
@@ -96,145 +87,4 @@ public interface NodeRepository {
/** Checks whether the zone has the spare capacity to remove the given hosts */
boolean isReplaceable(ZoneId zoneId, List<HostName> hostNames);
- static Node toNode(NodeRepositoryNode node) {
- var application = Optional.ofNullable(node.getOwner())
- .map(owner -> ApplicationId.from(owner.getTenant(), owner.getApplication(),
- owner.getInstance()));
- var parentHostname = Optional.ofNullable(node.getParentHostname()).map(HostName::from);
- var resources = new NodeResources(
- toDouble(node.getResources().getVcpu()),
- toDouble(node.getResources().getMemoryGb()),
- toDouble(node.getResources().getDiskGb()),
- toDouble(node.getResources().getBandwidthGbps()),
- diskSpeedFromString(node.getResources().getDiskSpeed()),
- storageTypeFromString(node.getResources().getStorageType()));
- return new Node(HostName.from(node.getHostname()),
- parentHostname,
- fromJacksonState(node.getState()),
- fromJacksonType(node.getType()),
- resources,
- application,
- versionFrom(node.getVespaVersion()),
- versionFrom(node.getWantedVespaVersion()),
- versionFrom(node.getCurrentOsVersion()),
- versionFrom(node.getWantedOsVersion()),
- Optional.ofNullable(node.getCurrentFirmwareCheck()).map(Instant::ofEpochMilli),
- Optional.ofNullable(node.getWantedFirmwareCheck()).map(Instant::ofEpochMilli),
- toServiceState(node.getOrchestratorStatus()),
- Optional.ofNullable(node.suspendedSinceMillis()).map(Instant::ofEpochMilli),
- toInt(node.getCurrentRestartGeneration()),
- toInt(node.getRestartGeneration()),
- toInt(node.getCurrentRebootGeneration()),
- toInt(node.getRebootGeneration()),
- toInt(node.getCost()),
- node.getFlavor(),
- clusterIdOf(node.getMembership()),
- clusterTypeOf(node.getMembership()),
- Optional.ofNullable(node.getMembership()).map(NodeMembership::getRetired).orElse(false),
- node.getWantToRetire(),
- node.getWantToDeprovision(),
- node.getWantToRebuild(), Optional.ofNullable(node.getReservedTo()).map(TenantName::from),
- Optional.ofNullable(node.getExclusiveTo()).map(ApplicationId::fromSerializedForm),
- dockerImageFrom(node.getWantedDockerImage()),
- dockerImageFrom(node.getCurrentDockerImage()),
- node.getReports(),
- node.getHistory(),
- node.getAdditionalIpAddresses(),
- node.getOpenStackId(),
- Optional.ofNullable(node.getSwitchHostname()),
- Optional.ofNullable(node.getModelName()));
- }
-
- private static String clusterIdOf(NodeMembership nodeMembership) {
- return nodeMembership == null ? "" : nodeMembership.clusterid;
- }
-
- private static Node.ClusterType clusterTypeOf(NodeMembership nodeMembership) {
- if (nodeMembership == null) return Node.ClusterType.unknown;
- switch (nodeMembership.clustertype) {
- case "admin": return Node.ClusterType.admin;
- case "content": return Node.ClusterType.content;
- case "container": return Node.ClusterType.container;
- case "combined": return Node.ClusterType.combined;
- }
- return Node.ClusterType.unknown;
- }
-
- // Convert Jackson type to config.provision type
- private static NodeType fromJacksonType(com.yahoo.vespa.hosted.controller.api.integration.noderepository.NodeType nodeType) {
- switch (nodeType) {
- case tenant: return NodeType.tenant;
- case host: return NodeType.host;
- case proxy: return NodeType.proxy;
- case proxyhost: return NodeType.proxyhost;
- case config: return NodeType.config;
- case confighost: return NodeType.confighost;
- case controller: return NodeType.controller;
- case controllerhost: return NodeType.controllerhost;
- default: throw new IllegalArgumentException("Unknown type: " + nodeType);
- }
- }
-
- private static com.yahoo.vespa.hosted.controller.api.integration.configserver.Node.State fromJacksonState(NodeState state) {
- switch (state) {
- case provisioned: return Node.State.provisioned;
- case ready: return Node.State.ready;
- case reserved: return Node.State.reserved;
- case active: return Node.State.active;
- case inactive: return Node.State.inactive;
- case dirty: return Node.State.dirty;
- case failed: return Node.State.failed;
- case parked: return Node.State.parked;
- case breakfixed: return Node.State.breakfixed;
- case deprovisioned: return Node.State.deprovisioned;
- }
- return Node.State.unknown;
- }
-
- private static NodeResources.DiskSpeed diskSpeedFromString(String diskSpeed) {
- if (diskSpeed == null) return NodeResources.DiskSpeed.getDefault();
- switch (diskSpeed) {
- case "fast": return NodeResources.DiskSpeed.fast;
- case "slow": return NodeResources.DiskSpeed.slow;
- case "any": return NodeResources.DiskSpeed.any;
- default: throw new IllegalArgumentException("Unknown disk speed '" + diskSpeed + "'");
- }
- }
-
- private static NodeResources.StorageType storageTypeFromString(String storageType) {
- if (storageType == null) return NodeResources.StorageType.getDefault();
- switch (storageType) {
- case "remote": return NodeResources.StorageType.remote;
- case "local": return NodeResources.StorageType.local;
- case "any": return NodeResources.StorageType.any;
- default: throw new IllegalArgumentException("Unknown storage type '" + storageType + "'");
- }
- }
-
- private static Node.ServiceState toServiceState(OrchestratorStatus orchestratorStatus) {
- switch (orchestratorStatus) {
- case ALLOWED_TO_BE_DOWN: return Node.ServiceState.allowedDown;
- case PERMANENTLY_DOWN: return Node.ServiceState.permanentlyDown;
- case NO_REMARKS: return Node.ServiceState.expectedUp;
- }
-
- return Node.ServiceState.unknown;
- }
-
- private static double toDouble(Double d) {
- return d == null ? 0 : d;
- }
-
- private static int toInt(Integer i) {
- return i == null ? 0 : i;
- }
-
- private static Version versionFrom(String s) {
- return s == null ? Version.emptyVersion : Version.fromString(s);
- }
-
- private static DockerImage dockerImageFrom(String s) {
- return s == null ? DockerImage.EMPTY : DockerImage.fromString(s);
- }
-
}
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/repair/RepairTicketReport.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/repair/RepairTicketReport.java
index c2425fe0f72..97c6222e77d 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/repair/RepairTicketReport.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/repair/RepairTicketReport.java
@@ -1,7 +1,6 @@
// 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.repair;
-import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.JsonNode;
@@ -53,8 +52,8 @@ public class RepairTicketReport {
return REPORT_ID;
}
- public static RepairTicketReport fromJsonNode(JsonNode node) {
- return uncheck(() -> objectMapper.treeToValue(node, RepairTicketReport.class));
+ public static RepairTicketReport fromJsonNode(String jsonReport) {
+ return uncheck(() -> objectMapper.readValue(jsonReport, RepairTicketReport.class));
}
public JsonNode toJsonNode() {
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/vcmr/VCMRReport.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/vcmr/VCMRReport.java
index a3c0af95053..8ebfde9f475 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/vcmr/VCMRReport.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/vcmr/VCMRReport.java
@@ -3,7 +3,6 @@ package com.yahoo.vespa.hosted.controller.api.integration.vcmr;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
-import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
@@ -69,12 +68,12 @@ public class VCMRReport {
/**
* Serialization functions - mapped to {@link Node#reports()}
*/
- public static VCMRReport fromReports(Map<String, JsonNode> reports) {
+ public static VCMRReport fromReports(Map<String, String> reports) {
var serialized = reports.get(REPORT_ID);
if (serialized == null)
return new VCMRReport();
- return uncheck(() -> objectMapper.treeToValue(serialized, VCMRReport.class));
+ return uncheck(() -> objectMapper.readValue(serialized, VCMRReport.class));
}
/**
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/ChangeManagementAssessor.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/ChangeManagementAssessor.java
index d74578d9adc..fc7b256a644 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/ChangeManagementAssessor.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/ChangeManagementAssessor.java
@@ -2,13 +2,10 @@
package com.yahoo.vespa.hosted.controller.maintenance;
import com.yahoo.config.provision.HostName;
+import com.yahoo.config.provision.NodeType;
import com.yahoo.config.provision.zone.ZoneId;
-import com.yahoo.text.Text;
import com.yahoo.vespa.hosted.controller.api.integration.configserver.Node;
import com.yahoo.vespa.hosted.controller.api.integration.configserver.NodeRepository;
-import com.yahoo.vespa.hosted.controller.api.integration.noderepository.NodeRepositoryNode;
-import com.yahoo.vespa.hosted.controller.api.integration.noderepository.NodeState;
-import com.yahoo.vespa.hosted.controller.api.integration.noderepository.NodeType;
import java.util.Collection;
import java.util.List;
@@ -16,6 +13,9 @@ import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
+/**
+ * @author smorgrav
+ */
public class ChangeManagementAssessor {
private final NodeRepository nodeRepository;
@@ -25,31 +25,31 @@ public class ChangeManagementAssessor {
}
public Assessment assessment(List<String> impactedHostnames, ZoneId zone) {
- return assessmentInner(impactedHostnames, nodeRepository.listNodes(zone).nodes(), zone);
+ return assessmentInner(impactedHostnames, nodeRepository.list(zone, false), zone);
}
- Assessment assessmentInner(List<String> impactedHostnames, List<NodeRepositoryNode> allNodes, ZoneId zone) {
+ Assessment assessmentInner(List<String> impactedHostnames, List<Node> allNodes, ZoneId zone) {
List<String> impactedParentHosts = toParentHosts(impactedHostnames, allNodes);
// Group impacted application nodes by parent host
- Map<NodeRepositoryNode, List<NodeRepositoryNode>> prParentHost = allNodes.stream()
- .filter(nodeRepositoryNode -> nodeRepositoryNode.getState() == NodeState.active) //TODO look at more states?
- .filter(node -> impactedParentHosts.contains(node.getParentHostname() == null ? "" : node.getParentHostname()))
+ Map<Node, List<Node>> prParentHost = allNodes.stream()
+ .filter(node -> node.state() == Node.State.active) //TODO look at more states?
+ .filter(node -> impactedParentHosts.contains(node.parentHostname().map(HostName::value).orElse("")))
.collect(Collectors.groupingBy(node ->
allNodes.stream()
- .filter(parent -> parent.getHostname().equals(node.getParentHostname()))
+ .filter(parent -> parent.hostname().equals(node.parentHostname().get()))
.findFirst().orElseThrow()
));
// Group nodes pr cluster
- Map<Cluster, List<NodeRepositoryNode>> prCluster = prParentHost.values()
+ Map<Cluster, List<Node>> prCluster = prParentHost.values()
.stream()
.flatMap(Collection::stream)
.collect(Collectors.groupingBy(ChangeManagementAssessor::clusterKey));
var tenantHosts = prParentHost.keySet().stream()
- .filter(node -> node.getType() == NodeType.host)
- .map(node -> HostName.from(node.getHostname()))
+ .filter(node -> node.type() == NodeType.host)
+ .map(node -> node.hostname())
.collect(Collectors.toList());
boolean allHostsReplacable = tenantHosts.isEmpty() || nodeRepository.isReplaceable(
@@ -60,7 +60,7 @@ public class ChangeManagementAssessor {
// Report assessment pr cluster
var clusterAssessments = prCluster.entrySet().stream().map((entry) -> {
Cluster cluster = entry.getKey();
- List<NodeRepositoryNode> nodes = entry.getValue();
+ List<Node> nodes = entry.getValue();
long[] totalStats = clusterStats(cluster, allNodes);
long[] impactedStats = clusterStats(cluster, nodes);
@@ -87,8 +87,8 @@ public class ChangeManagementAssessor {
var hostAssessments = prParentHost.entrySet().stream().map((entry) -> {
HostAssessment hostAssessment = new HostAssessment();
- hostAssessment.hostName = entry.getKey().getHostname();
- hostAssessment.switchName = entry.getKey().getSwitchHostname();
+ hostAssessment.hostName = entry.getKey().hostname().value();
+ hostAssessment.switchName = entry.getKey().switchHostname().orElse(null);
hostAssessment.numberOfChildren = entry.getValue().size();
//TODO: Some better heuristic for what's considered problematic
@@ -103,31 +103,31 @@ public class ChangeManagementAssessor {
return new Assessment(clusterAssessments, hostAssessments);
}
- private List<String> toParentHosts(List<String> impactedHostnames, List<NodeRepositoryNode> allNodes) {
+ private List<String> toParentHosts(List<String> impactedHostnames, List<Node> allNodes) {
return impactedHostnames.stream()
.flatMap(hostname ->
allNodes.stream()
- .filter(node -> List.of(NodeType.config, NodeType.proxy, NodeType.host).contains(node.getType()))
- .filter(node -> hostname.equals(node.getHostname()) || hostname.equals(node.getParentHostname()))
+ .filter(node -> List.of(NodeType.config, NodeType.proxy, NodeType.host).contains(node.type()))
+ .filter(node -> hostname.equals(node.hostname().value()) || hostname.equals(node.parentHostname().map(HostName::value).orElse("")))
.map(node -> {
- if (node.getType() == NodeType.host)
- return node.getHostname();
- return node.getParentHostname();
+ if (node.type() == NodeType.host)
+ return node.hostname().value();
+ return node.parentHostname().get().value();
}).findFirst().stream()
)
.collect(Collectors.toList());
}
- private static Cluster clusterKey(NodeRepositoryNode node) {
- if (node.getOwner() == null)
+ private static Cluster clusterKey(Node node) {
+ if (node.owner().isEmpty())
return Cluster.EMPTY;
- String appId = Text.format("%s:%s:%s", node.getOwner().tenant, node.getOwner().application, node.getOwner().instance);
- return new Cluster(Node.ClusterType.valueOf(node.getMembership().clustertype), node.getMembership().clusterid, appId, node.getType());
+ String appId = node.owner().get().serializedForm();
+ return new Cluster(node.clusterType(), node.clusterId(), appId, node.type());
}
- private static long[] clusterStats(Cluster cluster, List<NodeRepositoryNode> containerNodes) {
- List<NodeRepositoryNode> clusterNodes = containerNodes.stream().filter(nodeRepositoryNode -> cluster.equals(clusterKey(nodeRepositoryNode))).collect(Collectors.toList());
- long groups = clusterNodes.stream().map(nodeRepositoryNode -> nodeRepositoryNode.getMembership() != null ? nodeRepositoryNode.getMembership().group : "").distinct().count();
+ private static long[] clusterStats(Cluster cluster, List<Node> containerNodes) {
+ List<Node> clusterNodes = containerNodes.stream().filter(node -> cluster.equals(clusterKey(node))).collect(Collectors.toList());
+ long groups = clusterNodes.stream().map(Node::group).distinct().count();
return new long[] { clusterNodes.size(), groups};
}
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/VCMRMaintainer.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/VCMRMaintainer.java
index 38e10aa6750..19617a1f293 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/VCMRMaintainer.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/VCMRMaintainer.java
@@ -1,6 +1,7 @@
// 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.maintenance;
+import com.fasterxml.jackson.databind.JsonNode;
import com.yahoo.config.provision.Environment;
import com.yahoo.config.provision.NodeType;
import com.yahoo.config.provision.SystemName;
@@ -174,7 +175,7 @@ public class VCMRMaintainer extends ControllerMaintainer {
} catch (Exception e) {
logger.warning("Failed to retire host " + node.hostname() + ": " + Exceptions.toMessageString(e));
// Check if retirement actually failed
- if (!nodeRepository.getNode(changeRequest.getZoneId(), node.hostname().value()).getWantToRetire()) {
+ if (!nodeRepository.getNode(changeRequest.getZoneId(), node.hostname().value()).wantToRetire()) {
return hostAction;
}
}
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 c1e6c362c83..1a4fa3fcd79 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
@@ -880,7 +880,7 @@ public class ApplicationApiHandler extends AuditLoggingRequestHandler {
toSlime(node.resources(), nodeObject);
nodeObject.setString("clusterId", node.clusterId());
nodeObject.setString("clusterType", valueOf(node.clusterType()));
- nodeObject.setBool("down", node.history().stream().anyMatch(event -> "down".equals(event.getEvent())));
+ nodeObject.setBool("down", node.history().stream().anyMatch(event -> "down".equals(event.name())));
nodeObject.setBool("retired", node.retired() || node.wantToRetire());
nodeObject.setBool("restarting", node.wantedRestartGeneration() > node.restartGeneration());
nodeObject.setBool("rebooting", node.wantedRebootGeneration() > node.rebootGeneration());
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/deployment/InternalStepRunnerTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/deployment/InternalStepRunnerTest.java
index d8bddac4187..5e79f1e4d12 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/deployment/InternalStepRunnerTest.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/deployment/InternalStepRunnerTest.java
@@ -197,10 +197,10 @@ public class InternalStepRunnerTest {
app.instanceId()).iterator().next();
tester.clock().advance(InternalStepRunner.Timeouts.of(system()).noNodesDown().minus(Duration.ofSeconds(1)));
tester.configServer().nodeRepository().putNodes(JobType.systemTest.zone(system()),
- new Node.Builder(systemTestNode)
- .serviceState(Node.ServiceState.allowedDown)
- .suspendedSince(tester.clock().instant())
- .build());
+ Node.builder(systemTestNode)
+ .serviceState(Node.ServiceState.allowedDown)
+ .suspendedSince(tester.clock().instant())
+ .build());
tester.runner().run();
assertEquals(unfinished, tester.jobs().last(app.instanceId(), JobType.systemTest).get().stepStatuses().get(Step.installReal));
assertEquals(unfinished, tester.jobs().last(app.instanceId(), JobType.stagingTest).get().stepStatuses().get(Step.installInitialReal));
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 92c8cbc4889..c66cc3710c9 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
@@ -63,10 +63,7 @@ import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;
-import java.util.concurrent.atomic.AtomicReference;
-import java.util.function.BooleanSupplier;
import java.util.function.Consumer;
-import java.util.function.Function;
import java.util.function.Supplier;
import java.util.logging.Level;
import java.util.stream.Collectors;
@@ -138,23 +135,23 @@ public class ConfigServerMock extends AbstractComponent implements ConfigServer
Node parent = nodeRepository().list(zone, SystemApplication.tenantHost.id()).stream().findAny()
.orElseThrow(() -> new IllegalStateException("No parent hosts in " + zone));
- nodeRepository().putNodes(zone, new Node.Builder().hostname(hostFor(application, zone))
- .state(Node.State.reserved)
- .type(NodeType.tenant)
- .owner(application)
- .parentHostname(parent.hostname())
- .currentVersion(initialVersion)
- .wantedVersion(initialVersion)
- .currentDockerImage(initialDockerImage)
- .wantedDockerImage(initialDockerImage)
- .currentOsVersion(Version.emptyVersion)
- .wantedOsVersion(Version.emptyVersion)
- .resources(new NodeResources(2, 8, 50, 1, slow, remote))
- .serviceState(Node.ServiceState.unorchestrated)
- .flavor("d-2-8-50")
- .clusterId(clusterId.value())
- .clusterType(Node.ClusterType.container)
- .build());
+ nodeRepository().putNodes(zone, Node.builder().hostname(hostFor(application, zone))
+ .state(Node.State.reserved)
+ .type(NodeType.tenant)
+ .owner(application)
+ .parentHostname(parent.hostname())
+ .currentVersion(initialVersion)
+ .wantedVersion(initialVersion)
+ .currentDockerImage(initialDockerImage)
+ .wantedDockerImage(initialDockerImage)
+ .currentOsVersion(Version.emptyVersion)
+ .wantedOsVersion(Version.emptyVersion)
+ .resources(new NodeResources(2, 8, 50, 1, slow, remote))
+ .serviceState(Node.ServiceState.unorchestrated)
+ .flavor("d-2-8-50")
+ .clusterId(clusterId.value())
+ .clusterType(Node.ClusterType.container)
+ .build());
}
public HostName hostFor(ApplicationId application, ZoneId zone) {
@@ -174,16 +171,16 @@ public class ConfigServerMock extends AbstractComponent implements ConfigServer
for (ZoneId zone : zones) {
for (SystemApplication application : applications) {
for (int i = 1; i <= 3; i++) {
- Node node = new Node.Builder()
- .hostname(HostName.from("node-" + i + "-" + application.id().application()
+ Node node = Node.builder()
+ .hostname(HostName.from("node-" + i + "-" + application.id().application()
.value() + "-" + zone.value()))
- .state(Node.State.active)
- .type(application.nodeType())
- .owner(application.id())
- .currentVersion(initialVersion).wantedVersion(initialVersion)
- .currentOsVersion(Version.emptyVersion).wantedOsVersion(Version.emptyVersion)
- .build();
- nodeRepository().putNode(zone, node);
+ .state(Node.State.active)
+ .type(application.nodeType())
+ .owner(application.id())
+ .currentVersion(initialVersion).wantedVersion(initialVersion)
+ .currentOsVersion(Version.emptyVersion).wantedOsVersion(Version.emptyVersion)
+ .build();
+ nodeRepository().putNodes(zone, node);
}
convergeServices(application.id(), zone);
}
@@ -244,9 +241,9 @@ public class ConfigServerMock extends AbstractComponent implements ConfigServer
for (var node : nodes) {
Node newNode;
if (osVersion) {
- newNode = new Node.Builder(node).currentOsVersion(version).wantedOsVersion(version).build();
+ newNode = Node.builder(node).currentOsVersion(version).wantedOsVersion(version).build();
} else {
- newNode = new Node.Builder(node).currentVersion(version).wantedVersion(version).build();
+ newNode = Node.builder(node).currentVersion(version).wantedVersion(version).build();
}
nodeRepository().putNodes(zone, newNode);
}
@@ -410,10 +407,10 @@ public class ConfigServerMock extends AbstractComponent implements ConfigServer
application.activate();
List<Node> nodes = nodeRepository.list(id.zoneId(), id.applicationId());
for (Node node : nodes) {
- nodeRepository.putNodes(id.zoneId(), new Node.Builder(node)
- .state(Node.State.active)
- .wantedVersion(application.version().get())
- .build());
+ nodeRepository.putNodes(id.zoneId(), Node.builder(node)
+ .state(Node.State.active)
+ .wantedVersion(application.version().get())
+ .build());
}
serviceStatus.put(id, new ServiceConvergence(id.applicationId(),
id.zoneId(),
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 4079591730d..b16817c0f3d 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
@@ -1,7 +1,6 @@
// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.hosted.controller.integration;
-import com.fasterxml.jackson.databind.JsonNode;
import com.yahoo.collections.Pair;
import com.yahoo.component.Version;
import com.yahoo.config.provision.ApplicationId;
@@ -18,13 +17,11 @@ 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;
import com.yahoo.vespa.hosted.controller.api.integration.noderepository.NodeRepositoryNode;
import com.yahoo.vespa.hosted.controller.api.integration.noderepository.NodeState;
import java.net.URI;
import java.time.Duration;
-import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
@@ -33,7 +30,6 @@ import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.Optional;
-import java.util.function.Function;
import java.util.function.UnaryOperator;
import java.util.stream.Collectors;
@@ -50,115 +46,12 @@ public class NodeRepositoryMock implements NodeRepository {
private final Map<DeploymentId, Pair<Double, Double>> trafficFractions = new HashMap<>();
private final Map<ZoneId, Map<TenantName, URI>> archiveUris = new HashMap<>();
- // A separate/alternative list of NodeRepositoryNode nodes.
- // Methods operating with Node and NodeRepositoryNode lives separate lives.
- private final Map<ZoneId, List<NodeRepositoryNode>> nodeRepoNodes = new HashMap<>();
-
private boolean allowPatching = false;
private boolean hasSpareCapacity = false;
- /** Add or update given nodes in zone */
- public void putNodes(ZoneId zone, List<Node> nodes) {
- Map<HostName, Node> zoneNodes = nodeRepository.computeIfAbsent(zone, (k) -> new HashMap<>());
- for (var node : nodes) {
- zoneNodes.put(node.hostname(), node);
- }
- }
-
- public void putNode(ZoneId zone, Node node) {
- nodeRepository.computeIfAbsent(zone, (k) -> new HashMap<>()).put(node.hostname(), node);
- }
-
- public void putApplication(ZoneId zone, Application application) {
- applications.putIfAbsent(zone, new HashMap<>());
- applications.get(zone).put(application.id(), application);
- }
-
- @Override
- public NodeRepoStats getStats(ZoneId zone) {
- List<ApplicationStats> 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<Double, Double> getTrafficFraction(ApplicationId application, ZoneId zone) {
- return trafficFractions.get(new DeploymentId(application, zone));
- }
-
- /** Add or update given node in zone */
- public void putNodes(ZoneId zone, Node node) {
- putNodes(zone, Collections.singletonList(node));
- }
-
- /** Remove given nodes from zone */
- public void removeNodes(ZoneId zone, List<Node> nodes) {
- nodes.forEach(node -> nodeRepository.get(zone).remove(node.hostname()));
- }
-
- /** Remove all nodes in all zones */
- public void clear() {
- nodeRepository.clear();
- nodeRepoNodes.clear();
- }
-
- /** Replace nodes in zone with given nodes */
- public void setNodes(ZoneId zone, List<Node> nodes) {
- nodeRepository.put(zone, nodes.stream().collect(Collectors.toMap(Node::hostname, Function.identity())));
- }
-
- public Node require(HostName hostName) {
- return nodeRepository.values().stream()
- .map(zoneNodes -> zoneNodes.get(hostName))
- .filter(Objects::nonNull)
- .findFirst()
- .orElseThrow(() -> new NoSuchElementException("No node with the hostname " + hostName + " is known."));
- }
-
- /** Replace nodes in zone with a fixed set of nodes */
- public void setFixedNodes(ZoneId zone) {
- var nodeA = new Node.Builder()
- .hostname(HostName.from("hostA"))
- .parentHostname(HostName.from("parentHostA"))
- .state(Node.State.active)
- .type(NodeType.tenant)
- .owner(ApplicationId.from("tenant1", "app1", "default"))
- .currentVersion(Version.fromString("7.42"))
- .wantedVersion(Version.fromString("7.42"))
- .currentOsVersion(Version.fromString("7.6"))
- .wantedOsVersion(Version.fromString("7.6"))
- .serviceState(Node.ServiceState.expectedUp)
- .resources(new NodeResources(24, 24, 500, 1))
- .clusterId("clusterA")
- .clusterType(Node.ClusterType.container)
- .exclusiveTo(ApplicationId.from("t1", "a1", "i1"))
- .build();
- var nodeB = new Node.Builder()
- .hostname(HostName.from("hostB"))
- .parentHostname(HostName.from("parentHostB"))
- .state(Node.State.active)
- .type(NodeType.tenant)
- .owner(ApplicationId.from("tenant2", "app2", "default"))
- .currentVersion(Version.fromString("7.42"))
- .wantedVersion(Version.fromString("7.42"))
- .currentOsVersion(Version.fromString("7.6"))
- .wantedOsVersion(Version.fromString("7.6"))
- .serviceState(Node.ServiceState.expectedUp)
- .resources(new NodeResources(40, 24, 500, 1))
- .cost(20)
- .clusterId("clusterB")
- .clusterType(Node.ClusterType.container)
- .build();
- setNodes(zone, List.of(nodeA, nodeB));
- }
-
@Override
public void addNodes(ZoneId zone, Collection<NodeRepositoryNode> nodes) {
- nodeRepoNodes.put(zone, new ArrayList<>(nodes));
+ throw new UnsupportedOperationException();
}
@Override
@@ -171,23 +64,18 @@ public class NodeRepositoryMock implements NodeRepository {
var existing = list(zone, List.of(HostName.from(hostName)));
if (existing.size() != 1) throw new IllegalArgumentException("Node " + hostName + " not found in " + zone);
- var node = new Node.Builder(existing.get(0))
- .state(Node.State.valueOf(nodeState.name()))
- .build();
+ var node = Node.builder(existing.get(0))
+ .state(Node.State.valueOf(nodeState.name()))
+ .build();
putNodes(zone, node);
}
@Override
- public NodeRepositoryNode getNode(ZoneId zone, String hostname) {
+ public Node getNode(ZoneId zone, String hostname) {
throw new UnsupportedOperationException();
}
@Override
- public NodeList listNodes(ZoneId zone) {
- return new NodeList(nodeRepoNodes.get(zone));
- }
-
- @Override
public List<Node> list(ZoneId zone, boolean includeDeprovisioned) {
return List.copyOf(nodeRepository.getOrDefault(zone, Map.of()).values());
}
@@ -218,6 +106,18 @@ public class NodeRepositoryMock implements NodeRepository {
}
@Override
+ public NodeRepoStats getStats(ZoneId zone) {
+ List<ApplicationStats> 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);
+ }
+
+ @Override
public Map<TenantName, URI> getArchiveUris(ZoneId zone) {
return Map.copyOf(archiveUris.getOrDefault(zone, Map.of()));
}
@@ -244,7 +144,7 @@ public class NodeRepositoryMock implements NodeRepository {
nodeRepository.getOrDefault(zone, Map.of()).values()
.stream()
.filter(node -> node.type() == type)
- .map(node -> new Node.Builder(node).wantedVersion(version).build())
+ .map(node -> Node.builder(node).wantedVersion(version).build())
.forEach(node -> putNodes(zone, node));
}
@@ -261,7 +161,7 @@ public class NodeRepositoryMock implements NodeRepository {
nodeRepository.getOrDefault(zone, Map.of()).values()
.stream()
.filter(node -> node.type() == type)
- .map(node -> new Node.Builder(node).wantedOsVersion(version).build())
+ .map(node -> Node.builder(node).wantedOsVersion(version).build())
.forEach(node -> putNodes(zone, node));
}
@@ -290,15 +190,20 @@ public class NodeRepositoryMock implements NodeRepository {
if (existing.size() != 1) throw new IllegalArgumentException("Node " + hostName + " not found in " + zoneId);
// Note: Only supports switchHostname, modelName and wantToRetire
- Node.Builder newNode = new Node.Builder(existing.get(0));
+ Node.Builder newNode = Node.builder(existing.get(0));
if (node.getSwitchHostname() != null)
newNode.switchHostname(node.getSwitchHostname());
if (node.getModelName() != null)
newNode.modelName(node.getModelName());
if (node.getWantToRetire() != null)
newNode.wantToRetire(node.getWantToRetire());
- if (!node.getReports().isEmpty())
- newNode.reports(node.getReports());
+
+ Map<String, String> reports = new HashMap<>();
+ for (var kv : node.getReports().entrySet()) {
+ if (kv.getValue() == null) continue; // Null value clears a report
+ reports.put(kv.getKey(), kv.getValue().toString());
+ }
+ newNode.reports(reports);
putNodes(zoneId, newNode.build());
}
@@ -313,6 +218,83 @@ public class NodeRepositoryMock implements NodeRepository {
return hasSpareCapacity;
}
+ /** Add or update given nodes in zone */
+ public void putNodes(ZoneId zone, List<Node> nodes) {
+ Map<HostName, Node> zoneNodes = nodeRepository.computeIfAbsent(zone, (k) -> new HashMap<>());
+ for (var node : nodes) {
+ zoneNodes.put(node.hostname(), node);
+ }
+ }
+
+ /** Add or update given node in zone */
+ public void putNodes(ZoneId zone, Node node) {
+ putNodes(zone, List.of(node));
+ }
+
+ public void putApplication(ZoneId zone, Application application) {
+ applications.computeIfAbsent(zone, (k) -> new HashMap<>())
+ .put(application.id(), application);
+ }
+
+ public Pair<Double, Double> getTrafficFraction(ApplicationId application, ZoneId zone) {
+ return trafficFractions.get(new DeploymentId(application, zone));
+ }
+
+ /** Remove given nodes from zone */
+ public void removeNodes(ZoneId zone, List<Node> nodes) {
+ nodes.forEach(node -> nodeRepository.get(zone).remove(node.hostname()));
+ }
+
+ /** Remove all nodes in all zones */
+ public void clear() {
+ nodeRepository.clear();
+ }
+
+ public Node require(HostName hostName) {
+ return nodeRepository.values().stream()
+ .map(zoneNodes -> zoneNodes.get(hostName))
+ .filter(Objects::nonNull)
+ .findFirst()
+ .orElseThrow(() -> new NoSuchElementException("No node with the hostname " + hostName + " is known."));
+ }
+
+ /** Add a fixed set of nodes to given zone */
+ public void addFixedNodes(ZoneId zone) {
+ var nodeA = Node.builder()
+ .hostname(HostName.from("hostA"))
+ .parentHostname(HostName.from("parentHostA"))
+ .state(Node.State.active)
+ .type(NodeType.tenant)
+ .owner(ApplicationId.from("tenant1", "app1", "default"))
+ .currentVersion(Version.fromString("7.42"))
+ .wantedVersion(Version.fromString("7.42"))
+ .currentOsVersion(Version.fromString("7.6"))
+ .wantedOsVersion(Version.fromString("7.6"))
+ .serviceState(Node.ServiceState.expectedUp)
+ .resources(new NodeResources(24, 24, 500, 1))
+ .clusterId("clusterA")
+ .clusterType(Node.ClusterType.container)
+ .exclusiveTo(ApplicationId.from("t1", "a1", "i1"))
+ .build();
+ var nodeB = Node.builder()
+ .hostname(HostName.from("hostB"))
+ .parentHostname(HostName.from("parentHostB"))
+ .state(Node.State.active)
+ .type(NodeType.tenant)
+ .owner(ApplicationId.from("tenant2", "app2", "default"))
+ .currentVersion(Version.fromString("7.42"))
+ .wantedVersion(Version.fromString("7.42"))
+ .currentOsVersion(Version.fromString("7.6"))
+ .wantedOsVersion(Version.fromString("7.6"))
+ .serviceState(Node.ServiceState.expectedUp)
+ .resources(new NodeResources(40, 24, 500, 1))
+ .cost(20)
+ .clusterId("clusterB")
+ .clusterType(Node.ClusterType.container)
+ .build();
+ putNodes(zone, List.of(nodeA, nodeB));
+ }
+
public Optional<Duration> osUpgradeBudget(ZoneId zone, NodeType type, Version version) {
return Optional.ofNullable(osUpgradeBudgets.get(Objects.hash(zone, type, version)));
}
@@ -320,10 +302,10 @@ public class NodeRepositoryMock implements NodeRepository {
public void doUpgrade(DeploymentId deployment, Optional<HostName> hostName, Version version) {
modifyNodes(deployment, hostName, node -> {
assert node.wantedVersion().equals(version);
- return new Node.Builder(node)
- .currentVersion(version)
- .currentDockerImage(node.wantedDockerImage())
- .build();
+ return Node.builder(node)
+ .currentVersion(version)
+ .currentDockerImage(node.wantedDockerImage())
+ .build();
});
}
@@ -336,23 +318,29 @@ public class NodeRepositoryMock implements NodeRepository {
}
public void requestRestart(DeploymentId deployment, Optional<HostName> hostname) {
- modifyNodes(deployment, hostname, node -> new Node.Builder(node).wantedRestartGeneration(node.wantedRestartGeneration() + 1).build());
+ modifyNodes(deployment, hostname, node -> Node.builder(node).wantedRestartGeneration(node.wantedRestartGeneration() + 1).build());
}
public void doRestart(DeploymentId deployment, Optional<HostName> hostname) {
- modifyNodes(deployment, hostname, node -> new Node.Builder(node).restartGeneration(node.restartGeneration() + 1).build());
+ modifyNodes(deployment, hostname, node -> Node.builder(node).restartGeneration(node.restartGeneration() + 1).build());
}
public void requestReboot(DeploymentId deployment, Optional<HostName> hostname) {
- modifyNodes(deployment, hostname, node -> new Node.Builder(node).wantedRebootGeneration(node.wantedRebootGeneration() + 1).build());
+ modifyNodes(deployment, hostname, node -> Node.builder(node).wantedRebootGeneration(node.wantedRebootGeneration() + 1).build());
}
public void doReboot(DeploymentId deployment, Optional<HostName> hostname) {
- modifyNodes(deployment, hostname, node -> new Node.Builder(node).rebootGeneration(node.rebootGeneration() + 1).build());
+ modifyNodes(deployment, hostname, node -> Node.builder(node).rebootGeneration(node.rebootGeneration() + 1).build());
}
- public void addReport(ZoneId zoneId, HostName hostName, String reportId, JsonNode report) {
- nodeRepository.get(zoneId).get(hostName).reports().put(reportId, report);
+ public void addReport(ZoneId zoneId, HostName hostName, String reportId, String report) {
+ Node node = nodeRepository.getOrDefault(zoneId, Map.of()).get(hostName);
+ if (node == null) throw new IllegalArgumentException("No node named " + hostName + " in " + zoneId);
+
+ Map<String, String> reports = new HashMap<>(node.reports());
+ reports.put(reportId, report);
+ Node newNode = Node.builder(node).reports(reports).build();
+ putNodes(zoneId, newNode);
}
public NodeRepositoryMock allowPatching(boolean allowPatching) {
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/ChangeManagementAssessorTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/ChangeManagementAssessorTest.java
index 476d2465202..01c16139667 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/ChangeManagementAssessorTest.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/ChangeManagementAssessorTest.java
@@ -2,32 +2,32 @@
package com.yahoo.vespa.hosted.controller.maintenance;
+import com.yahoo.config.provision.ApplicationId;
+import com.yahoo.config.provision.NodeType;
import com.yahoo.config.provision.zone.ZoneId;
-import com.yahoo.vespa.hosted.controller.api.integration.noderepository.NodeMembership;
-import com.yahoo.vespa.hosted.controller.api.integration.noderepository.NodeOwner;
-import com.yahoo.vespa.hosted.controller.api.integration.noderepository.NodeRepositoryNode;
-import com.yahoo.vespa.hosted.controller.api.integration.noderepository.NodeState;
-import com.yahoo.vespa.hosted.controller.api.integration.noderepository.NodeType;
+import com.yahoo.vespa.hosted.controller.api.integration.configserver.Node;
import com.yahoo.vespa.hosted.controller.integration.NodeRepositoryMock;
import org.junit.Test;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
+/**
+ * @author smorgrav
+ */
public class ChangeManagementAssessorTest {
- private ChangeManagementAssessor changeManagementAssessor = new ChangeManagementAssessor(new NodeRepositoryMock());
+ private final ChangeManagementAssessor changeManagementAssessor = new ChangeManagementAssessor(new NodeRepositoryMock());
@Test
public void empty_input_variations() {
ZoneId zone = ZoneId.from("prod", "eu-trd");
List<String> hostNames = new ArrayList<>();
- List<NodeRepositoryNode> allNodesInZone = new ArrayList<>();
+ List<Node> allNodesInZone = new ArrayList<>();
// Both zone and hostnames are empty
ChangeManagementAssessor.Assessment assessment
@@ -39,7 +39,7 @@ public class ChangeManagementAssessorTest {
public void one_host_one_cluster_no_groups() {
ZoneId zone = ZoneId.from("prod", "eu-trd");
List<String> hostNames = Collections.singletonList("host1");
- List<NodeRepositoryNode> allNodesInZone = new ArrayList<>();
+ List<Node> allNodesInZone = new ArrayList<>();
allNodesInZone.add(createNode("node1", "host1", "default", 0 ));
allNodesInZone.add(createNode("node2", "host1", "default", 0 ));
allNodesInZone.add(createNode("node3", "host1", "default", 0 ));
@@ -69,8 +69,8 @@ public class ChangeManagementAssessorTest {
@Test
public void one_of_two_groups_in_one_of_two_clusters() {
ZoneId zone = ZoneId.from("prod", "eu-trd");
- List<String> hostNames = Arrays.asList("host1", "host2", "host5");
- List<NodeRepositoryNode> allNodesInZone = new ArrayList<>();
+ List<String> hostNames = List.of("host1", "host2", "host5");
+ List<Node> allNodesInZone = new ArrayList<>();
// Two impacted nodes on host1
allNodesInZone.add(createNode("node1", "host1", "default", 0 ));
@@ -123,8 +123,8 @@ public class ChangeManagementAssessorTest {
@Test
public void two_config_nodes() {
var zone = ZoneId.from("prod", "eu-trd");
- var hostNames = Arrays.asList("config1", "config2");
- var allNodesInZone = new ArrayList<NodeRepositoryNode>();
+ var hostNames = List.of("config1", "config2");
+ var allNodesInZone = new ArrayList<Node>();
// Add config nodes and parents
allNodesInZone.add(createNode("config1", "confighost1", "config", 0, NodeType.config));
@@ -141,8 +141,8 @@ public class ChangeManagementAssessorTest {
@Test
public void one_of_three_proxy_nodes() {
var zone = ZoneId.from("prod", "eu-trd");
- var hostNames = Arrays.asList("routing1");
- var allNodesInZone = new ArrayList<NodeRepositoryNode>();
+ var hostNames = List.of("routing1");
+ var allNodesInZone = new ArrayList<Node>();
// Add routing nodes and parents
allNodesInZone.add(createNode("routing1", "parentrouting1", "routing", 0, NodeType.proxy));
@@ -156,47 +156,33 @@ public class ChangeManagementAssessorTest {
assertEquals("33% of routing nodes impacted. Consider reprovisioning if too many", assessment.get(0).impact);
}
- private NodeOwner createOwner() {
- NodeOwner owner = new NodeOwner();
- owner.tenant = "mytenant";
- owner.application = "myapp";
- owner.instance = "default";
- return owner;
- }
-
- private NodeMembership createMembership(String clusterId, int group) {
- NodeMembership membership = new NodeMembership();
- membership.group = "" + group;
- membership.clusterid = clusterId;
- membership.clustertype = "content";
- membership.index = 2;
- membership.retired = false;
- return membership;
- }
-
- private NodeRepositoryNode createNode(String nodename, String hostname, String clusterId, int group) {
+ private Node createNode(String nodename, String hostname, String clusterId, int group) {
return createNode(nodename, hostname, clusterId, group, NodeType.tenant);
}
- private NodeRepositoryNode createNode(String nodename, String hostname, String clusterId, int group, NodeType nodeType) {
- NodeRepositoryNode node = new NodeRepositoryNode();
- node.setHostname(nodename);
- node.setParentHostname(hostname);
- node.setState(NodeState.active);
- node.setOwner(createOwner());
- node.setMembership(createMembership(clusterId, group));
- node.setType(nodeType);
-
- return node;
+ private Node createNode(String nodename, String hostname, String clusterId, int group, NodeType nodeType) {
+ return Node.builder().hostname(nodename)
+ .parentHostname(hostname)
+ .state(Node.State.active)
+ .owner(ApplicationId.from("mytenant", "myapp", "default"))
+ .group(String.valueOf(group))
+ .clusterId(clusterId)
+ .clusterType(Node.ClusterType.content)
+ .type(nodeType)
+ .build();
}
- private NodeRepositoryNode createHost(String hostname, NodeType nodeType) {
- NodeRepositoryNode node = new NodeRepositoryNode();
- node.setHostname(hostname);
- node.setSwitchHostname("switch1");
- node.setType(nodeType);
- node.setOwner(createOwner());
- node.setMembership(createMembership(nodeType.name(), 0));
- return node;
+ private Node createHost(String hostname, NodeType nodeType) {
+ return Node.builder()
+ .hostname(hostname)
+ .switchHostname("switch1")
+ .state(Node.State.active)
+ .owner(ApplicationId.from("mytenant", "myapp", "default"))
+ .group(String.valueOf(0))
+ .clusterId(nodeType.name())
+ .clusterType(Node.ClusterType.content)
+ .type(nodeType)
+ .build();
}
+
}
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/CloudEventReporterTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/CloudEventReporterTest.java
index 680743055c9..e838a693be1 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/CloudEventReporterTest.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/CloudEventReporterTest.java
@@ -121,10 +121,10 @@ public class CloudEventReporterTest {
}
private Node createNode(String hostname, NodeType nodeType) {
- return new Node.Builder()
- .hostname(HostName.from(hostname))
- .type(nodeType)
- .build();
+ return Node.builder()
+ .hostname(HostName.from(hostname))
+ .type(nodeType)
+ .build();
}
private Set<String> getHostnames(ZoneId zoneId) {
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/CostReportMaintainerTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/CostReportMaintainerTest.java
index cbffd6d610f..d78b48c362a 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/CostReportMaintainerTest.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/CostReportMaintainerTest.java
@@ -54,7 +54,7 @@ public class CostReportMaintainerTest {
private void addNodes() {
for (var zone : tester.zoneRegistry().zones().all().zones()) {
- tester.configServer().nodeRepository().setFixedNodes(zone.getId());
+ tester.configServer().nodeRepository().addFixedNodes(zone.getId());
}
}
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/HostInfoUpdaterTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/HostInfoUpdaterTest.java
index 0baee28143c..56f8de494f0 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/HostInfoUpdaterTest.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/HostInfoUpdaterTest.java
@@ -83,12 +83,12 @@ public class HostInfoUpdaterTest {
// Updates node registered under a different hostname
ZoneId zone = tester.zoneRegistry().zones().controllerUpgraded().all().ids().get(0);
String hostnameSuffix = ".prod." + zone.value();
- Node configNode = new Node.Builder().hostname(HostName.from("cfg3" + hostnameSuffix))
- .type(NodeType.config)
- .build();
- Node configHost = new Node.Builder().hostname(HostName.from("cfghost3" + hostnameSuffix))
- .type(NodeType.confighost)
- .build();
+ Node configNode = Node.builder().hostname(HostName.from("cfg3" + hostnameSuffix))
+ .type(NodeType.config)
+ .build();
+ Node configHost = Node.builder().hostname(HostName.from("cfghost3" + hostnameSuffix))
+ .type(NodeType.confighost)
+ .build();
tester.serviceRegistry().configServer().nodeRepository().putNodes(zone, List.of(configNode, configHost));
String switchHostname = switchHostname(configHost);
NodeEntity configNodeEntity = new NodeEntity("cfg3" + hostnameSuffix, "RD350G", "Lenovo", switchHostname);
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/MetricsReporterTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/MetricsReporterTest.java
index 29c5573a1f5..3789777a8fc 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/MetricsReporterTest.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/MetricsReporterTest.java
@@ -28,7 +28,6 @@ import org.junit.Test;
import java.time.Duration;
import java.util.Comparator;
import java.util.List;
-import java.util.Map;
import java.util.Set;
import java.util.function.UnaryOperator;
import java.util.stream.Collectors;
@@ -546,7 +545,7 @@ public class MetricsReporterTest {
ControllerTester tester) {
var currentNodes = getNodes(zone, nodes, tester);
var updatedNodes = currentNodes.stream()
- .map(node -> builderOps.apply(new Node.Builder(node)).build())
+ .map(node -> builderOps.apply(Node.builder(node)).build())
.collect(Collectors.toList());
tester.configServer().nodeRepository().putNodes(zone, updatedNodes);
}
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/OsUpgraderTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/OsUpgraderTest.java
index c29e10ab643..eca000ff969 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/OsUpgraderTest.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/OsUpgraderTest.java
@@ -273,7 +273,7 @@ public class OsUpgraderTest {
throw new IllegalArgumentException("No nodes allocated to " + application.id());
}
Node node = nodes.get(0);
- nodeRepository().putNodes(zone.getVirtualId(), new Node.Builder(node).state(Node.State.failed).build());
+ nodeRepository().putNodes(zone.getVirtualId(), Node.builder(node).state(Node.State.failed).build());
}
/** Simulate OS upgrade of nodes allocated to application. In a real system this is done by the node itself */
@@ -285,9 +285,9 @@ public class OsUpgraderTest {
assertWanted(wantedVersion, application, zones);
for (ZoneApi zone : zones) {
for (Node node : nodesRequiredToUpgrade(zone, application)) {
- nodeRepository().putNodes(zone.getVirtualId(), new Node.Builder(node).wantedOsVersion(version)
- .currentOsVersion(version)
- .build());
+ nodeRepository().putNodes(zone.getVirtualId(), Node.builder(node).wantedOsVersion(version)
+ .currentOsVersion(version)
+ .build());
}
assertCurrent(version, application, zone);
}
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/ResourceMeterMaintainerTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/ResourceMeterMaintainerTest.java
index e61516cbb1a..5ef64b460b9 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/ResourceMeterMaintainerTest.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/ResourceMeterMaintainerTest.java
@@ -114,8 +114,8 @@ public class ResourceMeterMaintainerTest {
ZoneApiMock zone1 = ZoneApiMock.newBuilder().withId("prod.region-2").build();
ZoneApiMock zone2 = ZoneApiMock.newBuilder().withId("test.region-3").build();
tester.zoneRegistry().setZones(zone1, zone2);
- tester.configServer().nodeRepository().setFixedNodes(zone1.getId());
- tester.configServer().nodeRepository().setFixedNodes(zone2.getId());
+ tester.configServer().nodeRepository().addFixedNodes(zone1.getId());
+ tester.configServer().nodeRepository().addFixedNodes(zone2.getId());
tester.configServer().nodeRepository().putNodes(zone1.getId(), createNodes());
}
@@ -126,21 +126,21 @@ public class ResourceMeterMaintainerTest {
Node.State.failed,
Node.State.parked,
Node.State.active)
- .map(state -> new Node.Builder()
- .hostname(HostName.from("host" + state))
- .parentHostname(HostName.from("parenthost" + state))
- .state(state)
- .type(NodeType.tenant)
- .owner(ApplicationId.from("tenant1", "app1", "default"))
- .currentVersion(Version.fromString("7.42"))
- .wantedVersion(Version.fromString("7.42"))
- .currentOsVersion(Version.fromString("7.6"))
- .wantedOsVersion(Version.fromString("7.6"))
- .serviceState(Node.ServiceState.expectedUp)
- .resources(new NodeResources(24, 24, 500, 1))
- .clusterId("clusterA")
- .clusterType(state == Node.State.active ? Node.ClusterType.admin : Node.ClusterType.container)
- .build())
+ .map(state -> Node.builder()
+ .hostname(HostName.from("host" + state))
+ .parentHostname(HostName.from("parenthost" + state))
+ .state(state)
+ .type(NodeType.tenant)
+ .owner(ApplicationId.from("tenant1", "app1", "default"))
+ .currentVersion(Version.fromString("7.42"))
+ .wantedVersion(Version.fromString("7.42"))
+ .currentOsVersion(Version.fromString("7.6"))
+ .wantedOsVersion(Version.fromString("7.6"))
+ .serviceState(Node.ServiceState.expectedUp)
+ .resources(new NodeResources(24, 24, 500, 1))
+ .clusterId("clusterA")
+ .clusterType(state == Node.State.active ? Node.ClusterType.admin : Node.ClusterType.container)
+ .build())
.collect(Collectors.toUnmodifiableList());
}
}
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/ResourceTagMaintainerTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/ResourceTagMaintainerTest.java
index 516c28ab5cd..a90c8a9593b 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/ResourceTagMaintainerTest.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/ResourceTagMaintainerTest.java
@@ -15,7 +15,6 @@ import org.junit.Test;
import java.time.Duration;
import java.util.List;
import java.util.Map;
-import java.util.Optional;
import static com.yahoo.vespa.hosted.controller.maintenance.ResourceTagMaintainer.SHARED_HOST_APPLICATION;
import static org.junit.Assert.assertEquals;
@@ -25,7 +24,7 @@ import static org.junit.Assert.assertEquals;
*/
public class ResourceTagMaintainerTest {
- final ControllerTester tester = new ControllerTester();
+ private final ControllerTester tester = new ControllerTester();
@Test
public void maintain() {
@@ -51,24 +50,24 @@ public class ResourceTagMaintainerTest {
}
public void setNodes(ZoneId zone) {
- var hostA = new Node.Builder()
- .hostname(HostName.from("parentHostA." + zone.value()))
- .type(NodeType.host)
- .owner(ApplicationId.from(SystemApplication.TENANT.value(), "tenant-host", "default"))
- .exclusiveTo(ApplicationId.from("t1", "a1", "i1"))
- .build();
- var nodeA = new Node.Builder()
- .hostname(HostName.from("hostA." + zone.value()))
- .type(NodeType.tenant)
- .parentHostname(HostName.from("parentHostA." + zone.value()))
- .owner(ApplicationId.from("tenant1", "app1", "default"))
- .build();
- var hostB = new Node.Builder()
- .hostname(HostName.from("parentHostB." + zone.value()))
- .type(NodeType.host)
- .owner(ApplicationId.from(SystemApplication.TENANT.value(), "tenant-host", "default"))
- .build();
- tester.configServer().nodeRepository().setNodes(zone, List.of(hostA, nodeA, hostB));
+ var hostA = Node.builder()
+ .hostname(HostName.from("parentHostA." + zone.value()))
+ .type(NodeType.host)
+ .owner(ApplicationId.from(SystemApplication.TENANT.value(), "tenant-host", "default"))
+ .exclusiveTo(ApplicationId.from("t1", "a1", "i1"))
+ .build();
+ var nodeA = Node.builder()
+ .hostname(HostName.from("hostA." + zone.value()))
+ .type(NodeType.tenant)
+ .parentHostname(HostName.from("parentHostA." + zone.value()))
+ .owner(ApplicationId.from("tenant1", "app1", "default"))
+ .build();
+ var hostB = Node.builder()
+ .hostname(HostName.from("parentHostB." + zone.value()))
+ .type(NodeType.host)
+ .owner(ApplicationId.from(SystemApplication.TENANT.value(), "tenant-host", "default"))
+ .build();
+ tester.configServer().nodeRepository().putNodes(zone, List.of(hostA, nodeA, hostB));
}
}
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/SystemUpgraderTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/SystemUpgraderTest.java
index db2353860ae..8090765b5f9 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/SystemUpgraderTest.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/SystemUpgraderTest.java
@@ -305,7 +305,7 @@ public class SystemUpgraderTest {
for (Node node : listNodes(zone, application)) {
nodeRepository().putNodes(
zone.getId(),
- new Node.Builder(node).currentVersion(node.wantedVersion()).build());
+ Node.builder(node).currentVersion(node.wantedVersion()).build());
}
assertCurrentVersion(application, version, zone);
});
@@ -329,7 +329,7 @@ public class SystemUpgraderTest {
Node node = nodes.get(0);
nodeRepository().putNodes(
zone.getId(),
- new Node.Builder(node).state(Node.State.failed).build());
+ Node.builder(node).state(Node.State.failed).build());
}
private void assertSystemVersion(Version version) {
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/VCMRMaintainerTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/VCMRMaintainerTest.java
index 16ed6b7ef98..f957b14ef95 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/VCMRMaintainerTest.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/VCMRMaintainerTest.java
@@ -20,8 +20,12 @@ import java.time.Duration;
import java.time.Instant;
import java.time.ZonedDateTime;
import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
/**
* @author olaa
@@ -49,9 +53,12 @@ public class VCMRMaintainerTest {
vcmrReport.addVcmr("id123", ZonedDateTime.now(), ZonedDateTime.now());
var parkedNode = createNode(host1, NodeType.host, Node.State.parked, true);
var failedNode = createNode(host2, NodeType.host, Node.State.failed, false);
- parkedNode = new Node.Builder(parkedNode)
- .reports(vcmrReport.toNodeReports())
- .build();
+ Map<String, String> reports = vcmrReport.toNodeReports().entrySet().stream()
+ .collect(Collectors.toMap(Map.Entry::getKey,
+ kv -> kv.getValue().toString()));
+ parkedNode = Node.builder(parkedNode)
+ .reports(reports)
+ .build();
nodeRepo.putNodes(zoneId, List.of(parkedNode, failedNode));
@@ -63,8 +70,7 @@ public class VCMRMaintainerTest {
assertEquals(Node.State.dirty, nodeList.get(0).state());
assertEquals(Node.State.failed, nodeList.get(1).state());
- var report = nodeList.get(0).reports();
- assertNull(report.get(VCMRReport.getReportId()));
+ assertTrue(nodeList.get(0).reports().isEmpty());
var writtenChangeRequest = tester.curator().readChangeRequest(changeRequestId).get();
assertEquals(Status.COMPLETED, writtenChangeRequest.getStatus());
@@ -235,11 +241,11 @@ public class VCMRMaintainerTest {
}
private Node createNode(HostName hostname, NodeType nodeType, Node.State state, boolean wantToRetire) {
- return new Node.Builder()
- .hostname(hostname)
- .type(nodeType)
- .state(state)
- .wantToRetire(wantToRetire)
- .build();
+ return Node.builder()
+ .hostname(hostname)
+ .type(nodeType)
+ .state(state)
+ .wantToRetire(wantToRetire)
+ .build();
}
-} \ No newline at end of file
+}
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/changemanagement/ChangeManagementApiHandlerTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/changemanagement/ChangeManagementApiHandlerTest.java
index 80cee3af58b..5846ab5f2a4 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/changemanagement/ChangeManagementApiHandlerTest.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/changemanagement/ChangeManagementApiHandlerTest.java
@@ -2,23 +2,17 @@
package com.yahoo.vespa.hosted.controller.restapi.changemanagement;
import com.yahoo.application.container.handler.Request;
-import com.yahoo.config.provision.HostName;
+import com.yahoo.config.provision.ApplicationId;
import com.yahoo.config.provision.zone.ZoneId;
import com.yahoo.vespa.athenz.api.AthenzIdentity;
import com.yahoo.vespa.athenz.api.AthenzUser;
import com.yahoo.vespa.hosted.controller.api.integration.configserver.Node;
-import com.yahoo.vespa.hosted.controller.api.integration.noderepository.NodeMembership;
-import com.yahoo.vespa.hosted.controller.api.integration.noderepository.NodeOwner;
-import com.yahoo.vespa.hosted.controller.api.integration.noderepository.NodeRepositoryNode;
-import com.yahoo.vespa.hosted.controller.api.integration.noderepository.NodeState;
-import com.yahoo.vespa.hosted.controller.api.integration.noderepository.NodeType;
import com.yahoo.vespa.hosted.controller.api.integration.vcmr.ChangeRequest;
import com.yahoo.vespa.hosted.controller.api.integration.vcmr.ChangeRequestSource;
import com.yahoo.vespa.hosted.controller.api.integration.vcmr.HostAction;
import com.yahoo.vespa.hosted.controller.api.integration.vcmr.VespaChangeRequest;
import com.yahoo.vespa.hosted.controller.restapi.ContainerTester;
import com.yahoo.vespa.hosted.controller.restapi.ControllerContainerTest;
-import org.intellij.lang.annotations.Language;
import org.junit.Before;
import org.junit.Test;
@@ -42,8 +36,7 @@ public class ChangeManagementApiHandlerTest extends ControllerContainerTest {
public void before() {
tester = new ContainerTester(container, responses);
addUserToHostedOperatorRole(operator);
- tester.serviceRegistry().configServer().nodeRepository().addNodes(ZoneId.from("prod.us-east-3"), createNodes());
- tester.serviceRegistry().configServer().nodeRepository().putNodes(ZoneId.from("prod.us-east-3"), createNode());
+ tester.serviceRegistry().configServer().nodeRepository().putNodes(ZoneId.from("prod.us-east-3"), createNodes());
tester.controller().curator().writeChangeRequest(createChangeRequest());
}
@@ -85,23 +78,11 @@ public class ChangeManagementApiHandlerTest extends ControllerContainerTest {
assertEquals(VespaChangeRequest.Status.COMPLETED, changeRequest.getStatus());
}
- private void assertResponse(Request request, @Language("JSON") String body, int statusCode) {
- addIdentityToRequest(request, operator);
- tester.assertResponse(request, body, statusCode);
- }
-
private void assertFile(Request request, String filename) {
addIdentityToRequest(request, operator);
tester.assertResponse(request, new File(filename));
}
- private Node createNode() {
- return new Node.Builder()
- .hostname(HostName.from("host1"))
- .switchHostname("switch1")
- .build();
- }
-
private VespaChangeRequest createChangeRequest() {
var instant = Instant.ofEpochMilli(9001);
var date = ZonedDateTime.ofInstant(instant, java.time.ZoneId.of("UTC"));
@@ -124,8 +105,8 @@ public class ChangeManagementApiHandlerTest extends ControllerContainerTest {
);
}
- private List<NodeRepositoryNode> createNodes() {
- List<NodeRepositoryNode> nodes = new ArrayList<>();
+ private List<Node> createNodes() {
+ List<Node> nodes = new ArrayList<>();
nodes.add(createNode("node1", "host1", "default", 0 ));
nodes.add(createNode("node2", "host1", "default", 0 ));
nodes.add(createNode("node3", "host1", "default", 0 ));
@@ -135,44 +116,27 @@ public class ChangeManagementApiHandlerTest extends ControllerContainerTest {
return nodes;
}
- private NodeOwner createOwner() {
- NodeOwner owner = new NodeOwner();
- owner.tenant = "mytenant";
- owner.application = "myapp";
- owner.instance = "default";
- return owner;
- }
-
- private NodeMembership createMembership(String clusterId, int group) {
- NodeMembership membership = new NodeMembership();
- membership.group = "" + group;
- membership.clusterid = clusterId;
- membership.clustertype = "content";
- membership.index = 2;
- membership.retired = false;
- return membership;
- }
-
- private NodeRepositoryNode createNode(String nodename, String hostname, String clusterId, int group) {
- NodeRepositoryNode node = new NodeRepositoryNode();
- node.setHostname(nodename);
- node.setParentHostname(hostname);
- node.setState(NodeState.active);
- node.setOwner(createOwner());
- node.setMembership(createMembership(clusterId, group));
- node.setType(NodeType.tenant);
-
- return node;
+ private Node createNode(String nodename, String hostname, String clusterId, int group) {
+ return Node.builder()
+ .hostname(nodename)
+ .parentHostname(hostname).state(Node.State.active)
+ .owner(ApplicationId.from("mytenant", "myapp", "default"))
+ .type(com.yahoo.config.provision.NodeType.tenant)
+ .clusterId(clusterId)
+ .group(String.valueOf(group))
+ .clusterType(Node.ClusterType.content)
+ .build();
}
- private NodeRepositoryNode createHost(String hostname, String switchName) {
- NodeRepositoryNode node = new NodeRepositoryNode();
- node.setHostname(hostname);
- node.setSwitchHostname(switchName);
- node.setOwner(createOwner());
- node.setType(NodeType.host);
- node.setMembership(createMembership("host", 0));
- return node;
+ private Node createHost(String hostname, String switchName) {
+ return Node.builder()
+ .hostname(hostname)
+ .switchHostname(switchName)
+ .owner(ApplicationId.from("mytenant", "myapp", "default"))
+ .type(com.yahoo.config.provision.NodeType.host)
+ .clusterId("host")
+ .group("0")
+ .build();
}
}
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/os/OsApiTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/os/OsApiTest.java
index 7364723f5f0..c1358decf19 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/os/OsApiTest.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/os/OsApiTest.java
@@ -142,7 +142,7 @@ public class OsApiTest extends ControllerContainerTest {
var targetVersion = nodeRepository().targetVersionsOf(zone).osVersion(application.nodeType());
for (Node node : nodeRepository().list(zone, application.id())) {
var version = targetVersion.orElse(node.wantedOsVersion());
- nodeRepository().putNodes(zone, new Node.Builder(node).currentOsVersion(version).wantedOsVersion(version).build());
+ nodeRepository().putNodes(zone, Node.builder(node).currentOsVersion(version).wantedOsVersion(version).build());
}
}
}
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/versions/VersionStatusTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/versions/VersionStatusTest.java
index 4dd283cf5d7..6e70fb8c3cb 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/versions/VersionStatusTest.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/versions/VersionStatusTest.java
@@ -70,7 +70,7 @@ public class VersionStatusTest {
// Upgrade some config servers
for (ZoneApi zone : tester.zoneRegistry().zones().all().zones()) {
for (Node node : tester.configServer().nodeRepository().list(zone.getId(), SystemApplication.configServer.id())) {
- Node upgradedNode = new Node.Builder(node).currentVersion(version1).build();
+ Node upgradedNode = Node.builder(node).currentVersion(version1).build();
tester.configServer().nodeRepository().putNodes(zone.getId(), upgradedNode);
break;
}
@@ -114,7 +114,7 @@ public class VersionStatusTest {
Version ancientVersion = Version.fromString("5.1");
for (ZoneApi zone : tester.controller().zoneRegistry().zones().all().zones()) {
for (Node node : tester.configServer().nodeRepository().list(zone.getId(), SystemApplication.configServer.id())) {
- Node downgradedNode = new Node.Builder(node).currentVersion(ancientVersion).build();
+ Node downgradedNode = Node.builder(node).currentVersion(ancientVersion).build();
tester.configServer().nodeRepository().putNodes(zone.getId(), downgradedNode);
break;
}