summaryrefslogtreecommitdiffstats
path: root/node-repository/src/main/java
diff options
context:
space:
mode:
Diffstat (limited to 'node-repository/src/main/java')
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/Node.java43
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/NodeRepository.java9
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/assimilate/PopulateClient.java15
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/ApplicationMaintainer.java2
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/Expirer.java2
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/monitoring/ProvisionMetrics.java2
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/persistence/CuratorDatabaseClient.java3
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/persistence/NodeSerializer.java32
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/GroupPreparer.java2
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/legacy/ProvisionResource.java7
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/v1/NodesApiHandler.java14
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/v2/NodesApiHandler.java19
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/v2/NodesResponse.java25
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/MockNodeRepository.java19
14 files changed, 138 insertions, 56 deletions
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/Node.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/Node.java
index 2ab98f0c582..d4a955cf746 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/Node.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/Node.java
@@ -30,6 +30,7 @@ public final class Node {
private final Configuration configuration;
private final Status status;
private final State state;
+ private final Type type;
/** Record of the last event of each type happening to this node */
private final History history;
@@ -38,19 +39,20 @@ public final class Node {
private Optional<Allocation> allocation;
/** Creates a node in the initial state (provisioned) */
- public static Node create(String openStackId, String hostname, Optional<String> parentHostname, Configuration configuration) {
+ public static Node create(String openStackId, String hostname, Optional<String> parentHostname, Configuration configuration, Type type) {
return new Node(openStackId, hostname, parentHostname, configuration, Status.initial(), State.provisioned,
- Optional.empty(), History.empty());
+ Optional.empty(), History.empty(), type);
}
/** Do not use. Construct nodes by calling {@link NodeRepository#createNode} */
public Node(String openStackId, String hostname, Optional<String> parentHostname,
- Configuration configuration, Status status, State state, Allocation allocation, History history) {
- this(openStackId, hostname, parentHostname, configuration, status, state, Optional.of(allocation), history);
+ Configuration configuration, Status status, State state, Allocation allocation, History history, Type type) {
+ this(openStackId, hostname, parentHostname, configuration, status, state, Optional.of(allocation), history, type);
}
public Node(String openStackId, String hostname, Optional<String> parentHostname,
- Configuration configuration, Status status, State state, Optional<Allocation> allocation, History history) {
+ Configuration configuration, Status status, State state, Optional<Allocation> allocation,
+ History history, Type type) {
Objects.requireNonNull(openStackId, "A node must have an openstack id");
Objects.requireNonNull(hostname, "A node must have a hostname");
Objects.requireNonNull(parentHostname, "A null parentHostname is not permitted.");
@@ -59,6 +61,7 @@ public final class Node {
Objects.requireNonNull(state, "A null node state is not permitted");
Objects.requireNonNull(allocation, "A null node allocation is not permitted");
Objects.requireNonNull(history, "A null node history is not permitted");
+ Objects.requireNonNull(type, "A null node type is not permitted");
this.id = hostname;
this.hostname = hostname;
@@ -69,6 +72,7 @@ public final class Node {
this.state = state;
this.allocation = allocation;
this.history = history;
+ this.type = type;
}
/**
@@ -96,6 +100,9 @@ public final class Node {
/** Returns the current state of this node (in the node state machine) */
public State state() { return state; }
+ /** Returns the type of this node */
+ public Type type() { return type; }
+
/** Returns the current allocation of this, if any */
public Optional<Allocation> allocation() { return allocation; }
@@ -135,24 +142,29 @@ public final class Node {
/** Returns a node with the status assigned to the given value */
public Node setStatus(Status status) {
- return new Node(openStackId, hostname, parentHostname, configuration, status, state, allocation, history);
+ return new Node(openStackId, hostname, parentHostname, configuration, status, state, allocation, history, type);
+ }
+
+ /** Returns a node with the type assigned to the given value */
+ public Node setType(Type type) {
+ return new Node(openStackId, hostname, parentHostname, configuration, status, state, allocation, history, type);
}
/** Returns a node with the hardware configuration assigned to the given value */
public Node setConfiguration(Configuration configuration) {
- return new Node(openStackId, hostname, parentHostname, configuration, status, state, allocation, history);
+ return new Node(openStackId, hostname, parentHostname, configuration, status, state, allocation, history, type);
}
/** Returns a copy of this with the current generation set to generation */
public Node setReboot(Generation generation) {
return new Node(openStackId, hostname, parentHostname, configuration, status.setReboot(generation), state,
- allocation, history);
+ allocation, history, type);
}
/** Returns a copy of this with the flavor set to flavor */
public Node setFlavor(Flavor flavor) {
return new Node(openStackId, hostname, parentHostname, new Configuration(flavor), status, state,
- allocation, history);
+ allocation, history, type);
}
/** Returns a copy of this with a history record saying it was detected to be down at this instant */
@@ -176,17 +188,17 @@ public final class Node {
* Do not use this to allocate a node.
*/
public Node setAllocation(Allocation allocation) {
- return new Node(openStackId, hostname, parentHostname, configuration, status, state, allocation, history);
+ return new Node(openStackId, hostname, parentHostname, configuration, status, state, allocation, history, type);
}
/** Returns a copy of this node with the parent hostname assigned to the given value. */
public Node setParentHostname(String parentHostname) {
- return new Node(openStackId, hostname, Optional.of(parentHostname), configuration, status, state, allocation, history);
+ return new Node(openStackId, hostname, Optional.of(parentHostname), configuration, status, state, allocation, history, type);
}
/** Returns a copy of this node with the given history. */
private Node setHistory(History history) {
- return new Node(openStackId, hostname, parentHostname, configuration, status, state, allocation, history);
+ return new Node(openStackId, hostname, parentHostname, configuration, status, state, allocation, history, type);
}
@Override
@@ -209,6 +221,8 @@ public final class Node {
(parentHostname.isPresent() ? " [on: " + parentHostname.get() + "]" : "");
}
+
+
public enum State {
/** This node has been requested (from OpenStack) but is not yet read for use */
@@ -236,7 +250,10 @@ public final class Node {
public boolean isAllocated() {
return this == reserved || this == active || this == inactive || this == failed;
}
-
}
+ public enum Type {
+ tenant,
+ host;
+ }
}
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/NodeRepository.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/NodeRepository.java
index 1980b1f5318..aff65652399 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/NodeRepository.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/NodeRepository.java
@@ -94,7 +94,9 @@ public class NodeRepository extends AbstractComponent {
return zkClient.getNode(state, hostname);
}
- public List<Node> getNodes(Node.State ... inState) { return zkClient.getNodes(inState); }
+ public List<Node> getNodes(Node.Type type, Node.State ... inState) {
+ return zkClient.getNodes(inState).stream().filter(node -> node.type().equals(type)).collect(Collectors.toList());
+ }
public List<Node> getNodes(ApplicationId id, Node.State ... inState) { return zkClient.getNodes(id, inState); }
public List<Node> getInactive() { return zkClient.getNodes(Node.State.inactive); }
public List<Node> getFailed() { return zkClient.getNodes(Node.State.failed); }
@@ -108,8 +110,9 @@ public class NodeRepository extends AbstractComponent {
// ----------------- Node lifecycle -----------------------------------------------------------
/** Creates a new node object, without adding it to the node repo */
- public Node createNode(String openStackId, String hostname, Optional<String> parentHostname, Configuration configuration) {
- return Node.create(openStackId, hostname, parentHostname, configuration);
+ public Node createNode(String openStackId, String hostname, Optional<String> parentHostname,
+ Configuration configuration, Node.Type type) {
+ return Node.create(openStackId, hostname, parentHostname, configuration, type);
}
/** Adds a list of (newly created) nodes to the node repository as <i>provisioned</i> nodes */
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/assimilate/PopulateClient.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/assimilate/PopulateClient.java
index 1ec20f6df0c..37e0fb2da17 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/assimilate/PopulateClient.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/assimilate/PopulateClient.java
@@ -85,14 +85,15 @@ public class PopulateClient {
private Node buildNode(String hostname, String clusterType, String clusterId, int nodeIndex) {
return new Node(
- hostname, // Id
- hostname, // Hostname
- Optional.empty(), // parent hostname
- new Configuration(getFlavor(clusterType, clusterId).get()), // Flavor
+ hostname /* id */,
+ hostname /* Hostname */,
+ Optional.empty() /* parent hostname */,
+ new Configuration(getFlavor(clusterType, clusterId).get()),
Status.initial(),
- Node.State.active, // State = active/allocated
- Optional.empty(), // Allocation
- History.empty()) // History
+ Node.State.active,
+ Optional.empty() /* Allocation */,
+ History.empty(),
+ Node.Type.tenant) // History
.allocate(
ApplicationId.from(
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/ApplicationMaintainer.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/ApplicationMaintainer.java
index fd5e229fa1b..d12c7f2a5ae 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/ApplicationMaintainer.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/ApplicationMaintainer.java
@@ -35,7 +35,7 @@ public class ApplicationMaintainer extends Maintainer {
@Override
protected void maintain() {
Set<ApplicationId> applications =
- nodeRepository().getNodes(Node.State.active).stream().map(node -> node.allocation().get().owner()).collect(Collectors.toSet());
+ nodeRepository().getNodes(Node.Type.tenant, Node.State.active).stream().map(node -> node.allocation().get().owner()).collect(Collectors.toSet());
for (ApplicationId application : applications) {
try {
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/Expirer.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/Expirer.java
index 8333996c23e..495ff3b756f 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/Expirer.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/Expirer.java
@@ -47,7 +47,7 @@ public abstract class Expirer extends Maintainer {
@Override
protected void maintain() {
List<Node> expired = new ArrayList<>();
- for (Node node : nodeRepository().getNodes(fromState)) {
+ for (Node node : nodeRepository().getNodes(Node.Type.tenant, fromState)) {
Optional<History.Event> event = node.history().event(eventType);
if (event.isPresent() && event.get().at().plus(expiryTime).isBefore(clock.instant()))
expired.add(node);
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/monitoring/ProvisionMetrics.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/monitoring/ProvisionMetrics.java
index 2753f435bde..b1e0df929f4 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/monitoring/ProvisionMetrics.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/monitoring/ProvisionMetrics.java
@@ -50,7 +50,7 @@ public class ProvisionMetrics extends AbstractComponent {
log.log(LogLevel.DEBUG, "Running provision metrics task");
try {
for (Node.State state : Node.State.values())
- metric.set("hostedVespa." + state.name() + "Hosts", nodeRepository.getNodes(state).size(), null);
+ metric.set("hostedVespa." + state.name() + "Hosts", nodeRepository.getNodes(Node.Type.tenant, state).size(), null);
} catch (RuntimeException e) {
log.log(LogLevel.INFO, "Failed gathering metrics data: " + e.getMessage());
}
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/persistence/CuratorDatabaseClient.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/persistence/CuratorDatabaseClient.java
index 5ff1f41272a..6805862baf3 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/persistence/CuratorDatabaseClient.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/persistence/CuratorDatabaseClient.java
@@ -145,7 +145,8 @@ public class CuratorDatabaseClient {
newNodeStatus(node, toState),
toState,
toState.isAllocated() ? node.allocation() : Optional.empty(),
- newNodeHistory(node, toState));
+ newNodeHistory(node, toState),
+ node.type());
curatorTransaction.add(CuratorOperations.delete(toPath(node).getAbsolute()))
.add(CuratorOperations.create(toPath(toState, newNode.hostname()).getAbsolute(), nodeSerializer.toJson(newNode)));
writtenNodes.add(newNode);
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/persistence/NodeSerializer.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/persistence/NodeSerializer.java
index 9e0a26be308..004cceee7cb 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/persistence/NodeSerializer.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/persistence/NodeSerializer.java
@@ -55,6 +55,9 @@ public class NodeSerializer {
private static final String stateVersionKey = "stateVersion";
private static final String failCountKey = "failCount";
private static final String hardwareFailureKey = "hardwareFailure";
+ private static final String nodeTypeKey = "type";
+ private static final String nodeTypeTenant = "tenant";
+ private static final String nodeTypeHost = "host";
// Configuration fields
private static final String flavorKey = "flavor";
@@ -71,7 +74,7 @@ public class NodeSerializer {
private static final String dockerImageKey = "dockerImage";
// History event fields
- private static final String typeKey = "type";
+ private static final String historyEventTypeKey = "type";
private static final String atKey = "at";
private static final String agentKey = "agent"; // retired events only
@@ -107,6 +110,15 @@ public class NodeSerializer {
object.setBool(hardwareFailureKey, node.status().hardwareFailure());
node.allocation().ifPresent(allocation -> toSlime(allocation, object.setObject(instanceKey)));
toSlime(node.history(), object.setArray(historyKey));
+ object.setString(nodeTypeKey, nodeTypeToString(node.type()));
+ }
+
+ private String nodeTypeToString(Node.Type type) {
+ switch (type) {
+ case tenant: return nodeTypeTenant;
+ case host: return nodeTypeHost;
+ }
+ throw new IllegalArgumentException("Unknown node type '" + type.toString() + "'");
}
private void toSlime(Configuration configuration, Cursor object) {
@@ -131,7 +143,7 @@ public class NodeSerializer {
}
private void toSlime(History.Event event, Cursor object) {
- object.setString(typeKey, toString(event.type()));
+ object.setString(historyEventTypeKey, toString(event.type()));
object.setLong(atKey, event.at().toEpochMilli());
if (event instanceof History.RetiredEvent)
object.setString(agentKey, toString(((History.RetiredEvent)event).agent()));
@@ -151,7 +163,8 @@ public class NodeSerializer {
statusFromSlime(object),
state,
allocationFromSlime(object.field(instanceKey)),
- historyFromSlime(object.field(historyKey)));
+ historyFromSlime(object.field(historyKey)),
+ typeFromSlime(object));
}
private Status statusFromSlime(Inspector object) {
@@ -194,8 +207,19 @@ public class NodeSerializer {
return new History(events);
}
+ private Node.Type typeFromSlime(Inspector object) {
+ String typeString = object.field(nodeTypeKey).asString();
+ switch (typeString) {
+ case nodeTypeTenant : return Node.Type.tenant;
+ case nodeTypeHost : return Node.Type.host;
+ // TODO: Remove this when all data is converted
+ case "" : return Node.Type.tenant;
+ }
+ throw new IllegalArgumentException("Unknown node type '" + typeString + "'");
+ }
+
private History.Event eventFromSlime(Inspector object) {
- History.Event.Type type = eventTypeFromString(object.field(typeKey).asString());
+ History.Event.Type type = eventTypeFromString(object.field(historyEventTypeKey).asString());
if (type == null) return null;
Instant at = Instant.ofEpochMilli(object.field(atKey).asLong());
if (type.equals(History.Event.Type.retired))
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/GroupPreparer.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/GroupPreparer.java
index 6b5d37d812a..0f5549e1110 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/GroupPreparer.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/GroupPreparer.java
@@ -78,7 +78,7 @@ class GroupPreparer {
// Use new, ready nodes. Need to lock ready pool to ensure that nodes are not grabbed by others.
try (Mutex readyLock = nodeRepository.lockUnallocated()) {
- List<Node> readyNodes = nodeRepository.getNodes(Node.State.ready);
+ List<Node> readyNodes = nodeRepository.getNodes(Node.Type.tenant, Node.State.ready);
accepted = nodeList.offer(optimize(readyNodes), !canChangeGroup);
nodeList.update(nodeRepository.reserve(accepted));
}
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/legacy/ProvisionResource.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/legacy/ProvisionResource.java
index f4c52010415..867d45b4fcd 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/legacy/ProvisionResource.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/legacy/ProvisionResource.java
@@ -47,7 +47,7 @@ public class ProvisionResource {
public void addNodes(List<HostInfo> hostInfoList) {
List<Node> nodes = new ArrayList<>();
for (HostInfo hostInfo : hostInfoList)
- nodes.add(nodeRepository.createNode(hostInfo.openStackId, hostInfo.hostname, Optional.empty(), new Configuration(nodeFlavors.getFlavorOrThrow(hostInfo.flavor))));
+ nodes.add(nodeRepository.createNode(hostInfo.openStackId, hostInfo.hostname, Optional.empty(), new Configuration(nodeFlavors.getFlavorOrThrow(hostInfo.flavor)), Node.Type.tenant));
nodeRepository.addNodes(nodes);
}
@@ -94,7 +94,7 @@ public class ProvisionResource {
Map<String, TenantStatus.ApplicationUsage> appinstanceUsageMap = new HashMap<>();
- nodeRepository.getNodes(Node.State.active).stream()
+ nodeRepository.getNodes(Node.Type.tenant, Node.State.active).stream()
.filter(node -> {
return node.allocation().get().owner().tenant().value().equals(tenantId);
})
@@ -115,11 +115,12 @@ public class ProvisionResource {
}
//TODO: move this to nodes/v2/ when the spec for this has been nailed.
+ //TODO: Change it to list host nodes, instead of hosts for tenant nodes.
@GET
@Path("/dockerhost/{hostname}")
public ContainersForHost getContainersForHost(@PathParam("hostname") String hostname) {
List<DockerContainer> dockerContainersForHost =
- nodeRepository.getNodes(State.active, State.inactive).stream()
+ nodeRepository.getNodes(Node.Type.tenant, State.active, State.inactive).stream()
.filter(runsOnDockerHost(hostname))
.flatMap(ProvisionResource::toDockerContainer)
.collect(Collectors.toList());
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/v1/NodesApiHandler.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/v1/NodesApiHandler.java
index 00e232dcfd3..0c9ca701a6e 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/v1/NodesApiHandler.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/v1/NodesApiHandler.java
@@ -78,13 +78,15 @@ public class
}
private void toSlime(Node.State state, Cursor object) {
- List<Node> nodes = nodeRepository.getNodes(state);
Cursor nodeArray = null; // create if there are nodes
- for (Node node : nodes) {
- if (hostnameFilter.isPresent() && ! node.hostname().equals(hostnameFilter.get())) continue;
- if (nodeArray == null)
- nodeArray = object.setArray(state.name());
- toSlime(node, nodeArray.addObject());
+ for (Node.Type type : Node.Type.values()) {
+ List<Node> nodes = nodeRepository.getNodes(type, state);
+ for (Node node : nodes) {
+ if (hostnameFilter.isPresent() && !node.hostname().equals(hostnameFilter.get())) continue;
+ if (nodeArray == null)
+ nodeArray = object.setArray(state.name());
+ toSlime(node, nodeArray.addObject());
+ }
}
}
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/v2/NodesApiHandler.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/v2/NodesApiHandler.java
index 9981602e4d0..8c388fbd4db 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/v2/NodesApiHandler.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/v2/NodesApiHandler.java
@@ -44,6 +44,8 @@ public class NodesApiHandler extends LoggingRequestHandler {
private final NodeRepository nodeRepository;
private final NodeFlavors nodeFlavors;
+ private static final String nodeTypeKey = "type";
+
public NodesApiHandler(Executor executor, AccessLog accessLog, NodeRepository nodeRepository, NodeFlavors flavors) {
super(executor, accessLog);
@@ -189,7 +191,22 @@ public class NodesApiHandler extends LoggingRequestHandler {
inspector.field("openStackId").asString(),
inspector.field("hostname").asString(),
parentHostname,
- new Configuration(nodeFlavors.getFlavorOrThrow(inspector.field("flavor").asString())));
+ new Configuration(nodeFlavors.getFlavorOrThrow(inspector.field("flavor").asString())),
+ nodeTypeFromSlime(inspector.field(nodeTypeKey)));
+ }
+
+ private Node.Type nodeTypeFromSlime(Inspector object) {
+ // TODO: Remove this when 6.13 is deployed everywhere.
+ if (! object.valid()) {
+ return Node.Type.tenant;
+ }
+ String typeString = object.asString();
+ switch (typeString) {
+ case "tenant" : return Node.Type.tenant;
+ case "host" : return Node.Type.host;
+ }
+ // TODO: Change this to throw an exception when 6.13 is deployed everywhere.
+ return Node.Type.tenant;
}
// TODO: Move most of this to node repo
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/v2/NodesResponse.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/v2/NodesResponse.java
index 4e8fbe6099b..9318c6d0d7b 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/v2/NodesResponse.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/v2/NodesResponse.java
@@ -1,7 +1,6 @@
// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.hosted.provision.restapi.v2;
-import com.yahoo.component.Version;
import com.yahoo.config.provision.ApplicationId;
import com.yahoo.config.provision.ClusterMembership;
import com.yahoo.container.jdisc.HttpRequest;
@@ -42,7 +41,7 @@ class NodesResponse extends HttpResponse {
private final Slime slime;
- public NodesResponse(ResponseType type, HttpRequest request, NodeRepository nodeRepository) {
+ public NodesResponse(ResponseType responseType, HttpRequest request, NodeRepository nodeRepository) {
super(200);
this.parentUrl = toParentUrl(request);
this.nodeParentUrl = toNodeParentUrl(request);
@@ -52,7 +51,7 @@ class NodesResponse extends HttpResponse {
slime = new Slime();
Cursor root = slime.setObject();
- switch (type) {
+ switch (responseType) {
case nodeList: nodesToSlime(root); break;
case stateList : statesToSlime(root); break;
case nodesInStateList: nodesToSlime(stateFromString(lastElement(parentUrl)), root); break;
@@ -103,14 +102,17 @@ class NodesResponse extends HttpResponse {
/** Outputs the nodes in the given state to a node array */
private void nodesToSlime(Node.State state, Cursor parentObject) {
Cursor nodeArray = parentObject.setArray("nodes");
- toSlime(nodeRepository.getNodes(state), nodeArray);
+ for (Node.Type type : Node.Type.values())
+ toSlime(nodeRepository.getNodes(type, state), nodeArray);
}
/** Outputs all the nodes to a node array */
private void nodesToSlime(Cursor parentObject) {
Cursor nodeArray = parentObject.setArray("nodes");
- for (Node.State state : Node.State.values())
- toSlime(nodeRepository.getNodes(state), nodeArray);
+ for (Node.State state : Node.State.values()) {
+ for (Node.Type type : Node.Type.values())
+ toSlime(nodeRepository.getNodes(type, state), nodeArray);
+ }
}
private void toSlime(List<Node> nodes, Cursor array) {
@@ -132,7 +134,9 @@ class NodesResponse extends HttpResponse {
if ( ! allFields) return;
object.setString("id", node.id());
object.setString("state", NodeStateSerializer.wireNameOf(node.state()));
+ object.setString("type", node.type().name());
object.setString("hostname", node.hostname());
+ object.setString("type", toString(node.type()));
if (node.parentHostname().isPresent()) {
object.setString("parentHostname", node.parentHostname().get());
}
@@ -177,6 +181,15 @@ class NodesResponse extends HttpResponse {
toSlime(node.history(), object.setArray("history"));
}
+ private String toString(Node.Type type) {
+ switch(type) {
+ case tenant: return "tenant";
+ case host: return "host";
+ default:
+ throw new RuntimeException("New type added to enum, not implemented in NodesResponse: " + type.name());
+ }
+ }
+
private void toSlime(ApplicationId id, Cursor object) {
object.setString("tenant", id.tenant().value());
object.setString("application", id.application().value());
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/MockNodeRepository.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/MockNodeRepository.java
index d60e43cebed..123104a354f 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/MockNodeRepository.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/MockNodeRepository.java
@@ -48,22 +48,22 @@ public class MockNodeRepository extends NodeRepository {
NodeRepositoryProvisioner provisioner = new NodeRepositoryProvisioner(this, flavors, Zone.defaultZone());
List<Node> nodes = new ArrayList<>();
- nodes.add(createNode("node1", "host1.yahoo.com", Optional.empty(), new Configuration(flavors.getFlavorOrThrow("default"))));
- nodes.add(createNode("node2", "host2.yahoo.com", Optional.empty(), new Configuration(flavors.getFlavorOrThrow("default"))));
- nodes.add(createNode("node3", "host3.yahoo.com", Optional.empty(), new Configuration(flavors.getFlavorOrThrow("expensive"))));
+ nodes.add(createNode("node1", "host1.yahoo.com", Optional.empty(), new Configuration(flavors.getFlavorOrThrow("default")), Node.Type.tenant));
+ nodes.add(createNode("node2", "host2.yahoo.com", Optional.empty(), new Configuration(flavors.getFlavorOrThrow("default")), Node.Type.tenant));
+ nodes.add(createNode("node3", "host3.yahoo.com", Optional.empty(), new Configuration(flavors.getFlavorOrThrow("expensive")), Node.Type.tenant));
// TODO: Use docker flavor
- Node node4 = createNode("node4", "host4.yahoo.com", Optional.of("dockerhost4"), new Configuration(flavors.getFlavorOrThrow("default")));
+ Node node4 = createNode("node4", "host4.yahoo.com", Optional.of("dockerhost4"), new Configuration(flavors.getFlavorOrThrow("default")), Node.Type.tenant);
node4 = node4.setStatus(node4.status().setDockerImage("image-12"));
nodes.add(node4);
- Node node5 = createNode("node5", "host5.yahoo.com", Optional.of("dockerhost"), new Configuration(flavors.getFlavorOrThrow("default")));
+ Node node5 = createNode("node5", "host5.yahoo.com", Optional.of("dockerhost"), new Configuration(flavors.getFlavorOrThrow("default")), Node.Type.tenant);
nodes.add(node5.setStatus(node5.status().setDockerImage("image-123")));
- nodes.add(createNode("node6", "host6.yahoo.com", Optional.empty(), new Configuration(flavors.getFlavorOrThrow("default"))));
- nodes.add(createNode("node7", "host7.yahoo.com", Optional.empty(), new Configuration(flavors.getFlavorOrThrow("default"))));
+ nodes.add(createNode("node6", "host6.yahoo.com", Optional.empty(), new Configuration(flavors.getFlavorOrThrow("default")), Node.Type.tenant));
+ nodes.add(createNode("node7", "host7.yahoo.com", Optional.empty(), new Configuration(flavors.getFlavorOrThrow("default")), Node.Type.tenant));
// 8 and 9 are added by web service calls
- Node node10 = createNode("node10", "host10.yahoo.com", Optional.of("parent.yahoo.com"), new Configuration(flavors.getFlavorOrThrow("default")));
+ Node node10 = createNode("node10", "host10.yahoo.com", Optional.of("parent.yahoo.com"), new Configuration(flavors.getFlavorOrThrow("default")), Node.Type.tenant);
Status node10newStatus = node10.status();
node10newStatus = node10newStatus
.setVespaVersion(Version.fromString("5.104.142"))
@@ -71,6 +71,9 @@ public class MockNodeRepository extends NodeRepository {
.setStateVersion("5.104.142-2.1.2408");
node10 = node10.setStatus(node10newStatus);
nodes.add(node10);
+
+ nodes.add(createNode("parent1", "parent1.yahoo.com", Optional.empty(), new Configuration(flavors.getFlavorOrThrow("default")), Node.Type.host));
+
nodes = addNodes(nodes);
nodes.remove(6);
setReady(nodes);