diff options
Diffstat (limited to 'controller-api')
17 files changed, 261 insertions, 67 deletions
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/application/v4/model/ClusterMetrics.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/application/v4/model/ClusterMetrics.java index cc10041992c..cb29d5854a0 100644 --- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/application/v4/model/ClusterMetrics.java +++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/application/v4/model/ClusterMetrics.java @@ -1,7 +1,6 @@ // Copyright 2019 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.hosted.controller.api.application.v4.model; -import java.util.HashMap; import java.util.Map; import java.util.Optional; @@ -16,15 +15,16 @@ public class ClusterMetrics { public static final String DOCUMENT_COUNT = "documentCount"; public static final String FEED_LATENCY = "feedLatency"; public static final String QUERY_LATENCY = "queryLatency"; + public static final String FEEDING_BLOCKED = "feedingBlocked"; private final String clusterId; private final String clusterType; private final Map<String, Double> metrics; - public ClusterMetrics(String clusterId, String clusterType) { + public ClusterMetrics(String clusterId, String clusterType, Map<String, Double> metrics) { this.clusterId = clusterId; this.clusterType = clusterType; - this.metrics = new HashMap<>(); + this.metrics = Map.copyOf(metrics); } public String getClusterId() { @@ -55,9 +55,8 @@ public class ClusterMetrics { return Optional.ofNullable(metrics.get(QUERY_LATENCY)); } - public ClusterMetrics addMetric(String name, double value) { - metrics.put(name, value); - return this; + public Optional<Double> feedingBlocked() { + return Optional.ofNullable(metrics.get(FEEDING_BLOCKED)); } } diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/Cluster.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/Cluster.java index d356f5eb89f..07de259be2f 100644 --- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/Cluster.java +++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/Cluster.java @@ -107,16 +107,19 @@ public class Cluster { private final ClusterResources from, to; private final Instant at; + private final Optional<Instant> completion; - public ScalingEvent(ClusterResources from, ClusterResources to, Instant at) { + public ScalingEvent(ClusterResources from, ClusterResources to, Instant at, Optional<Instant> completion) { this.from = from; this.to = to; this.at = at; + this.completion = completion; } public ClusterResources from() { return from; } public ClusterResources to() { return to; } public Instant at() { return at; } + public Optional<Instant> completion() { return completion; } } diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/ConfigServer.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/ConfigServer.java index ed545dc35d1..81c4d7be483 100644 --- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/ConfigServer.java +++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/ConfigServer.java @@ -39,7 +39,7 @@ public interface ConfigServer { void reindex(DeploymentId deployment, List<String> clusterNames, List<String> documentTypes, boolean indexedOnly); - Optional<ApplicationReindexing> getReindexing(DeploymentId deployment); + ApplicationReindexing getReindexing(DeploymentId deployment); void disableReindexing(DeploymentId deployment); @@ -47,7 +47,7 @@ public interface ConfigServer { void restart(DeploymentId deployment, RestartFilter restartFilter); - void deactivate(DeploymentId deployment) throws NotFoundException; + void deactivate(DeploymentId deployment); boolean isSuspended(DeploymentId deployment); diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/ConfigServerException.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/ConfigServerException.java index 4240b0d9fa6..d651eda7139 100644 --- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/ConfigServerException.java +++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/ConfigServerException.java @@ -1,38 +1,32 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +// 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.configserver; -import java.net.URI; -import java.util.Objects; +import com.yahoo.slime.Inspector; +import com.yahoo.slime.SlimeUtils; +import org.apache.hc.core5.http.ClassicHttpRequest; + +import java.util.stream.Stream; /** - * @author Tony Vaagenes + * An exception due to server error, a bad request, or similar. + * + * @author jonmv */ public class ConfigServerException extends RuntimeException { - private final URI serverUri; - private final ErrorCode errorCode; - private final String serverMessage; + private final ErrorCode code; + private final String message; - public ConfigServerException(URI serverUri, String context, String serverMessage, ErrorCode errorCode, Throwable cause) { - super(context + ": " + serverMessage, cause); - this.serverUri = Objects.requireNonNull(serverUri); - this.errorCode = Objects.requireNonNull(errorCode); - this.serverMessage = Objects.requireNonNull(serverMessage); + public ConfigServerException(ErrorCode code, String message, String context) { + super(context + ": " + message); + this.code = code; + this.message = message; } - public ErrorCode getErrorCode() { - return errorCode; - } + public ErrorCode code() { return code; } - public URI getServerUri() { - return serverUri; - } + public String message() { return message; } - public String getServerMessage() { - return serverMessage; - } - - // TODO: Copied from Vespa. Expose these in Vespa and use them here public enum ErrorCode { APPLICATION_LOCK_FAILURE, BAD_REQUEST, @@ -46,7 +40,18 @@ public class ConfigServerException extends RuntimeException { UNKNOWN_VESPA_VERSION, PARENT_HOST_NOT_READY, CERTIFICATE_NOT_READY, - LOAD_BALANCER_NOT_READY + LOAD_BALANCER_NOT_READY, + INCOMPLETE_RESPONSE + } + + public static ConfigServerException readException(byte[] body, String context) { + Inspector root = SlimeUtils.jsonToSlime(body).get(); + String codeName = root.field("error-code").asString(); + ErrorCode code = Stream.of(ErrorCode.values()) + .filter(value -> value.name().equals(codeName)) + .findAny().orElse(ErrorCode.INCOMPLETE_RESPONSE); + String message = root.field("message").valid() ? root.field("message").asString() : "(no message)"; + return new ConfigServerException(code, message, context); } } diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/LoadBalancer.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/LoadBalancer.java index 05bdf3c3412..d2f19f4df9f 100644 --- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/LoadBalancer.java +++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/LoadBalancer.java @@ -18,11 +18,11 @@ public class LoadBalancer { private final String id; private final ApplicationId application; private final ClusterSpec.Id cluster; - private final HostName hostname; + private final Optional<HostName> hostname; private final State state; private final Optional<String> dnsZone; - public LoadBalancer(String id, ApplicationId application, ClusterSpec.Id cluster, HostName hostname, State state, + public LoadBalancer(String id, ApplicationId application, ClusterSpec.Id cluster, Optional<HostName> hostname, State state, Optional<String> dnsZone) { this.id = Objects.requireNonNull(id, "id must be non-null"); this.application = Objects.requireNonNull(application, "application must be non-null"); @@ -44,7 +44,7 @@ public class LoadBalancer { return cluster; } - public HostName hostname() { + public Optional<HostName> hostname() { return hostname; } diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/Log.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/Log.java index ba5d740d0e1..29c3253c9c0 100644 --- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/Log.java +++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/Log.java @@ -11,5 +11,6 @@ public class Log { public long time; public String level; public String message; + public boolean applicationPackage; } 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 d1078b5e30c..0f9e12d8cf2 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 @@ -64,6 +64,7 @@ public class Node { private final Set<String> additionalIpAddresses; private final String openStackId; 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, @@ -72,7 +73,7 @@ public class Node { 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) { + Set<String> additionalIpAddresses, String openStackId, Optional<String> switchHostname, Optional<String> modelName) { this.hostname = hostname; this.parentHostname = parentHostname; this.state = state; @@ -108,6 +109,7 @@ public class Node { this.openStackId = openStackId; this.additionalIpAddresses = additionalIpAddresses; this.switchHostname = switchHostname; + this.modelName = modelName; } public HostName hostname() { @@ -244,6 +246,8 @@ public class Node { return switchHostname; } + public Optional<String> modelName() { return modelName; } + @Override public boolean equals(Object o) { if (this == o) return true; @@ -326,6 +330,7 @@ public class Node { private Set<String> additionalIpAddresses = new HashSet<>(); private String openStackId; private Optional<String> switchHostname = Optional.empty(); + private Optional<String> modelName = Optional.empty(); public Builder() { } @@ -365,6 +370,7 @@ public class Node { this.additionalIpAddresses = node.additionalIpAddresses; this.openStackId = node.openStackId; this.switchHostname = node.switchHostname; + this.modelName = node.modelName; } public Builder hostname(HostName hostname) { @@ -537,12 +543,17 @@ public class Node { return this; } + public Builder modelName(String modelName) { + this.modelName = Optional.ofNullable(modelName); + return this; + } + public Node build() { return new Node(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); + wantedDockerImage, currentDockerImage, reports, history, additionalIpAddresses, openStackId, switchHostname, modelName); } } 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 72592e16bfd..ac4ff0a80a0 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 @@ -36,36 +36,21 @@ public interface NodeRepository { void deleteNode(ZoneId zone, String hostname); - void setState(ZoneId zone, NodeState nodeState, String nodename); + 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); - NodeList listNodes(ZoneId zone, ApplicationId application); - - NodeList listNodes(ZoneId zone, List<HostName> hostnames); - /** List all nodes in given zone */ - default List<Node> list(ZoneId zone) { - return listNodes(zone).nodes().stream() - .map(NodeRepository::toNode) - .collect(Collectors.toUnmodifiableList()); - } + List<Node> list(ZoneId zone, boolean includeDeprovisioned); /** List all nodes in zone having given hostnames */ - default List<Node> list(ZoneId zone, List<HostName> hostnames) { - return listNodes(zone, hostnames).nodes().stream() - .map(NodeRepository::toNode) - .collect(Collectors.toUnmodifiableList()); - } + List<Node> list(ZoneId zone, List<HostName> hostnames); /** List all nodes in zone owned by given application */ - default List<Node> list(ZoneId zone, ApplicationId application) { - return listNodes(zone, application).nodes().stream() - .map(NodeRepository::toNode) - .collect(Collectors.toUnmodifiableList()); - } + List<Node> list(ZoneId zone, ApplicationId application); /** List all nodes in states, in zone owned by given application */ default List<Node> list(ZoneId zone, ApplicationId application, Set<Node.State> states) { @@ -111,7 +96,7 @@ public interface NodeRepository { /** Checks whether the zone has the spare capacity to remove the given hosts */ boolean isReplaceable(ZoneId zoneId, List<HostName> hostNames); - private static Node toNode(NodeRepositoryNode node) { + static Node toNode(NodeRepositoryNode node) { var application = Optional.ofNullable(node.getOwner()) .map(owner -> ApplicationId.from(owner.getTenant(), owner.getApplication(), owner.getInstance())); @@ -156,7 +141,8 @@ public interface NodeRepository { node.getHistory(), node.getAdditionalIpAddresses(), node.getOpenStackId(), - Optional.ofNullable(node.getSwitchHostname())); + Optional.ofNullable(node.getSwitchHostname()), + Optional.ofNullable(node.getModelName())); } private static String clusterIdOf(NodeMembership nodeMembership) { @@ -200,6 +186,7 @@ public interface NodeRepository { 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; } diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/noderepository/ProvisionResource.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/noderepository/ProvisionResource.java index 26243a28ee0..5714e3d5f6d 100644 --- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/noderepository/ProvisionResource.java +++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/noderepository/ProvisionResource.java @@ -2,7 +2,6 @@ package com.yahoo.vespa.hosted.controller.api.integration.noderepository; import com.yahoo.config.provision.TenantName; -import com.yahoo.vespa.hosted.controller.api.integration.configserver.NodeRepoStats; import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; @@ -44,7 +43,7 @@ public interface ProvisionResource { @GET @Path("/node/") - NodeList listNodes(@QueryParam("recursive") boolean recursive); + NodeList listNodes(@QueryParam("recursive") boolean recursive, @QueryParam("includeDeprovisioned") boolean includeDeprovisioned); @GET @Path("/node/") diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/noderepository/ScalingEventData.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/noderepository/ScalingEventData.java index b33a7436522..1ac24695afe 100644 --- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/noderepository/ScalingEventData.java +++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/noderepository/ScalingEventData.java @@ -7,6 +7,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.yahoo.vespa.hosted.controller.api.integration.configserver.Cluster; import java.time.Instant; +import java.util.Optional; /** * @author bratseth @@ -24,8 +25,17 @@ public class ScalingEventData { @JsonProperty("at") public Long at; + @JsonProperty("completion") + public Long completion; + public Cluster.ScalingEvent toScalingEvent() { - return new Cluster.ScalingEvent(from.toClusterResources(), to.toClusterResources(), Instant.ofEpochMilli(at)); + return new Cluster.ScalingEvent(from.toClusterResources(), to.toClusterResources(), Instant.ofEpochMilli(at), + toOptionalInstant(completion)); + } + + private Optional<Instant> toOptionalInstant(Long epochMillis) { + if (epochMillis == null) return Optional.empty(); + return Optional.of(Instant.ofEpochMilli(epochMillis)); } } diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/vcmr/ChangeRequest.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/vcmr/ChangeRequest.java index 31665c8ae0a..11adc1f7bb6 100644 --- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/vcmr/ChangeRequest.java +++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/vcmr/ChangeRequest.java @@ -16,7 +16,7 @@ public class ChangeRequest { private final Approval approval; private final Impact impact; - private ChangeRequest(String id, ChangeRequestSource changeRequestSource, List<String> impactedSwitches, List<String> impactedHosts, Approval approval, Impact impact) { + public ChangeRequest(String id, ChangeRequestSource changeRequestSource, List<String> impactedSwitches, List<String> impactedHosts, Approval approval, Impact impact) { this.id = Objects.requireNonNull(id); this.changeRequestSource = Objects.requireNonNull(changeRequestSource); this.impactedSwitches = Objects.requireNonNull(impactedSwitches); diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/vcmr/ChangeRequestClient.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/vcmr/ChangeRequestClient.java index e8ff768927f..f8f54567bea 100644 --- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/vcmr/ChangeRequestClient.java +++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/vcmr/ChangeRequestClient.java @@ -8,7 +8,8 @@ import java.util.List; */ public interface ChangeRequestClient { - List<ChangeRequest> getUpcomingChangeRequests(); + /** Get upcoming change requests and updated status of previously stored requests */ + List<ChangeRequest> getChangeRequests(List<ChangeRequest> changeRequests); void approveChangeRequests(List<ChangeRequest> changeRequests); diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/vcmr/ChangeRequestSource.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/vcmr/ChangeRequestSource.java index 63f6c256766..6cf0f6e0ebd 100644 --- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/vcmr/ChangeRequestSource.java +++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/vcmr/ChangeRequestSource.java @@ -2,8 +2,11 @@ package com.yahoo.vespa.hosted.controller.api.integration.vcmr; import java.time.ZonedDateTime; +import java.util.List; import java.util.Objects; +import static com.yahoo.vespa.hosted.controller.api.integration.vcmr.ChangeRequestSource.Status.*; + /** * @author olaa */ @@ -17,7 +20,7 @@ public class ChangeRequestSource { private final ZonedDateTime plannedEndTime; - private ChangeRequestSource(String system, String id, String url, Status status, ZonedDateTime plannedStartTime, ZonedDateTime plannedEndTime) { + public ChangeRequestSource(String system, String id, String url, Status status, ZonedDateTime plannedStartTime, ZonedDateTime plannedEndTime) { this.system = Objects.requireNonNull(system); this.id = Objects.requireNonNull(id); this.url = Objects.requireNonNull(url); @@ -80,6 +83,10 @@ public class ChangeRequestSource { return Objects.hash(system, id, status, url, plannedStartTime, plannedEndTime); } + public boolean isClosed() { + return List.of(CLOSED, CANCELED, COMPLETE).contains(status); + } + public enum Status { DRAFT, WAITING_FOR_APPROVAL, diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/vcmr/HostAction.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/vcmr/HostAction.java new file mode 100644 index 00000000000..5a018475e9f --- /dev/null +++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/vcmr/HostAction.java @@ -0,0 +1,72 @@ +// 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.vcmr; + +import java.time.Instant; +import java.util.Objects; + +/** + * @author olaa + * + * Contains planned/current action for a host impacted by a change request + */ +public class HostAction { + + private final String hostname; + private final State state; + private final Instant lastUpdated; + + public HostAction(String hostname, State state, Instant lastUpdated) { + this.hostname = hostname; + this.state = state; + this.lastUpdated = lastUpdated; + } + + public String getHostname() { + return hostname; + } + + public State getState() { + return state; + } + + public Instant getLastUpdated() { + return lastUpdated; + } + + public HostAction withState(State state) { + return new HostAction(hostname, state, this.state == state ? lastUpdated : Instant.now()); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + HostAction that = (HostAction) o; + return Objects.equals(hostname, that.hostname) && + state == that.state && + Objects.equals(lastUpdated, that.lastUpdated); + } + + @Override + public int hashCode() { + return Objects.hash(hostname, state, lastUpdated); + } + + @Override + public String toString() { + return "HostAction{" + + "hostname='" + hostname + '\'' + + ", state=" + state + + ", lastUpdated=" + lastUpdated + + '}'; + } + + public enum State { + REQUIRES_OPERATOR_ACTION, + PENDING_RETIREMENT, + NONE, + RETIRING, + RETIRED, + COMPLETE + } +} diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/vcmr/MockChangeRequestClient.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/vcmr/MockChangeRequestClient.java index e85c0afcb0e..10175f36991 100644 --- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/vcmr/MockChangeRequestClient.java +++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/vcmr/MockChangeRequestClient.java @@ -13,7 +13,7 @@ public class MockChangeRequestClient implements ChangeRequestClient { private List<ChangeRequest> approvedChangeRequests = new ArrayList<>(); @Override - public List<ChangeRequest> getUpcomingChangeRequests() { + public List<ChangeRequest> getChangeRequests(List<ChangeRequest> changeRequests) { return upcomingChangeRequests; } diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/vcmr/VespaChangeRequest.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/vcmr/VespaChangeRequest.java new file mode 100644 index 00000000000..a8be4a77c71 --- /dev/null +++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/vcmr/VespaChangeRequest.java @@ -0,0 +1,98 @@ +// 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.vcmr; + +import com.yahoo.config.provision.zone.ZoneId; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +/** + * @author olaa + */ +public class VespaChangeRequest extends ChangeRequest { + + private final Status status; + private final ZoneId zoneId; + // TODO: Create applicationActionPlan + private final List<HostAction> hostActionPlan; + + public VespaChangeRequest(String id, ChangeRequestSource changeRequestSource, List<String> impactedSwitches, List<String> impactedHosts, Approval approval, Impact impact, Status status, List<HostAction> hostActionPlan, ZoneId zoneId) { + super(id, changeRequestSource, impactedSwitches, impactedHosts, approval, impact); + this.status = status; + this.hostActionPlan = hostActionPlan; + this.zoneId = zoneId; + } + public VespaChangeRequest(ChangeRequest changeRequest, ZoneId zoneId) { + this(changeRequest.getId(), changeRequest.getChangeRequestSource(), changeRequest.getImpactedSwitches(), + changeRequest.getImpactedHosts(), changeRequest.getApproval(), changeRequest.getImpact(), Status.PENDING_ASSESSMENT, List.of(), zoneId); + } + + public Status getStatus() { + return status; + } + + public List<HostAction> getHostActionPlan() { + return hostActionPlan; + } + + public ZoneId getZoneId() { + return zoneId; + } + + public VespaChangeRequest withStatus(Status status) { + return new VespaChangeRequest(getId(), getChangeRequestSource(), getImpactedSwitches(), getImpactedHosts(), getApproval(), getImpact(), status, hostActionPlan, zoneId); + } + + public VespaChangeRequest withSource(ChangeRequestSource source) { + return new VespaChangeRequest(getId(), source, getImpactedSwitches(), getImpactedHosts(), getApproval(), getImpact(), status, hostActionPlan, zoneId); + } + + public VespaChangeRequest withApproval(Approval approval) { + return new VespaChangeRequest(getId(), getChangeRequestSource(), getImpactedSwitches(), getImpactedHosts(), approval, getImpact(), status, hostActionPlan, zoneId); + } + + public VespaChangeRequest withActionPlan(List<HostAction> hostActionPlan) { + return new VespaChangeRequest(getId(), getChangeRequestSource(), getImpactedSwitches(), getImpactedHosts(), getApproval(), getImpact(), status, hostActionPlan, zoneId); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + if (!super.equals(o)) return false; + VespaChangeRequest that = (VespaChangeRequest) o; + return status == that.status && + Objects.equals(hostActionPlan, that.hostActionPlan) && + Objects.equals(zoneId, that.zoneId); + } + + @Override + public int hashCode() { + return Objects.hash(super.hashCode(), status, hostActionPlan, zoneId); + } + + @Override + public String toString() { + return "VespaChangeRequest{" + + "id='" + getId() + '\'' + + ", changeRequestSource=" + getChangeRequestSource() + + ", impactedSwitches=" + getImpactedSwitches() + + ", impactedHosts=" + getImpactedHosts() + + ", approval=" + getApproval() + + ", impact=" + getImpact() + + ", status=" + status + + ", zoneId=" + zoneId + + ", hostActionPlan=" + hostActionPlan + + '}'; + } + + public enum Status { + COMPLETED, + IN_PROGRESS, + PENDING_ACTION, + PENDING_ASSESSMENT, + REQUIRES_OPERATOR_ACTION, + NOOP + } +} diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/role/PathGroup.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/role/PathGroup.java index 1387f4a4eaa..558beb20e66 100644 --- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/role/PathGroup.java +++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/role/PathGroup.java @@ -54,6 +54,7 @@ enum PathGroup { tenantInfo(Matcher.tenant, "/application/v4/tenant/{tenant}/application/", "/application/v4/tenant/{tenant}/info/", + "/application/v4/tenant/{tenant}/notifications", "/routing/v1/status/tenant/{tenant}/{*}"), tenantKeys(Matcher.tenant, |