diff options
Diffstat (limited to 'node-repository/src/main/java/com')
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); |