diff options
58 files changed, 469 insertions, 369 deletions
diff --git a/application-model/pom.xml b/application-model/pom.xml index 4937bc54a34..19823a12e67 100644 --- a/application-model/pom.xml +++ b/application-model/pom.xml @@ -23,6 +23,12 @@ </dependency> <dependency> <groupId>com.yahoo.vespa</groupId> + <artifactId>config-provisioning</artifactId> + <version>${project.version}</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>com.yahoo.vespa</groupId> <artifactId>annotations</artifactId> <version>${project.version}</version> </dependency> diff --git a/application-model/src/main/java/com/yahoo/vespa/applicationmodel/ApplicationInstanceId.java b/application-model/src/main/java/com/yahoo/vespa/applicationmodel/ApplicationInstanceId.java index 76605a8d6b2..63810d1d109 100644 --- a/application-model/src/main/java/com/yahoo/vespa/applicationmodel/ApplicationInstanceId.java +++ b/application-model/src/main/java/com/yahoo/vespa/applicationmodel/ApplicationInstanceId.java @@ -10,15 +10,17 @@ import java.util.Objects; */ // TODO: Remove this and use ApplicationName/InstanceName instead (if you need it for the JSON stuff move it to that layer and don't let it leak) public class ApplicationInstanceId { - public static final ApplicationInstanceId CONFIG_SERVER = new ApplicationInstanceId("zone-config-servers"); - public static final ApplicationInstanceId CONTROLLER = new ApplicationInstanceId("controller"); + + public static final ApplicationInstanceId CONFIG_SERVER = new ApplicationInstanceId(InfrastructureApplication.CONFIG_SERVER.applicationName()); + public static final ApplicationInstanceId CONTROLLER = new ApplicationInstanceId(InfrastructureApplication.CONTROLLER.applicationName()); // Unfortunately, for config server host the ApplicationInstanceId is: configserver-host:prod:cd-us-central-1:default - public boolean isConfigServerHost() { return id.startsWith("configserver-host:"); } - public static final ApplicationInstanceId CONTROLLER_HOST = new ApplicationInstanceId("controller-host:prod:default:default"); - public boolean isTenantHost() { return id.startsWith("tenant-host:"); } - public boolean isProxyHost() { return id.startsWith("proxy-host:"); } + public boolean isConfigServerHost() { return id.startsWith(InfrastructureApplication.CONFIG_SERVER_HOST.applicationName() + ":"); } + public static final ApplicationInstanceId CONTROLLER_HOST = new ApplicationInstanceId(InfrastructureApplication.CONTROLLER_HOST.applicationName() + + ":prod:default:default"); + public boolean isTenantHost() { return id.startsWith(InfrastructureApplication.TENANT_HOST.applicationName() + ":"); } + public boolean isProxyHost() { return id.startsWith(InfrastructureApplication.PROXY_HOST.applicationName() + ":"); } // Routing application instance ID is of the form: routing:prod:eu-west-1:default - public boolean isProxy() { return id.startsWith("routing:"); } + public boolean isProxy() { return id.startsWith(InfrastructureApplication.PROXY.applicationName() + ":"); } private final String id; @@ -34,8 +36,7 @@ public class ApplicationInstanceId { return id; } - // For compatibility with original Scala case class - public String s() { + public String value() { return id; } diff --git a/application-model/src/main/java/com/yahoo/vespa/applicationmodel/ApplicationInstanceReference.java b/application-model/src/main/java/com/yahoo/vespa/applicationmodel/ApplicationInstanceReference.java index f9bc0cec0b0..c11af132722 100644 --- a/application-model/src/main/java/com/yahoo/vespa/applicationmodel/ApplicationInstanceReference.java +++ b/application-model/src/main/java/com/yahoo/vespa/applicationmodel/ApplicationInstanceReference.java @@ -39,7 +39,7 @@ public class ApplicationInstanceReference implements Comparable<ApplicationInsta } public String asString() { - return tenantId.s() + ":" + applicationInstanceId.s(); + return tenantId.value() + ":" + applicationInstanceId.value(); } @Override diff --git a/application-model/src/main/java/com/yahoo/vespa/applicationmodel/ClusterId.java b/application-model/src/main/java/com/yahoo/vespa/applicationmodel/ClusterId.java index e193c32b16b..9ccd3e4d706 100644 --- a/application-model/src/main/java/com/yahoo/vespa/applicationmodel/ClusterId.java +++ b/application-model/src/main/java/com/yahoo/vespa/applicationmodel/ClusterId.java @@ -10,13 +10,13 @@ import java.util.Objects; */ public class ClusterId { - public static final ClusterId CONFIG_SERVER = new ClusterId("zone-config-servers"); - public static final ClusterId CONTROLLER = new ClusterId("controller"); - public static final ClusterId CONFIG_SERVER_HOST = new ClusterId("configserver-host"); - public static final ClusterId CONTROLLER_HOST = new ClusterId("controller-host"); - public static final ClusterId PROXY_HOST = new ClusterId("proxy-host"); - public static final ClusterId ROUTING = new ClusterId("routing"); - public static final ClusterId TENANT_HOST = new ClusterId("tenant-host"); + public static final ClusterId CONFIG_SERVER = new ClusterId(InfrastructureApplication.CONFIG_SERVER.applicationName()); + public static final ClusterId CONTROLLER = new ClusterId(InfrastructureApplication.CONTROLLER.applicationName()); + public static final ClusterId CONFIG_SERVER_HOST = new ClusterId(InfrastructureApplication.CONFIG_SERVER_HOST.applicationName()); + public static final ClusterId CONTROLLER_HOST = new ClusterId(InfrastructureApplication.CONTROLLER_HOST.applicationName()); + public static final ClusterId PROXY_HOST = new ClusterId(InfrastructureApplication.PROXY_HOST.applicationName()); + public static final ClusterId ROUTING = new ClusterId(InfrastructureApplication.PROXY.applicationName()); + public static final ClusterId TENANT_HOST = new ClusterId(InfrastructureApplication.TENANT_HOST.applicationName()); private final String id; diff --git a/application-model/src/main/java/com/yahoo/vespa/applicationmodel/InfrastructureApplication.java b/application-model/src/main/java/com/yahoo/vespa/applicationmodel/InfrastructureApplication.java new file mode 100644 index 00000000000..f3b529d8c05 --- /dev/null +++ b/application-model/src/main/java/com/yahoo/vespa/applicationmodel/InfrastructureApplication.java @@ -0,0 +1,53 @@ +// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.vespa.applicationmodel; + +import com.yahoo.config.provision.ApplicationId; +import com.yahoo.config.provision.NodeType; + +import java.util.stream.Stream; + +/** + * Special infrastructure applications in hosted Vespa. + * + * @author hakonhall + */ +public enum InfrastructureApplication { + CONTROLLER_HOST("controller-host", NodeType.controllerhost), + CONTROLLER("controller", NodeType.controller), + CONFIG_SERVER_HOST("configserver-host", NodeType.confighost), + CONFIG_SERVER("zone-config-servers", NodeType.config), + PROXY_HOST("proxy-host", NodeType.proxyhost), + PROXY("routing", NodeType.proxy), + TENANT_HOST("tenant-host", NodeType.host), + DEV_HOST("dev-host", NodeType.devhost); + + private final ApplicationId id; + private final NodeType nodeType; + + public static InfrastructureApplication withNodeType(NodeType nodeType) { + return Stream.of(values()) + .filter(application -> nodeType == application.nodeType) + .findAny() + .orElseThrow(() -> new IllegalArgumentException("No application associated with " + nodeType)); + } + + InfrastructureApplication(String name, NodeType nodeType) { + this.id = ApplicationId.from(TenantId.HOSTED_VESPA.value(), name, "default"); + this.nodeType = nodeType; + } + + public ApplicationId id() { return id; } + /** Avoid using {@link #name()} which is the name of the enum constant. */ + public String applicationName() { return id.application().value(); } + public NodeType nodeType() { return nodeType; } + public boolean isConfigServerLike() { return this == CONFIG_SERVER || this == CONTROLLER; } + public boolean isConfigServerHostLike() { return this == CONFIG_SERVER_HOST || this == CONTROLLER_HOST; } + + @Override + public String toString() { + return "InfrastructureApplication{" + + "id=" + id + + ", nodeType=" + nodeType + + '}'; + } +} diff --git a/application-model/src/main/java/com/yahoo/vespa/applicationmodel/TenantId.java b/application-model/src/main/java/com/yahoo/vespa/applicationmodel/TenantId.java index 9789f1ac9f9..7d94a0418e4 100644 --- a/application-model/src/main/java/com/yahoo/vespa/applicationmodel/TenantId.java +++ b/application-model/src/main/java/com/yahoo/vespa/applicationmodel/TenantId.java @@ -2,6 +2,7 @@ package com.yahoo.vespa.applicationmodel; import com.fasterxml.jackson.annotation.JsonValue; +import com.yahoo.config.provision.TenantName; import java.util.Objects; @@ -26,11 +27,12 @@ public class TenantId { return id; } - // For compatibility with original Scala case class - public String s() { + public String value() { return id; } + public TenantName toName() { return TenantName.from(id); } + @Override public boolean equals(Object o) { if (this == o) return true; diff --git a/cloud-tenant-base-dependencies-enforcer/pom.xml b/cloud-tenant-base-dependencies-enforcer/pom.xml index 2025431d86c..99aa3f9e1b2 100644 --- a/cloud-tenant-base-dependencies-enforcer/pom.xml +++ b/cloud-tenant-base-dependencies-enforcer/pom.xml @@ -246,7 +246,7 @@ <include>org.apache.httpcomponents.client5:httpclient5:${httpclient5.version}:jar:test</include> <include>org.apache.httpcomponents.core5:httpcore5:${httpclient5.version}:jar:test</include> <include>org.apache.httpcomponents.core5:httpcore5-h2:${httpclient5.version}:jar:test</include> - <include>org.apache.httpcomponents:httpclient:4.5.12:jar:test</include> + <include>org.apache.httpcomponents:httpclient:4.5.13:jar:test</include> <include>org.apache.httpcomponents:httpcore:4.4.13:jar:test</include> <include>org.apache.opennlp:opennlp-tools:1.9.3:jar:test</include> <include>org.apiguardian:apiguardian-api:1.1.0:jar:test</include> diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java b/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java index d5c64689648..7f0948cccda 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java @@ -187,7 +187,6 @@ public class ContainerModelBuilder extends ConfigModelBuilder<ContainerModel> { addConfiguredComponents(deployState, cluster, spec); addSecretStore(cluster, spec, deployState); - addServlets(deployState, spec, cluster); addModelEvaluation(spec, cluster, context); addModelEvaluationBundles(cluster); @@ -527,12 +526,6 @@ public class ContainerModelBuilder extends ConfigModelBuilder<ContainerModel> { return http; } - // TODO Vespa 8: Remove - private void addServlets(DeployState deployState, Element spec, ApplicationContainerCluster cluster) { - if (XML.getChildren(spec, "servlet").size() > 0) - throw new IllegalArgumentException("The 'servlet' tag is no longer supported in services.xml. Please use a handler instead."); - } - private void addDocumentApi(Element spec, ApplicationContainerCluster cluster) { ContainerDocumentApi containerDocumentApi = buildDocumentApi(cluster, spec); if (containerDocumentApi == null) return; diff --git a/config-model/src/main/resources/schema/containercluster.rnc b/config-model/src/main/resources/schema/containercluster.rnc index b06bf0897cf..e8ff1721397 100644 --- a/config-model/src/main/resources/schema/containercluster.rnc +++ b/config-model/src/main/resources/schema/containercluster.rnc @@ -12,7 +12,6 @@ ContainerCluster = element container | jdisc { } ContainerServices = - Servlet* & SearchInContainer? & DocprocInContainer? & ProcessingInContainer? & @@ -136,18 +135,6 @@ Threadpool = element threadpool { element queue-size { xsd:nonNegativeInteger } } -# Servlet: - -Servlet = element servlet { - ComponentDefinition & - ServletConfig? & - element path { xsd:string { pattern = "\w[\w_/\-\.]*(\*)?" } } -} - -ServletConfig = element servlet-config { - anyElement+ -} - # SEARCH: SearchInContainer = element search { diff --git a/config-model/src/test/schema-test-files/services.xml b/config-model/src/test/schema-test-files/services.xml index b477ceef169..9ccf50de906 100644 --- a/config-model/src/test/schema-test-files/services.xml +++ b/config-model/src/test/schema-test-files/services.xml @@ -58,20 +58,6 @@ <group name="foo" environment="aws_stage" /> </secret-store> - <servlet id="my-servlet" class="com.yahoo.MyServlet" bundle="my-bundle"> - <path>p/a/t/h</path> - </servlet> - - <servlet id="my-servlet" class="com.yahoo.MyServlet" bundle="my-bundle"> - <path>Apps/app_1.3-4/*</path> - <config name="foo"> - <intVal>0</intVal> - </config> - <servlet-config> - <foo>bar</foo> - </servlet-config> - </servlet> - <http> <filtering strict-mode="true"> <access-control domain="my.athens-domain" read="true"> diff --git a/config-model/src/test/schema-test-files/standalone-container.xml b/config-model/src/test/schema-test-files/standalone-container.xml index 85f577882fb..cc34ae43712 100644 --- a/config-model/src/test/schema-test-files/standalone-container.xml +++ b/config-model/src/test/schema-test-files/standalone-container.xml @@ -2,20 +2,6 @@ <!-- Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. --> <container id='qrsCluster_1' version='1.0'> - <servlet id="my-servlet" class="com.yahoo.MyServlet" bundle="my-bundle"> - <path>p/a/t/h</path> - </servlet> - - <servlet id="my-servlet" class="com.yahoo.MyServlet" bundle="my-bundle"> - <path>Apps/app_1.3-4/*</path> - <config name="foo"> - <intVal>0</intVal> - </config> - <servlet-config> - <foo>bar</foo> - </servlet-config> - </servlet> - <http> <filtering> <filter id="com.yahoo.YcaFilter" bundle="mybundle"> diff --git a/config-provisioning/src/main/java/com/yahoo/config/provision/zone/UpgradePolicy.java b/config-provisioning/src/main/java/com/yahoo/config/provision/zone/UpgradePolicy.java index 91ecf7b29e4..85cc384660d 100644 --- a/config-provisioning/src/main/java/com/yahoo/config/provision/zone/UpgradePolicy.java +++ b/config-provisioning/src/main/java/com/yahoo/config/provision/zone/UpgradePolicy.java @@ -2,45 +2,68 @@ package com.yahoo.config.provision.zone; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collections; import java.util.List; +import java.util.Set; /** - * This class declares the order to use when upgrading zones in a system. + * This class declares the steps (zones) to follow when upgrading a system. If a step contains multiple zones, those + * will be upgraded in parallel. * * @author mpolden */ public class UpgradePolicy { - private final List<List<ZoneApi>> zones; + private final List<Set<ZoneApi>> steps; - private UpgradePolicy(List<List<ZoneApi>> zones) { - this.zones = zones; + private UpgradePolicy(List<Set<ZoneApi>> steps) { + for (int i = 0; i < steps.size(); i++) { + for (int j = 0; j < i; j++) { + if (!Collections.disjoint(steps.get(i), steps.get(j))) { + throw new IllegalArgumentException("One or more zones are declared in multiple steps"); + } + } + } + this.steps = List.copyOf(steps); } - public List<List<ZoneApi>> asList() { - return List.copyOf(zones); + /** Returns the steps in this */ + public List<Set<ZoneApi>> steps() { + return steps; } - private UpgradePolicy with(ZoneApi... zone) { - List<List<ZoneApi>> zones = new ArrayList<>(this.zones); - zones.add(Arrays.asList(zone)); - return new UpgradePolicy(zones); + /** Returns a copy of this with the step order inverted */ + public UpgradePolicy inverted() { + List<Set<ZoneApi>> copy = new ArrayList<>(steps); + Collections.reverse(copy); + return new UpgradePolicy(copy); } - /** Upgrade given zone as the next step */ - public UpgradePolicy upgrade(ZoneApi zone) { - return with(zone); + public static UpgradePolicy.Builder builder() { + return new UpgradePolicy.Builder(); } - /** Upgrade given zones in parallel as the next step */ - public UpgradePolicy upgradeInParallel(ZoneApi... zone) { - return with(zone); - } + public static class Builder { + + private final List<Set<ZoneApi>> steps = new ArrayList<>(); + + private Builder() {} + + /** Upgrade given zone as the next step */ + public Builder upgrade(ZoneApi zone) { + return upgradeInParallel(zone); + } + + /** Upgrade given zones in parallel as the next step */ + public Builder upgradeInParallel(ZoneApi... zone) { + this.steps.add(Set.of(zone)); + return this; + } + + public UpgradePolicy build() { + return new UpgradePolicy(steps); + } - public static UpgradePolicy create() { - return new UpgradePolicy(Collections.emptyList()); } } diff --git a/config/src/main/java/com/yahoo/config/subscription/ConfigSubscriber.java b/config/src/main/java/com/yahoo/config/subscription/ConfigSubscriber.java index 01008f0a8a2..4bf442a0890 100644 --- a/config/src/main/java/com/yahoo/config/subscription/ConfigSubscriber.java +++ b/config/src/main/java/com/yahoo/config/subscription/ConfigSubscriber.java @@ -434,8 +434,8 @@ public class ConfigSubscriber implements AutoCloseable { } /** - * Use this convenience method if you only want to subscribe on <em>one</em> config, and want generic error handling. - * Implement {@link SingleSubscriber} and pass to this method. + * Convenience method that can be used if you only want to subscribe to <em>one</em> config, and want generic error handling. + * Implement {@link SingleSubscriber} and pass it to this method. * You will get initial config, and a config thread will be started. The method will throw in your thread if initial * configuration fails, and the config thread will print a generic error message (but continue) if it fails thereafter. The config * thread will stop if you {@link #close()} this {@link ConfigSubscriber}. diff --git a/config/src/main/java/com/yahoo/config/subscription/impl/JRTConfigSubscription.java b/config/src/main/java/com/yahoo/config/subscription/impl/JRTConfigSubscription.java index 68e22ad5656..a18f1b4b260 100644 --- a/config/src/main/java/com/yahoo/config/subscription/impl/JRTConfigSubscription.java +++ b/config/src/main/java/com/yahoo/config/subscription/impl/JRTConfigSubscription.java @@ -36,10 +36,9 @@ public class JRTConfigSubscription<T extends ConfigInstance> extends ConfigSubsc private Instant lastOK = Instant.MIN; /** - * A queue containing either zero or one (the newest) request that got a callback from JRT, - * but has not yet been handled. + * A queue containing responses (requests that got a callback from JRT) that has not yet been handled. */ - private BlockingQueue<JRTClientConfigRequest> reqQueue = new LinkedBlockingQueue<>(); + private BlockingQueue<JRTClientConfigRequest> responseQueue = new LinkedBlockingQueue<>(); public JRTConfigSubscription(ConfigKey<T> key, JRTConfigRequester requester, TimingValues timingValues) { super(key); @@ -49,31 +48,40 @@ public class JRTConfigSubscription<T extends ConfigInstance> extends ConfigSubsc @Override public boolean nextConfig(long timeoutMillis) { - // Note: since the JRT callback thread will clear the queue first when it inserts a brand new element, - // (see #updateConfig()) there is a race here. However: the caller will handle it no matter what it gets - // from the queue here, the important part is that local state on the subscription objects is preserved. + JRTClientConfigRequest response = pollForNewConfig(timeoutMillis); + if (response == null) return newConfigOrException(); - // Poll the queue for a next config until timeout - JRTClientConfigRequest jrtReq = pollQueue(timeoutMillis); - if (jrtReq == null) return newConfigOrException(); - - log.log(FINE, () -> "Polled queue and found config " + jrtReq); + log.log(FINE, () -> "Polled queue and found config " + response); // Might set the following (caller must check): // generation, generation changed, config, config changed // Important: it never <em>resets</em> those flags, we must persist that state until the // ConfigSubscriber clears it - if (jrtReq.hasUpdatedGeneration()) { - setApplyOnRestart(jrtReq.responseIsApplyOnRestart()); - if (jrtReq.hasUpdatedConfig()) { - setNewConfig(jrtReq); + if (response.hasUpdatedGeneration()) { + setApplyOnRestart(response.responseIsApplyOnRestart()); + if (response.hasUpdatedConfig()) { + setNewConfig(response); } else { - setNewConfigAndGeneration(jrtReq); + setNewConfigAndGeneration(response); } } return newConfigOrException(); } + private JRTClientConfigRequest pollForNewConfig(long timeoutMillis) { + JRTClientConfigRequest response = pollQueue(timeoutMillis); + // There might be more than one response on the queue, so empty queue by polling with + // 0 timeout until queue is empty (returned value is null) + JRTClientConfigRequest temp; + do { + temp = pollQueue(0); + if (temp != null) + response = temp; + } while (temp != null); + + return response; + } + private boolean newConfigOrException() { // These flags may have been left true from a previous call, since ConfigSubscriber's nextConfig // not necessarily returned true and reset the flags then @@ -89,7 +97,7 @@ public class JRTConfigSubscription<T extends ConfigInstance> extends ConfigSubsc private JRTClientConfigRequest pollQueue(long timeoutMillis) { try { // Only valid responses are on queue, no need to validate - return reqQueue.poll(timeoutMillis, TimeUnit.MILLISECONDS); + return responseQueue.poll(timeoutMillis, TimeUnit.MILLISECONDS); } catch (InterruptedException e1) { throw new ConfigInterruptedException(e1); } @@ -133,11 +141,9 @@ public class JRTConfigSubscription<T extends ConfigInstance> extends ConfigSubsc return configInstance; } - // Will be called by JRTConfigRequester when there is a config with new generation for this subscription + // Called by JRTConfigRequester when there is a config with new generation for this subscription void updateConfig(JRTClientConfigRequest jrtReq) { - // We only want this latest generation to be in the queue, we do not preserve history in this system - reqQueue.clear(); - if ( ! reqQueue.offer(jrtReq)) + if ( ! responseQueue.offer(jrtReq)) setException(new ConfigurationRuntimeException("Failed offering returned request to queue of subscription " + this)); } @@ -145,14 +151,14 @@ public class JRTConfigSubscription<T extends ConfigInstance> extends ConfigSubsc public boolean subscribe(long timeout) { lastOK = Instant.now(); requester.request(this); - JRTClientConfigRequest req = reqQueue.peek(); + JRTClientConfigRequest req = responseQueue.peek(); while (req == null && (Instant.now().isBefore(lastOK.plus(Duration.ofMillis(timeout))))) { try { Thread.sleep(10); } catch (InterruptedException e) { throw new ConfigInterruptedException(e); } - req = reqQueue.peek(); + req = responseQueue.peek(); } return req != null; } @@ -160,11 +166,11 @@ public class JRTConfigSubscription<T extends ConfigInstance> extends ConfigSubsc @Override public void close() { super.close(); - reqQueue = new LinkedBlockingQueue<>() { + responseQueue = new LinkedBlockingQueue<>() { @SuppressWarnings("NullableProblems") @Override public void put(JRTClientConfigRequest e) { - // When closed, throw away all requests that callbacks try to put + // When closed, throw away all responses that callbacks try to put on queue } }; } diff --git a/config/src/test/java/com/yahoo/config/subscription/GenericConfigSubscriberTest.java b/config/src/test/java/com/yahoo/config/subscription/GenericConfigSubscriberTest.java index fc922cc3b07..61573fd19be 100644 --- a/config/src/test/java/com/yahoo/config/subscription/GenericConfigSubscriberTest.java +++ b/config/src/test/java/com/yahoo/config/subscription/GenericConfigSubscriberTest.java @@ -33,7 +33,7 @@ public class GenericConfigSubscriberTest { public void testSubscribeGeneric() throws InterruptedException { JRTConfigRequester requester = new JRTConfigRequester(new MockConnection(), tv); GenericConfigSubscriber sub = new GenericConfigSubscriber(requester); - final List<String> defContent = List.of("myVal int"); + List<String> defContent = List.of("myVal int"); GenericConfigHandle handle = sub.subscribe(new ConfigKey<>("simpletypes", "id", "config"), defContent, tv); @@ -46,9 +46,9 @@ public class GenericConfigSubscriberTest { assertFalse(handle.isChanged()); // Wait some time, config should be the same, but generation should be higher - Thread.sleep(tv.getFixedDelay() * 2); + Thread.sleep(tv.getFixedDelay() * 3); assertEquals("{}", getConfig(handle)); - assertTrue(handle.getRawConfig().getGeneration() > 1); + assertTrue("Unexpected generation (not > 1): " + handle.getRawConfig().getGeneration(), handle.getRawConfig().getGeneration() > 1); assertFalse(sub.nextConfig(false)); assertFalse(handle.isChanged()); } diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/ApplicationRepository.java b/configserver/src/main/java/com/yahoo/vespa/config/server/ApplicationRepository.java index 69098ea0030..02ca4ce14c4 100644 --- a/configserver/src/main/java/com/yahoo/vespa/config/server/ApplicationRepository.java +++ b/configserver/src/main/java/com/yahoo/vespa/config/server/ApplicationRepository.java @@ -33,6 +33,7 @@ import com.yahoo.path.Path; import com.yahoo.slime.Slime; import com.yahoo.transaction.NestedTransaction; import com.yahoo.transaction.Transaction; +import com.yahoo.vespa.applicationmodel.InfrastructureApplication; import com.yahoo.vespa.config.server.application.Application; import com.yahoo.vespa.config.server.application.ApplicationCuratorDatabase; import com.yahoo.vespa.config.server.application.ApplicationReindexing; @@ -57,8 +58,8 @@ import com.yahoo.vespa.config.server.http.LogRetriever; import com.yahoo.vespa.config.server.http.SecretStoreValidator; import com.yahoo.vespa.config.server.http.SimpleHttpFetcher; import com.yahoo.vespa.config.server.http.TesterClient; -import com.yahoo.vespa.config.server.http.v2.response.DeploymentMetricsResponse; import com.yahoo.vespa.config.server.http.v2.PrepareResult; +import com.yahoo.vespa.config.server.http.v2.response.DeploymentMetricsResponse; import com.yahoo.vespa.config.server.http.v2.response.ProtonMetricsResponse; import com.yahoo.vespa.config.server.metrics.DeploymentMetricsRetriever; import com.yahoo.vespa.config.server.metrics.ProtonMetricsRetriever; @@ -1123,7 +1124,7 @@ public class ApplicationRepository implements com.yahoo.config.provision.Deploye // most applications under hosted-vespa are not known to the model and it's OK for a user to get // logs for any host if they are authorized for the hosted-vespa tenant. if (hostname.isPresent() && HOSTED_VESPA_TENANT.equals(applicationId.tenant())) { - int port = List.of("zone-config-servers", "controller").contains(applicationId.application().value()) ? 19071 : 8080; + int port = List.of(InfrastructureApplication.CONFIG_SERVER.id(), InfrastructureApplication.CONTROLLER.id()).contains(applicationId) ? 19071 : 8080; return "http://" + hostname.get() + ":" + port + "/logs"; } diff --git a/container-core/abi-spec.json b/container-core/abi-spec.json index 174febca9df..d5be3ab52f2 100644 --- a/container-core/abi-spec.json +++ b/container-core/abi-spec.json @@ -2090,100 +2090,6 @@ "public static final java.lang.String[] CONFIG_DEF_SCHEMA" ] }, - "com.yahoo.jdisc.http.ServletPathsConfig$Builder": { - "superClass": "java.lang.Object", - "interfaces": [ - "com.yahoo.config.ConfigInstance$Builder" - ], - "attributes": [ - "public" - ], - "methods": [ - "public void <init>()", - "public void <init>(com.yahoo.jdisc.http.ServletPathsConfig)", - "public com.yahoo.jdisc.http.ServletPathsConfig$Builder servlets(java.lang.String, com.yahoo.jdisc.http.ServletPathsConfig$Servlets$Builder)", - "public com.yahoo.jdisc.http.ServletPathsConfig$Builder servlets(java.util.Map)", - "public com.yahoo.jdisc.http.ServletPathsConfig$Builder servlets(java.lang.String, java.util.function.Consumer)", - "public final boolean dispatchGetConfig(com.yahoo.config.ConfigInstance$Producer)", - "public final java.lang.String getDefMd5()", - "public final java.lang.String getDefName()", - "public final java.lang.String getDefNamespace()", - "public final boolean getApplyOnRestart()", - "public final void setApplyOnRestart(boolean)", - "public com.yahoo.jdisc.http.ServletPathsConfig build()" - ], - "fields": [ - "public java.util.Map servlets" - ] - }, - "com.yahoo.jdisc.http.ServletPathsConfig$Producer": { - "superClass": "java.lang.Object", - "interfaces": [ - "com.yahoo.config.ConfigInstance$Producer" - ], - "attributes": [ - "public", - "interface", - "abstract" - ], - "methods": [ - "public abstract void getConfig(com.yahoo.jdisc.http.ServletPathsConfig$Builder)" - ], - "fields": [] - }, - "com.yahoo.jdisc.http.ServletPathsConfig$Servlets$Builder": { - "superClass": "java.lang.Object", - "interfaces": [ - "com.yahoo.config.ConfigBuilder" - ], - "attributes": [ - "public" - ], - "methods": [ - "public void <init>()", - "public void <init>(com.yahoo.jdisc.http.ServletPathsConfig$Servlets)", - "public com.yahoo.jdisc.http.ServletPathsConfig$Servlets$Builder path(java.lang.String)", - "public com.yahoo.jdisc.http.ServletPathsConfig$Servlets build()" - ], - "fields": [] - }, - "com.yahoo.jdisc.http.ServletPathsConfig$Servlets": { - "superClass": "com.yahoo.config.InnerNode", - "interfaces": [], - "attributes": [ - "public", - "final" - ], - "methods": [ - "public void <init>(com.yahoo.jdisc.http.ServletPathsConfig$Servlets$Builder)", - "public java.lang.String path()" - ], - "fields": [] - }, - "com.yahoo.jdisc.http.ServletPathsConfig": { - "superClass": "com.yahoo.config.ConfigInstance", - "interfaces": [], - "attributes": [ - "public", - "final" - ], - "methods": [ - "public static java.lang.String getDefMd5()", - "public static java.lang.String getDefName()", - "public static java.lang.String getDefNamespace()", - "public static java.lang.String getDefVersion()", - "public void <init>(com.yahoo.jdisc.http.ServletPathsConfig$Builder)", - "public java.util.Map servlets()", - "public com.yahoo.jdisc.http.ServletPathsConfig$Servlets servlets(java.lang.String)" - ], - "fields": [ - "public static final java.lang.String CONFIG_DEF_MD5", - "public static final java.lang.String CONFIG_DEF_NAME", - "public static final java.lang.String CONFIG_DEF_NAMESPACE", - "public static final java.lang.String CONFIG_DEF_VERSION", - "public static final java.lang.String[] CONFIG_DEF_SCHEMA" - ] - }, "com.yahoo.jdisc.http.filter.DiscFilterRequest$ThreadLocalSimpleDateFormat": { "superClass": "java.lang.ThreadLocal", "interfaces": [], diff --git a/container-core/src/main/java/com/yahoo/container/servlet/package-info.java b/container-core/src/main/java/com/yahoo/container/servlet/package-info.java deleted file mode 100644 index 8ecb3cbe827..00000000000 --- a/container-core/src/main/java/com/yahoo/container/servlet/package-info.java +++ /dev/null @@ -1,7 +0,0 @@ -// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -// TODO Vespa 8 Remove export package -@ExportPackage -package com.yahoo.container.servlet; - -import com.yahoo.osgi.annotation.ExportPackage; - diff --git a/container-core/src/main/resources/configdefinitions/container.servlet.servlet-config.def b/container-core/src/main/resources/configdefinitions/container.servlet.servlet-config.def deleted file mode 100644 index 3cc65475913..00000000000 --- a/container-core/src/main/resources/configdefinitions/container.servlet.servlet-config.def +++ /dev/null @@ -1,5 +0,0 @@ -# Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -# TODO Vespa 8 Remove config definition -namespace=container.servlet -map{} string - diff --git a/container-core/src/main/resources/configdefinitions/jdisc.http.jdisc.http.servlet-paths.def b/container-core/src/main/resources/configdefinitions/jdisc.http.jdisc.http.servlet-paths.def deleted file mode 100644 index af788764364..00000000000 --- a/container-core/src/main/resources/configdefinitions/jdisc.http.jdisc.http.servlet-paths.def +++ /dev/null @@ -1,6 +0,0 @@ -# Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -# TODO Vespa 8 Remove config definition -namespace=jdisc.http - -# path by servlet componentId -servlets{}.path string diff --git a/container-core/src/test/java/com/yahoo/jdisc/http/server/jetty/FilterTestCase.java b/container-core/src/test/java/com/yahoo/jdisc/http/server/jetty/FilterTestCase.java index d5229add01b..c975f7c17c3 100644 --- a/container-core/src/test/java/com/yahoo/jdisc/http/server/jetty/FilterTestCase.java +++ b/container-core/src/test/java/com/yahoo/jdisc/http/server/jetty/FilterTestCase.java @@ -22,7 +22,6 @@ import com.yahoo.jdisc.http.ConnectorConfig; import com.yahoo.jdisc.http.HttpRequest; import com.yahoo.jdisc.http.HttpResponse; import com.yahoo.jdisc.http.ServerConfig; -import com.yahoo.jdisc.http.ServletPathsConfig; import com.yahoo.jdisc.http.filter.RequestFilter; import com.yahoo.jdisc.http.filter.ResponseFilter; import com.yahoo.jdisc.http.filter.ResponseHeaderFilter; @@ -585,7 +584,6 @@ public class FilterTestCase { bind(FilterBindings.class).toInstance(filterBindings); bind(ServerConfig.class).toInstance(new ServerConfig(new ServerConfig.Builder().strictFiltering(strictFiltering))); bind(ConnectorConfig.class).toInstance(new ConnectorConfig(new ConnectorConfig.Builder())); - bind(ServletPathsConfig.class).toInstance(new ServletPathsConfig(new ServletPathsConfig.Builder())); bind(ConnectionLog.class).toInstance(new VoidConnectionLog()); bind(RequestLog.class).toInstance(new VoidRequestLog()); } diff --git a/container-core/src/test/java/com/yahoo/jdisc/http/server/jetty/HttpServerConformanceTest.java b/container-core/src/test/java/com/yahoo/jdisc/http/server/jetty/HttpServerConformanceTest.java index 613c5e88cf2..baf198dde5d 100644 --- a/container-core/src/test/java/com/yahoo/jdisc/http/server/jetty/HttpServerConformanceTest.java +++ b/container-core/src/test/java/com/yahoo/jdisc/http/server/jetty/HttpServerConformanceTest.java @@ -7,7 +7,6 @@ import com.google.inject.util.Modules; import com.yahoo.container.logging.ConnectionLog; import com.yahoo.container.logging.RequestLog; import com.yahoo.jdisc.http.ServerConfig; -import com.yahoo.jdisc.http.ServletPathsConfig; import com.yahoo.jdisc.http.server.jetty.testutils.ConnectorFactoryRegistryModule; import com.yahoo.jdisc.test.ServerProviderConformanceTest; import org.apache.http.HttpResponse; @@ -773,8 +772,6 @@ public class HttpServerConformanceTest extends ServerProviderConformanceTest { .toInstance(new FilterBindings.Builder().build()); bind(ServerConfig.class) .toInstance(new ServerConfig(new ServerConfig.Builder())); - bind(ServletPathsConfig.class) - .toInstance(new ServletPathsConfig(new ServletPathsConfig.Builder())); bind(ConnectionLog.class) .toInstance(new VoidConnectionLog()); bind(RequestLog.class) 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 0208f9ecd0d..395f0642965 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 @@ -55,7 +55,7 @@ public interface NodeRepository { void removeArchiveUri(ZoneId zone, TenantName tenantName); /** Upgrade all nodes of given type to a new version */ - void upgrade(ZoneId zone, NodeType type, Version version); + void upgrade(ZoneId zone, NodeType type, Version version, boolean allowDowngrade); /** Upgrade OS for all nodes of given type to a new version */ void upgradeOs(ZoneId zone, NodeType type, Version version, Duration upgradeBudget); diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/organization/SystemMonitor.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/organization/SystemMonitor.java index 20dd0a8739d..f1fe2524e99 100644 --- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/organization/SystemMonitor.java +++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/organization/SystemMonitor.java @@ -4,7 +4,7 @@ package com.yahoo.vespa.hosted.controller.api.integration.organization; import com.yahoo.component.Version; /** - * Montitors a Vespa controller and its system. + * Monitors a Vespa controller and its system. * * @author jonmv */ @@ -14,7 +14,7 @@ public interface SystemMonitor { void reportSystemVersion(Version systemVersion, Confidence confidence); enum Confidence { - broken, low, normal, high; + aborted, broken, low, normal, high; } } diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/ApplicationController.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/ApplicationController.java index 39223d6c031..81f8831a8a7 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/ApplicationController.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/ApplicationController.java @@ -449,12 +449,12 @@ public class ApplicationController { } /** Deploy a system application to given zone */ - public void deploy(SystemApplication application, ZoneId zone, Version version) { + public void deploy(SystemApplication application, ZoneId zone, Version version, boolean allowDowngrade) { if (application.hasApplicationPackage()) { deploySystemApplicationPackage(application, zone, version); } else { // Deploy by calling node repository directly - configServer.nodeRepository().upgrade(zone, application.nodeType(), version); + configServer.nodeRepository().upgrade(zone, application.nodeType(), version, allowDowngrade); } } diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/ArchiveUriUpdater.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/ArchiveUriUpdater.java index 1d71fa66329..045960fdce2 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/ArchiveUriUpdater.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/ArchiveUriUpdater.java @@ -1,7 +1,6 @@ // Copyright Yahoo. 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.yahoo.config.provision.SystemName; import com.yahoo.config.provision.TenantName; import com.yahoo.config.provision.zone.ZoneId; import com.yahoo.vespa.hosted.controller.ApplicationController; @@ -31,7 +30,7 @@ public class ArchiveUriUpdater extends ControllerMaintainer { private final CuratorArchiveBucketDb archiveBucketDb; public ArchiveUriUpdater(Controller controller, Duration duration) { - super(controller, duration, ArchiveUriUpdater.class.getSimpleName(), SystemName.all()); + super(controller, duration); this.applications = controller.applications(); this.nodeRepository = controller.serviceRegistry().configServer().nodeRepository(); this.archiveBucketDb = controller.archiveBucketDb(); diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/DeploymentMetricsMaintainer.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/DeploymentMetricsMaintainer.java index aca154a4b5b..f196ca610c8 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/DeploymentMetricsMaintainer.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/DeploymentMetricsMaintainer.java @@ -1,7 +1,6 @@ // Copyright Yahoo. 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.yahoo.config.provision.SystemName; import com.yahoo.text.Text; import com.yahoo.vespa.hosted.controller.ApplicationController; import com.yahoo.vespa.hosted.controller.Controller; @@ -40,7 +39,7 @@ public class DeploymentMetricsMaintainer extends ControllerMaintainer { private final ApplicationController applications; public DeploymentMetricsMaintainer(Controller controller, Duration duration) { - super(controller, duration, DeploymentMetricsMaintainer.class.getSimpleName(), SystemName.all()); + super(controller, duration); this.applications = controller.applications(); } diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/EndpointCertificateMaintainer.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/EndpointCertificateMaintainer.java index f7e46aaa34a..e96afd0ba8a 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/EndpointCertificateMaintainer.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/EndpointCertificateMaintainer.java @@ -4,7 +4,6 @@ package com.yahoo.vespa.hosted.controller.maintenance; import com.google.common.collect.Sets; import com.google.inject.Inject; import com.yahoo.config.provision.ApplicationId; -import com.yahoo.config.provision.SystemName; import com.yahoo.container.jdisc.secretstore.SecretNotFoundException; import com.yahoo.container.jdisc.secretstore.SecretStore; import com.yahoo.log.LogLevel; @@ -54,7 +53,7 @@ public class EndpointCertificateMaintainer extends ControllerMaintainer { @Inject public EndpointCertificateMaintainer(Controller controller, Duration interval) { - super(controller, interval, null, SystemName.all()); + super(controller, interval); this.deploymentTrigger = controller.applications().deploymentTrigger(); this.clock = controller.clock(); this.secretStore = controller.secretStore(); diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/InfrastructureUpgrader.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/InfrastructureUpgrader.java index bb10410d2ef..82413f21222 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/InfrastructureUpgrader.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/InfrastructureUpgrader.java @@ -10,14 +10,19 @@ import com.yahoo.vespa.hosted.controller.Controller; import com.yahoo.vespa.hosted.controller.api.integration.configserver.Node; import com.yahoo.vespa.hosted.controller.api.integration.configserver.NodeFilter; import com.yahoo.vespa.hosted.controller.application.SystemApplication; +import com.yahoo.vespa.hosted.controller.versions.VersionTarget; import com.yahoo.yolean.Exceptions; import java.time.Duration; import java.util.Comparator; import java.util.EnumSet; +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.function.Function; import java.util.logging.Logger; @@ -26,7 +31,7 @@ import java.util.logging.Logger; * * @author mpolden */ -public abstract class InfrastructureUpgrader<VERSION> extends ControllerMaintainer { +public abstract class InfrastructureUpgrader<TARGET extends VersionTarget> extends ControllerMaintainer { private static final Logger log = Logger.getLogger(InfrastructureUpgrader.class.getName()); @@ -42,17 +47,19 @@ public abstract class InfrastructureUpgrader<VERSION> extends ControllerMaintain @Override protected double maintain() { - if (targetVersion().isEmpty()) return 1.0; - return upgradeAll(targetVersion().get(), managedApplications); + return target().map(target -> upgradeAll(target, managedApplications)) + .orElse(1.0); } /** Deploy a list of system applications until they converge on the given version */ - private double upgradeAll(VERSION target, List<SystemApplication> applications) { + private double upgradeAll(TARGET target, List<SystemApplication> applications) { int attempts = 0; int failures = 0; - for (List<ZoneApi> zones : upgradePolicy.asList()) { + // Invert zone order if we're downgrading + UpgradePolicy policy = target.downgrade() ? upgradePolicy.inverted() : upgradePolicy; + for (Set<ZoneApi> step : policy.steps()) { boolean converged = true; - for (ZoneApi zone : zones) { + for (ZoneApi zone : step) { try { attempts++; converged &= upgradeAll(target, applications, zone); @@ -76,10 +83,24 @@ public abstract class InfrastructureUpgrader<VERSION> extends ControllerMaintain } /** Returns whether all applications have converged to the target version in zone */ - private boolean upgradeAll(VERSION target, List<SystemApplication> applications, ZoneApi zone) { + private boolean upgradeAll(TARGET target, List<SystemApplication> applications, ZoneApi zone) { + Map<SystemApplication, Set<SystemApplication>> dependenciesByApplication = new HashMap<>(); + if (target.downgrade()) { // Invert dependencies when we're downgrading + for (var application : applications) { + dependenciesByApplication.computeIfAbsent(application, k -> new HashSet<>()); + for (var dependency : application.dependencies()) { + dependenciesByApplication.computeIfAbsent(dependency, k -> new HashSet<>()) + .add(application); + } + } + } else { + applications.forEach(app -> dependenciesByApplication.put(app, Set.copyOf(app.dependencies()))); + } boolean converged = true; - for (SystemApplication application : applications) { - if (convergedOn(target, application.dependencies(), zone)) { + for (var kv : dependenciesByApplication.entrySet()) { + SystemApplication application = kv.getKey(); + Set<SystemApplication> dependencies = kv.getValue(); + if (convergedOn(target, dependencies, zone)) { if (changeTargetTo(target, application, zone)) { upgrade(target, application, zone); } @@ -89,21 +110,21 @@ public abstract class InfrastructureUpgrader<VERSION> extends ControllerMaintain return converged; } - private boolean convergedOn(VERSION target, List<SystemApplication> applications, ZoneApi zone) { + private boolean convergedOn(TARGET target, Set<SystemApplication> applications, ZoneApi zone) { return applications.stream().allMatch(application -> convergedOn(target, application, zone)); } /** Returns whether target version for application in zone should be changed */ - protected abstract boolean changeTargetTo(VERSION target, SystemApplication application, ZoneApi zone); + protected abstract boolean changeTargetTo(TARGET target, SystemApplication application, ZoneApi zone); /** Upgrade component to target version. Implementation should be idempotent */ - protected abstract void upgrade(VERSION target, SystemApplication application, ZoneApi zone); + protected abstract void upgrade(TARGET target, SystemApplication application, ZoneApi zone); /** Returns whether application has converged to target version in zone */ - protected abstract boolean convergedOn(VERSION target, SystemApplication application, ZoneApi zone); + protected abstract boolean convergedOn(TARGET target, SystemApplication application, ZoneApi zone); - /** Returns the target version for the component upgraded by this, if any */ - protected abstract Optional<VERSION> targetVersion(); + /** Returns the version target for the component upgraded by this, if any */ + protected abstract Optional<TARGET> target(); /** Returns whether the upgrader should expect given node to upgrade */ protected abstract boolean expectUpgradeOf(Node node, SystemApplication application, ZoneApi zone); diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/OsUpgrader.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/OsUpgrader.java index a1e956737cc..fa64a2677f4 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/OsUpgrader.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/OsUpgrader.java @@ -66,7 +66,7 @@ public class OsUpgrader extends InfrastructureUpgrader<OsVersionTarget> { } @Override - protected Optional<OsVersionTarget> targetVersion() { + protected Optional<OsVersionTarget> target() { // Return target if we have nodes in this cloud on a lower version return controller().osVersionTarget(cloud) .filter(target -> controller().osVersionStatus().nodesIn(cloud).stream() @@ -90,7 +90,7 @@ public class OsUpgrader extends InfrastructureUpgrader<OsVersionTarget> { /** Returns the available upgrade budget for given zone */ private Duration zoneBudgetOf(Duration totalBudget, ZoneApi zone) { if (!spendBudgetOn(zone)) return Duration.ZERO; - long consecutiveZones = upgradePolicy.asList().stream() + long consecutiveZones = upgradePolicy.steps().stream() .filter(parallelZones -> parallelZones.stream().anyMatch(this::spendBudgetOn)) .count(); return totalBudget.dividedBy(consecutiveZones); diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/SystemUpgrader.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/SystemUpgrader.java index 8b0371e2c1a..99ab6d420cb 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/SystemUpgrader.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/SystemUpgrader.java @@ -8,7 +8,9 @@ import com.yahoo.text.Text; import com.yahoo.vespa.hosted.controller.Controller; import com.yahoo.vespa.hosted.controller.api.integration.configserver.Node; import com.yahoo.vespa.hosted.controller.application.SystemApplication; +import com.yahoo.vespa.hosted.controller.versions.VersionStatus; import com.yahoo.vespa.hosted.controller.versions.VespaVersion; +import com.yahoo.vespa.hosted.controller.versions.VespaVersionTarget; import java.time.Duration; import java.util.Optional; @@ -20,7 +22,7 @@ import java.util.logging.Logger; * * @author mpolden */ -public class SystemUpgrader extends InfrastructureUpgrader<Version> { +public class SystemUpgrader extends InfrastructureUpgrader<VespaVersionTarget> { private static final Logger log = Logger.getLogger(SystemUpgrader.class.getName()); @@ -31,19 +33,19 @@ public class SystemUpgrader extends InfrastructureUpgrader<Version> { } @Override - protected void upgrade(Version target, SystemApplication application, ZoneApi zone) { + protected void upgrade(VespaVersionTarget target, SystemApplication application, ZoneApi zone) { log.info(Text.format("Deploying %s version %s in %s", application.id(), target, zone.getId())); - controller().applications().deploy(application, zone.getId(), target); + controller().applications().deploy(application, zone.getId(), target.version(), target.downgrade()); } @Override - protected boolean convergedOn(Version target, SystemApplication application, ZoneApi zone) { + protected boolean convergedOn(VespaVersionTarget target, SystemApplication application, ZoneApi zone) { Optional<Version> minVersion = minVersion(zone, application, Node::currentVersion); // Skip application convergence check if there are no nodes belonging to the application in the zone if (minVersion.isEmpty()) return true; - return minVersion.get().equals(target) && - application.configConvergedIn(zone.getId(), controller(), Optional.of(target)); + return minVersion.get().equals(target.version()) && + application.configConvergedIn(zone.getId(), controller(), Optional.of(target.version())); } @Override @@ -52,30 +54,41 @@ public class SystemUpgrader extends InfrastructureUpgrader<Version> { } @Override - protected Optional<Version> targetVersion() { - return controller().readVersionStatus().controllerVersion() - .filter(vespaVersion -> !vespaVersion.isSystemVersion()) - .filter(vespaVersion -> vespaVersion.confidence() != VespaVersion.Confidence.broken) - .map(VespaVersion::versionNumber); + protected Optional<VespaVersionTarget> target() { + VersionStatus status = controller().readVersionStatus(); + Optional<VespaVersion> target = status.controllerVersion() + .filter(version -> { + Version systemVersion = status.systemVersion() + .map(VespaVersion::versionNumber) + .orElse(Version.emptyVersion); + return version.versionNumber().isAfter(systemVersion); + }) + .filter(version -> version.confidence() != VespaVersion.Confidence.broken); + boolean downgrade = target.isPresent() && target.get().confidence() == VespaVersion.Confidence.aborted; + if (downgrade) { + target = status.systemVersion(); + } + return target.map(VespaVersion::versionNumber) + .map(version -> new VespaVersionTarget(version, downgrade)); } @Override - protected boolean changeTargetTo(Version target, SystemApplication application, ZoneApi zone) { + protected boolean changeTargetTo(VespaVersionTarget target, SystemApplication application, ZoneApi zone) { if (application.hasApplicationPackage()) { // For applications with package we do not have a zone-wide version target. This means that we must check // the wanted version of each node. boolean zoneHasSharedRouting = controller().zoneRegistry().routingMethods(zone.getId()).stream() .anyMatch(RoutingMethod::isShared); return minVersion(zone, application, Node::wantedVersion) - .map(target::isAfter) // Upgrade if target is after any wanted version + .map(wantedVersion -> !wantedVersion.equals(target.version())) .orElse(zoneHasSharedRouting); // Always upgrade if zone uses shared routing, but has no nodes allocated yet } return controller().serviceRegistry().configServer().nodeRepository() .targetVersionsOf(zone.getId()) .vespaVersion(application.nodeType()) - .map(target::isAfter) // Upgrade if target is after current - .orElse(true); // Upgrade if target is unset + .map(wantedVersion -> !wantedVersion.equals(target.version())) + .orElse(true); // Always set target if there are no nodes } /** Returns whether node in application should be upgraded by this */ diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/Upgrader.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/Upgrader.java index be72ac2f09d..7a7eee7183b 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/Upgrader.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/Upgrader.java @@ -174,6 +174,11 @@ public class Upgrader extends ControllerMaintainer { /** Override confidence for given version. This will cause the computed confidence to be ignored */ public void overrideConfidence(Version version, Confidence confidence) { + if (confidence == Confidence.aborted && !version.isAfter(controller().readSystemVersion())) { + throw new IllegalArgumentException("Cannot override confidence to " + confidence + + " for version " + version.toFullString() + + ": Version may be in use by applications"); + } try (Lock lock = curator.lockConfidenceOverrides()) { Map<Version, Confidence> overrides = new LinkedHashMap<>(curator.readConfidenceOverrides()); overrides.put(version, confidence); diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/VersionStatusUpdater.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/VersionStatusUpdater.java index 6bf73c45965..6597d59027c 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/VersionStatusUpdater.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/VersionStatusUpdater.java @@ -14,6 +14,7 @@ import static com.yahoo.vespa.hosted.controller.api.integration.organization.Sys import static com.yahoo.vespa.hosted.controller.api.integration.organization.SystemMonitor.Confidence.high; import static com.yahoo.vespa.hosted.controller.api.integration.organization.SystemMonitor.Confidence.low; import static com.yahoo.vespa.hosted.controller.api.integration.organization.SystemMonitor.Confidence.normal; +import static com.yahoo.vespa.hosted.controller.api.integration.organization.SystemMonitor.Confidence.aborted; /** * This maintenance job periodically updates the version status. @@ -47,10 +48,11 @@ public class VersionStatusUpdater extends ControllerMaintainer { static SystemMonitor.Confidence convert(VespaVersion.Confidence confidence) { switch (confidence) { - case broken: return broken; - case low: return low; - case normal: return normal; - case high: return high; + case aborted: return aborted; + case broken: return broken; + case low: return low; + case normal: return normal; + case high: return high; default: throw new IllegalArgumentException("Unexpected confidence '" + confidence + "'"); } } diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/versions/OsVersionStatus.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/versions/OsVersionStatus.java index c70d9fd20cb..fc7fbe45767 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/versions/OsVersionStatus.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/versions/OsVersionStatus.java @@ -89,7 +89,7 @@ public class OsVersionStatus { private static List<ZoneApi> zonesToUpgrade(Controller controller) { return controller.zoneRegistry().osUpgradePolicies().stream() - .flatMap(upgradePolicy -> upgradePolicy.asList().stream()) + .flatMap(upgradePolicy -> upgradePolicy.steps().stream()) .flatMap(Collection::stream) .collect(Collectors.toUnmodifiableList()); } diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/versions/OsVersionTarget.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/versions/OsVersionTarget.java index a8fcb6c78fc..1c27058a6ef 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/versions/OsVersionTarget.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/versions/OsVersionTarget.java @@ -1,16 +1,18 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.hosted.controller.versions; +import com.yahoo.component.Version; + import java.time.Duration; import java.time.Instant; import java.util.Objects; /** - * An {@link OsVersion} and its upgrade budget. + * The OS version target for a cloud/system, containing the {@link OsVersion} and its upgrade budget. * * @author mpolden */ -public class OsVersionTarget implements Comparable<OsVersionTarget> { +public class OsVersionTarget implements VersionTarget, Comparable<OsVersionTarget> { // WARNING: Since there are multiple servers in a ZooKeeper cluster and they upgrade one by one // (and rewrite all nodes on startup), changes to the serialized format must be made @@ -63,4 +65,14 @@ public class OsVersionTarget implements Comparable<OsVersionTarget> { return osVersion.compareTo(o.osVersion); } + @Override + public Version version() { + return osVersion.version(); + } + + @Override + public boolean downgrade() { + return false; // Not supported by this target type + } + } diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/versions/VersionTarget.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/versions/VersionTarget.java new file mode 100644 index 00000000000..9b53d04c80f --- /dev/null +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/versions/VersionTarget.java @@ -0,0 +1,19 @@ +// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.vespa.hosted.controller.versions; + +import com.yahoo.component.Version; + +/** + * Interface for a version target of some kind of upgrade. + * + * @author mpolden + */ +public interface VersionTarget { + + /** The version of this target */ + Version version(); + + /** Returns whether this target is potentially a downgrade */ + boolean downgrade(); + +} diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/versions/VespaVersion.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/versions/VespaVersion.java index 660704d356b..792ec36bbb3 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/versions/VespaVersion.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/versions/VespaVersion.java @@ -130,6 +130,9 @@ public class VespaVersion implements Comparable<VespaVersion> { /** The confidence of a version. */ public enum Confidence { + /** Rollout was aborted. The system infrastructure should stay on, or roll back to, its current version */ + aborted, + /** This version has been proven defective */ broken, diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/versions/VespaVersionTarget.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/versions/VespaVersionTarget.java new file mode 100644 index 00000000000..fd5603b96b8 --- /dev/null +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/versions/VespaVersionTarget.java @@ -0,0 +1,33 @@ +// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.vespa.hosted.controller.versions; + +import com.yahoo.component.Version; + +import java.util.Objects; + +/** + * The target Vespa version for a system. + * + * @author mpolden + */ +public class VespaVersionTarget implements VersionTarget { + + private final Version version; + private final boolean downgrade; + + public VespaVersionTarget(Version version, boolean downgrade) { + this.version = Objects.requireNonNull(version); + this.downgrade = downgrade; + } + + @Override + public Version version() { + return version; + } + + @Override + public boolean downgrade() { + return downgrade; + } + +} diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/ControllerTester.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/ControllerTester.java index 6697ddac808..99c97b3bdd6 100644 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/ControllerTester.java +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/ControllerTester.java @@ -251,7 +251,7 @@ public final class ControllerTester { for (ZoneApi zone : zoneRegistry().zones().all().zones()) { for (SystemApplication application : systemApplications) { if (!application.hasApplicationPackage()) { - configServer().nodeRepository().upgrade(zone.getId(), application.nodeType(), version); + configServer().nodeRepository().upgrade(zone.getId(), application.nodeType(), version, false); } configServer().setVersion(version, application.id(), zone.getId()); configServer().convergeServices(application.id(), zone.getId()); 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 ef99183ecde..a2a1b4ba0a1 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 @@ -125,11 +125,17 @@ public class NodeRepositoryMock implements NodeRepository { } @Override - public void upgrade(ZoneId zone, NodeType type, Version version) { + public void upgrade(ZoneId zone, NodeType type, Version version, boolean allowDowngrade) { this.targetVersions.compute(zone, (ignored, targetVersions) -> { if (targetVersions == null) { targetVersions = TargetVersions.EMPTY; } + Optional<Version> current = targetVersions.vespaVersion(type); + if (current.isPresent() && version.isBefore(current.get()) && !allowDowngrade) { + throw new IllegalArgumentException("Changing wanted version for " + type + " in " + zone + " from " + + current.get() + " to " + version + + ", but downgrade is not allowed"); + } return targetVersions.withVespaVersion(type, version); }); // Bump wanted version of each node. This is done by InfrastructureProvisioner in a real node repository. 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 71a3ce262ad..604a42f3d19 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 @@ -295,7 +295,7 @@ public class MetricsReporterTest { var tester = new ControllerTester(); var reporter = createReporter(tester.controller()); var zone = ZoneId.from("prod.eu-west-1"); - tester.zoneRegistry().setUpgradePolicy(UpgradePolicy.create().upgrade(ZoneApiMock.from(zone))); + tester.zoneRegistry().setUpgradePolicy(UpgradePolicy.builder().upgrade(ZoneApiMock.from(zone)).build()); var systemUpgrader = new SystemUpgrader(tester.controller(), Duration.ofDays(1) ); tester.configServer().bootstrap(List.of(zone), SystemApplication.configServer); @@ -352,7 +352,7 @@ public class MetricsReporterTest { var reporter = createReporter(tester.controller()); var zone = ZoneId.from("prod.eu-west-1"); var cloud = CloudName.defaultName(); - tester.zoneRegistry().setOsUpgradePolicy(cloud, UpgradePolicy.create().upgrade(ZoneApiMock.from(zone))); + tester.zoneRegistry().setOsUpgradePolicy(cloud, UpgradePolicy.builder().upgrade(ZoneApiMock.from(zone)).build()); var osUpgrader = new OsUpgrader(tester.controller(), Duration.ofDays(1), CloudName.defaultName()); var statusUpdater = new OsVersionStatusUpdater(tester.controller(), Duration.ofDays(1) ); 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 ec1a5455413..3c3f0053e91 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 @@ -42,12 +42,13 @@ public class OsUpgraderTest { ZoneApi zone3 = zone("prod.us-central-1", cloud1); ZoneApi zone4 = zone("prod.us-east-3", cloud1); ZoneApi zone5 = zone("prod.us-north-1", cloud2); - UpgradePolicy upgradePolicy = UpgradePolicy.create() + UpgradePolicy upgradePolicy = UpgradePolicy.builder() .upgrade(zone0) .upgrade(zone1) .upgradeInParallel(zone2, zone3) .upgrade(zone5) // Belongs to a different cloud and is ignored by this upgrader - .upgrade(zone4); + .upgrade(zone4) + .build(); OsUpgrader osUpgrader = osUpgrader(upgradePolicy, cloud1, false); // Bootstrap system @@ -125,11 +126,12 @@ public class OsUpgraderTest { ZoneApi zone2 = zone("prod.us-west-1", cloud); ZoneApi zone3 = zone("prod.us-central-1", cloud); ZoneApi zone4 = zone("prod.eu-west-1", cloud); - UpgradePolicy upgradePolicy = UpgradePolicy.create() + UpgradePolicy upgradePolicy = UpgradePolicy.builder() .upgrade(zone0) .upgrade(zone1) .upgradeInParallel(zone2, zone3) - .upgrade(zone4); + .upgrade(zone4) + .build(); OsUpgrader osUpgrader = osUpgrader(upgradePolicy, cloud, true); // Bootstrap system @@ -189,9 +191,10 @@ public class OsUpgraderTest { CloudName cloud = CloudName.from("cloud"); ZoneApi zone1 = zone("dev.us-east-1", cloud); ZoneApi zone2 = zone("prod.us-west-1", cloud); - UpgradePolicy upgradePolicy = UpgradePolicy.create() + UpgradePolicy upgradePolicy = UpgradePolicy.builder() .upgrade(zone1) - .upgrade(zone2); + .upgrade(zone2) + .build(); OsUpgrader osUpgrader = osUpgrader(upgradePolicy, cloud, false); // Bootstrap system @@ -299,7 +302,7 @@ public class OsUpgraderTest { } private OsUpgrader osUpgrader(UpgradePolicy upgradePolicy, CloudName cloud, boolean reprovisionToUpgradeOs) { - var zones = upgradePolicy.asList().stream().flatMap(Collection::stream).collect(Collectors.toList()); + var zones = upgradePolicy.steps().stream().flatMap(Collection::stream).collect(Collectors.toList()); tester.zoneRegistry() .setZones(zones) .setOsUpgradePolicy(cloud, upgradePolicy); diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/OsVersionStatusUpdaterTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/OsVersionStatusUpdaterTest.java index f5ae6bafc65..f2d738bd2e1 100644 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/OsVersionStatusUpdaterTest.java +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/OsVersionStatusUpdaterTest.java @@ -28,11 +28,11 @@ public class OsVersionStatusUpdaterTest { OsVersionStatusUpdater statusUpdater = new OsVersionStatusUpdater(tester.controller(), Duration.ofDays(1) ); // Add all zones to upgrade policy - UpgradePolicy upgradePolicy = UpgradePolicy.create(); + UpgradePolicy.Builder upgradePolicy = UpgradePolicy.builder(); for (ZoneApi zone : tester.zoneRegistry().zones().controllerUpgraded().zones()) { upgradePolicy = upgradePolicy.upgrade(zone); } - tester.zoneRegistry().setOsUpgradePolicy(CloudName.defaultName(), upgradePolicy); + tester.zoneRegistry().setOsUpgradePolicy(CloudName.defaultName(), upgradePolicy.build()); // Initially empty assertSame(OsVersionStatus.empty, tester.controller().osVersionStatus()); 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 ff47b6cc231..c09d3ec3a92 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 @@ -21,6 +21,7 @@ import java.util.stream.Stream; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; /** * @author mpolden @@ -37,10 +38,11 @@ public class SystemUpgraderTest { @Test public void upgrade_system() { SystemUpgrader systemUpgrader = systemUpgrader( - UpgradePolicy.create() + UpgradePolicy.builder() .upgrade(zone1) .upgradeInParallel(zone2, zone3) .upgrade(zone4) + .build() ); Version version1 = Version.fromString("6.5"); @@ -137,7 +139,7 @@ public class SystemUpgraderTest { @Test public void upgrade_controller_with_non_converging_application() { - SystemUpgrader systemUpgrader = systemUpgrader(UpgradePolicy.create().upgrade(zone1)); + SystemUpgrader systemUpgrader = systemUpgrader(UpgradePolicy.builder().upgrade(zone1).build()); // Bootstrap system tester.configServer().bootstrap(List.of(zone1.getId()), SystemApplication.configServer, @@ -173,10 +175,11 @@ public class SystemUpgraderTest { @Test public void upgrade_system_containing_host_applications() { SystemUpgrader systemUpgrader = systemUpgrader( - UpgradePolicy.create() + UpgradePolicy.builder() .upgrade(zone1) .upgradeInParallel(zone2, zone3) .upgrade(zone4) + .build() ); Version version1 = Version.fromString("6.5"); @@ -223,7 +226,7 @@ public class SystemUpgraderTest { @Test public void downgrading_controller_never_downgrades_system() { - SystemUpgrader systemUpgrader = systemUpgrader(UpgradePolicy.create().upgrade(zone1)); + SystemUpgrader systemUpgrader = systemUpgrader(UpgradePolicy.builder().upgrade(zone1).build()); Version version = Version.fromString("6.5"); tester.upgradeSystem(version); @@ -242,7 +245,7 @@ public class SystemUpgraderTest { @Test public void upgrade_halts_on_broken_version() { - SystemUpgrader systemUpgrader = systemUpgrader(UpgradePolicy.create().upgrade(zone1).upgrade(zone2)); + SystemUpgrader systemUpgrader = systemUpgrader(UpgradePolicy.builder().upgrade(zone1).upgrade(zone2).build()); // Initial system version Version version1 = Version.fromString("6.5"); @@ -267,9 +270,7 @@ public class SystemUpgraderTest { convergeServices(SystemApplication.proxy, zone1); // Confidence is reduced to broken and next zone is not scheduled for upgrade - new Upgrader(tester.controller(), Duration.ofDays(1)) - .overrideConfidence(version2, VespaVersion.Confidence.broken); - tester.computeVersionStatus(); + overrideConfidence(version2, VespaVersion.Confidence.broken); systemUpgrader.maintain(); assertWantedVersion(List.of(SystemApplication.configServerHost, SystemApplication.proxyHost, SystemApplication.configServer, SystemApplication.proxy), version1, zone2); @@ -282,7 +283,7 @@ public class SystemUpgraderTest { tester.configServer().bootstrap(List.of(zone1.getId()), applications); tester.configServer().disallowConvergenceCheck(SystemApplication.proxy.id()); tester.zoneRegistry().exclusiveRoutingIn(zone1); - var systemUpgrader = systemUpgrader(UpgradePolicy.create().upgrade(zone1)); + var systemUpgrader = systemUpgrader(UpgradePolicy.builder().upgrade(zone1).build()); // System begins upgrade var version1 = Version.fromString("6.5"); @@ -299,6 +300,75 @@ public class SystemUpgraderTest { assertEquals(version1, tester.controller().readSystemVersion()); } + @Test + public void downgrade_from_aborted_version() { + SystemUpgrader systemUpgrader = systemUpgrader(UpgradePolicy.builder().upgrade(zone1).upgrade(zone2).upgrade(zone3).build()); + + Version version1 = Version.fromString("6.5"); + tester.configServer().bootstrap(List.of(zone1.getId(), zone2.getId(), zone3.getId()), SystemApplication.notController()); + tester.upgradeSystem(version1); + systemUpgrader.maintain(); + assertCurrentVersion(SystemApplication.notController(), version1, zone1, zone2, zone3); + + // Controller upgrades + Version version2 = Version.fromString("6.6"); + tester.upgradeController(version2); + assertControllerVersion(version2); + + // 2/3 zones upgrade + for (var zone : List.of(zone1, zone2)) { + systemUpgrader.maintain(); + completeUpgrade(List.of(SystemApplication.tenantHost, + SystemApplication.proxyHost, + SystemApplication.configServerHost), + version2, zone); + completeUpgrade(SystemApplication.configServer, version2, zone); + systemUpgrader.maintain(); + completeUpgrade(SystemApplication.proxy, version2, zone); + convergeServices(SystemApplication.proxy, zone); + } + + // Upgrade is aborted + overrideConfidence(version2, VespaVersion.Confidence.aborted); + + // Dependency graph is inverted and applications without dependencies downgrade first. Upgrade policy is + // also followed in inverted order + for (var zone : List.of(zone2, zone1)) { + systemUpgrader.maintain(); + completeUpgrade(List.of(SystemApplication.tenantHost, + SystemApplication.configServerHost, + SystemApplication.proxy), + version1, zone); + convergeServices(SystemApplication.proxy, zone); + List<SystemApplication> lastToDowngrade = List.of(SystemApplication.configServer, + SystemApplication.proxyHost); + assertWantedVersion(lastToDowngrade, version2, zone); + + // ... and then configserver and proxyhost + systemUpgrader.maintain(); + completeUpgrade(lastToDowngrade, version1, zone); + } + assertSystemVersion(version1); + + // Another version is released and system upgrades + Version version3 = Version.fromString("6.7"); + tester.upgradeSystem(version3); + assertEquals(version3, tester.controller().readSystemVersion()); + + // Attempt to abort current system version is rejected + try { + overrideConfidence(version3, VespaVersion.Confidence.aborted); + fail("Expected exception"); + } catch (IllegalArgumentException ignored) {} + systemUpgrader.maintain(); + assertWantedVersion(SystemApplication.notController(), version3, zone1, zone2, zone3); + } + + private void overrideConfidence(Version version, VespaVersion.Confidence confidence) { + new Upgrader(tester.controller(), Duration.ofDays(1)).overrideConfidence(version, confidence); + tester.computeVersionStatus(); + } + /** Simulate upgrade of nodes allocated to given application. In a real system this is done by the node itself */ private void completeUpgrade(SystemApplication application, Version version, ZoneApi first, ZoneApi... rest) { assertWantedVersion(application, version, first, rest); 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 6b6ced68b0a..7d17e97e66b 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 @@ -55,8 +55,8 @@ public class OsApiTest extends ControllerContainerTest { zoneRegistryMock().setSystemName(SystemName.cd) .setZones(zone1, zone2, zone3) .reprovisionToUpgradeOsIn(zone3) - .setOsUpgradePolicy(cloud1, UpgradePolicy.create().upgrade(zone1).upgrade(zone2)) - .setOsUpgradePolicy(cloud2, UpgradePolicy.create().upgrade(zone3)); + .setOsUpgradePolicy(cloud1, UpgradePolicy.builder().upgrade(zone1).upgrade(zone2).build()) + .setOsUpgradePolicy(cloud2, UpgradePolicy.builder().upgrade(zone3).build()); osUpgraders = List.of( new OsUpgrader(tester.controller(), Duration.ofDays(1), cloud1), diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/LoadBalancerProvisionerTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/LoadBalancerProvisionerTest.java index 614817bce84..885efed9241 100644 --- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/LoadBalancerProvisionerTest.java +++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/LoadBalancerProvisionerTest.java @@ -12,6 +12,7 @@ import com.yahoo.config.provision.NodeResources; import com.yahoo.config.provision.NodeType; import com.yahoo.config.provision.exception.LoadBalancerServiceException; import com.yahoo.transaction.NestedTransaction; +import com.yahoo.vespa.applicationmodel.InfrastructureApplication; import com.yahoo.vespa.flags.InMemoryFlagSource; import com.yahoo.vespa.flags.PermanentFlags; import com.yahoo.vespa.hosted.provision.Node; @@ -234,14 +235,13 @@ public class LoadBalancerProvisionerTest { @Test public void provision_load_balancer_config_server_cluster() { - ApplicationId configServerApp = ApplicationId.from("hosted-vespa", "zone-config-servers", "default"); - Supplier<List<LoadBalancer>> lbs = () -> tester.nodeRepository().loadBalancers().list(configServerApp).asList(); + Supplier<List<LoadBalancer>> lbs = () -> tester.nodeRepository().loadBalancers().list(InfrastructureApplication.CONFIG_SERVER.id()).asList(); var cluster = ClusterSpec.Id.from("zone-config-servers"); - var nodes = prepare(configServerApp, Capacity.fromRequiredNodeType(NodeType.config), + var nodes = prepare(InfrastructureApplication.CONFIG_SERVER.id(), Capacity.fromRequiredNodeType(NodeType.config), clusterRequest(ClusterSpec.Type.admin, cluster)); assertEquals(1, lbs.get().size()); assertEquals("Prepare provisions load balancer with reserved nodes", 2, lbs.get().get(0).instance().get().reals().size()); - tester.activate(configServerApp, nodes); + tester.activate(InfrastructureApplication.CONFIG_SERVER.id(), nodes); assertSame(LoadBalancer.State.active, lbs.get().get(0).state()); assertEquals(cluster, lbs.get().get(0).id().cluster()); } diff --git a/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/policy/HostedVespaOrchestration.java b/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/policy/HostedVespaOrchestration.java index 0028a5a252c..eb2b863aefb 100644 --- a/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/policy/HostedVespaOrchestration.java +++ b/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/policy/HostedVespaOrchestration.java @@ -1,8 +1,8 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.orchestrator.policy; -import com.yahoo.config.provision.ApplicationId; import com.yahoo.vespa.applicationmodel.ClusterId; +import com.yahoo.vespa.applicationmodel.InfrastructureApplication; import com.yahoo.vespa.applicationmodel.ServiceType; /** @@ -19,7 +19,7 @@ public class HostedVespaOrchestration { return new OrchestrationParams.Builder() // Controller host - .addApplicationParams(ApplicationId.fromSerializedForm("hosted-vespa:controller-host:default"), + .addApplicationParams(InfrastructureApplication.CONTROLLER_HOST, new ApplicationParams .Builder() .add(ClusterId.CONTROLLER, @@ -31,7 +31,7 @@ public class HostedVespaOrchestration { .build()) // Controller - .addApplicationParams(ApplicationId.fromSerializedForm("hosted-vespa:controller:default"), + .addApplicationParams(InfrastructureApplication.CONTROLLER, new ApplicationParams .Builder() .add(ClusterId.CONTROLLER, @@ -43,7 +43,7 @@ public class HostedVespaOrchestration { .build()) // Config server host - .addApplicationParams(ApplicationId.fromSerializedForm("hosted-vespa:configserver-host:default"), + .addApplicationParams(InfrastructureApplication.CONFIG_SERVER_HOST, new ApplicationParams .Builder() .add(ClusterId.CONFIG_SERVER_HOST, @@ -55,7 +55,7 @@ public class HostedVespaOrchestration { .build()) // Config server - .addApplicationParams(ApplicationId.fromSerializedForm("hosted-vespa:zone-config-servers:default"), + .addApplicationParams(InfrastructureApplication.CONFIG_SERVER, new ApplicationParams .Builder() .add(ClusterId.CONFIG_SERVER, @@ -67,7 +67,7 @@ public class HostedVespaOrchestration { .build()) // Proxy host - .addApplicationParams(ApplicationId.fromSerializedForm("hosted-vespa:proxy-host:default"), + .addApplicationParams(InfrastructureApplication.PROXY_HOST, new ApplicationParams .Builder() .add(ClusterId.PROXY_HOST, @@ -79,7 +79,7 @@ public class HostedVespaOrchestration { .build()) // Proxy - .addApplicationParams(ApplicationId.fromSerializedForm("hosted-vespa:routing:default"), + .addApplicationParams(InfrastructureApplication.PROXY, new ApplicationParams .Builder() .add(ClusterId.ROUTING, diff --git a/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/policy/OrchestrationParams.java b/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/policy/OrchestrationParams.java index 530f2dc8faf..43065831cbc 100644 --- a/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/policy/OrchestrationParams.java +++ b/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/policy/OrchestrationParams.java @@ -2,6 +2,7 @@ package com.yahoo.vespa.orchestrator.policy; import com.yahoo.config.provision.ApplicationId; +import com.yahoo.vespa.applicationmodel.InfrastructureApplication; import java.util.HashMap; import java.util.Map; @@ -20,8 +21,8 @@ public class OrchestrationParams { public Builder() {} - public Builder addApplicationParams(ApplicationId applicationId, ApplicationParams params) { - this.applicationParams.put(applicationId, params); + public Builder addApplicationParams(InfrastructureApplication application, ApplicationParams params) { + this.applicationParams.put(application.id(), params); return this; } diff --git a/service-monitor/src/main/java/com/yahoo/vespa/service/duper/ConfigServerApplication.java b/service-monitor/src/main/java/com/yahoo/vespa/service/duper/ConfigServerApplication.java index b57ddc6bc92..121b7e358e8 100644 --- a/service-monitor/src/main/java/com/yahoo/vespa/service/duper/ConfigServerApplication.java +++ b/service-monitor/src/main/java/com/yahoo/vespa/service/duper/ConfigServerApplication.java @@ -2,9 +2,9 @@ package com.yahoo.vespa.service.duper; import com.yahoo.config.provision.ClusterSpec; -import com.yahoo.config.provision.NodeType; import com.yahoo.config.provision.Zone; import com.yahoo.vespa.applicationmodel.ApplicationInstanceId; +import com.yahoo.vespa.applicationmodel.InfrastructureApplication; import com.yahoo.vespa.applicationmodel.ServiceType; /** @@ -15,7 +15,7 @@ import com.yahoo.vespa.applicationmodel.ServiceType; public class ConfigServerApplication extends ConfigServerLikeApplication { public ConfigServerApplication() { - super("zone-config-servers", NodeType.config, ClusterSpec.Type.admin, ServiceType.CONFIG_SERVER); + super(InfrastructureApplication.CONFIG_SERVER, ClusterSpec.Type.admin, ServiceType.CONFIG_SERVER); } /** diff --git a/service-monitor/src/main/java/com/yahoo/vespa/service/duper/ConfigServerHostApplication.java b/service-monitor/src/main/java/com/yahoo/vespa/service/duper/ConfigServerHostApplication.java index 909b86886b8..b970c3c6b77 100644 --- a/service-monitor/src/main/java/com/yahoo/vespa/service/duper/ConfigServerHostApplication.java +++ b/service-monitor/src/main/java/com/yahoo/vespa/service/duper/ConfigServerHostApplication.java @@ -1,12 +1,12 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.service.duper; -import com.yahoo.config.provision.NodeType; +import com.yahoo.vespa.applicationmodel.InfrastructureApplication; public class ConfigServerHostApplication extends HostAdminApplication { public ConfigServerHostApplication() { - super("configserver-host", NodeType.confighost); + super(InfrastructureApplication.CONFIG_SERVER_HOST); } } diff --git a/service-monitor/src/main/java/com/yahoo/vespa/service/duper/ConfigServerLikeApplication.java b/service-monitor/src/main/java/com/yahoo/vespa/service/duper/ConfigServerLikeApplication.java index 38808b66435..cc3aeddff01 100644 --- a/service-monitor/src/main/java/com/yahoo/vespa/service/duper/ConfigServerLikeApplication.java +++ b/service-monitor/src/main/java/com/yahoo/vespa/service/duper/ConfigServerLikeApplication.java @@ -3,7 +3,7 @@ package com.yahoo.vespa.service.duper; import com.yahoo.component.Version; import com.yahoo.config.provision.ClusterSpec; -import com.yahoo.config.provision.NodeType; +import com.yahoo.vespa.applicationmodel.InfrastructureApplication; import com.yahoo.vespa.applicationmodel.ServiceType; /** @@ -12,8 +12,8 @@ import com.yahoo.vespa.applicationmodel.ServiceType; * @author hakonhall */ public abstract class ConfigServerLikeApplication extends InfraApplication { - protected ConfigServerLikeApplication(String applicationName, NodeType nodeType, ClusterSpec.Type clusterType, ServiceType serviceType) { - super(applicationName, nodeType, clusterType, ClusterSpec.Id.from(applicationName), serviceType, 19071); + protected ConfigServerLikeApplication(InfrastructureApplication application, ClusterSpec.Type clusterType, ServiceType serviceType) { + super(application, clusterType, ClusterSpec.Id.from(application.applicationName()), serviceType, 19071); } @Override diff --git a/service-monitor/src/main/java/com/yahoo/vespa/service/duper/ControllerApplication.java b/service-monitor/src/main/java/com/yahoo/vespa/service/duper/ControllerApplication.java index 6c38149f662..c46b040d443 100644 --- a/service-monitor/src/main/java/com/yahoo/vespa/service/duper/ControllerApplication.java +++ b/service-monitor/src/main/java/com/yahoo/vespa/service/duper/ControllerApplication.java @@ -2,7 +2,7 @@ package com.yahoo.vespa.service.duper; import com.yahoo.config.provision.ClusterSpec; -import com.yahoo.config.provision.NodeType; +import com.yahoo.vespa.applicationmodel.InfrastructureApplication; import com.yahoo.vespa.applicationmodel.ServiceType; /** @@ -13,7 +13,7 @@ import com.yahoo.vespa.applicationmodel.ServiceType; public class ControllerApplication extends ConfigServerLikeApplication { public ControllerApplication() { - super("controller", NodeType.controller, ClusterSpec.Type.container, ServiceType.CONTROLLER); + super(InfrastructureApplication.CONTROLLER, ClusterSpec.Type.container, ServiceType.CONTROLLER); } } diff --git a/service-monitor/src/main/java/com/yahoo/vespa/service/duper/ControllerHostApplication.java b/service-monitor/src/main/java/com/yahoo/vespa/service/duper/ControllerHostApplication.java index eaf7537e45c..7e3c8c03cb7 100644 --- a/service-monitor/src/main/java/com/yahoo/vespa/service/duper/ControllerHostApplication.java +++ b/service-monitor/src/main/java/com/yahoo/vespa/service/duper/ControllerHostApplication.java @@ -1,13 +1,13 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.service.duper; -import com.yahoo.config.provision.NodeType; +import com.yahoo.vespa.applicationmodel.InfrastructureApplication; /** * @author mpolden */ public class ControllerHostApplication extends HostAdminApplication { public ControllerHostApplication() { - super("controller-host", NodeType.controllerhost); + super(InfrastructureApplication.CONTROLLER_HOST); } } diff --git a/service-monitor/src/main/java/com/yahoo/vespa/service/duper/DevHostApplication.java b/service-monitor/src/main/java/com/yahoo/vespa/service/duper/DevHostApplication.java index 65a679d2d33..e522b736290 100644 --- a/service-monitor/src/main/java/com/yahoo/vespa/service/duper/DevHostApplication.java +++ b/service-monitor/src/main/java/com/yahoo/vespa/service/duper/DevHostApplication.java @@ -1,13 +1,13 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.service.duper; -import com.yahoo.config.provision.NodeType; +import com.yahoo.vespa.applicationmodel.InfrastructureApplication; /** * @author mortent */ public class DevHostApplication extends HostAdminApplication { public DevHostApplication() { - super("dev-host", NodeType.devhost); + super(InfrastructureApplication.DEV_HOST); } } diff --git a/service-monitor/src/main/java/com/yahoo/vespa/service/duper/HostAdminApplication.java b/service-monitor/src/main/java/com/yahoo/vespa/service/duper/HostAdminApplication.java index 0b90350b7be..70a8e5e7443 100644 --- a/service-monitor/src/main/java/com/yahoo/vespa/service/duper/HostAdminApplication.java +++ b/service-monitor/src/main/java/com/yahoo/vespa/service/duper/HostAdminApplication.java @@ -2,7 +2,7 @@ package com.yahoo.vespa.service.duper; import com.yahoo.config.provision.ClusterSpec; -import com.yahoo.config.provision.NodeType; +import com.yahoo.vespa.applicationmodel.InfrastructureApplication; import com.yahoo.vespa.applicationmodel.ServiceType; /** @@ -12,11 +12,10 @@ public abstract class HostAdminApplication extends InfraApplication { public static final int HOST_ADMIN_HEALT_PORT = 8080; - protected HostAdminApplication(String applicationName, NodeType nodeType) { - super(applicationName, - nodeType, + protected HostAdminApplication(InfrastructureApplication application) { + super(application, ClusterSpec.Type.container, - ClusterSpec.Id.from(applicationName), + ClusterSpec.Id.from(application.applicationName()), ServiceType.HOST_ADMIN, HOST_ADMIN_HEALT_PORT); } diff --git a/service-monitor/src/main/java/com/yahoo/vespa/service/duper/InfraApplication.java b/service-monitor/src/main/java/com/yahoo/vespa/service/duper/InfraApplication.java index 8a62db87e7c..eccffa27930 100644 --- a/service-monitor/src/main/java/com/yahoo/vespa/service/duper/InfraApplication.java +++ b/service-monitor/src/main/java/com/yahoo/vespa/service/duper/InfraApplication.java @@ -10,12 +10,11 @@ import com.yahoo.config.provision.ApplicationId; import com.yahoo.config.provision.Capacity; import com.yahoo.config.provision.ClusterSpec; import com.yahoo.config.provision.HostName; -import com.yahoo.config.provision.NodeType; -import com.yahoo.config.provision.TenantName; import com.yahoo.config.provision.Zone; import com.yahoo.vespa.applicationmodel.ApplicationInstanceId; import com.yahoo.vespa.applicationmodel.ClusterId; import com.yahoo.vespa.applicationmodel.ConfigId; +import com.yahoo.vespa.applicationmodel.InfrastructureApplication; import com.yahoo.vespa.applicationmodel.ServiceType; import com.yahoo.vespa.applicationmodel.TenantId; import com.yahoo.vespa.service.health.StateV1HealthModel; @@ -35,30 +34,20 @@ import java.util.stream.Collectors; */ public abstract class InfraApplication implements InfraApplicationApi { - static final TenantName TENANT_NAME = TenantName.from("hosted-vespa"); - - private final ApplicationId applicationId; + private final InfrastructureApplication application; private final Capacity capacity; private final ClusterSpec.Type clusterSpecType; private final ClusterSpec.Id clusterSpecId; private final ServiceType serviceType; private final int healthPort; - public static ApplicationId createHostedVespaApplicationId(String applicationName) { - return new ApplicationId.Builder() - .tenant(TENANT_NAME) - .applicationName(applicationName) - .build(); - } - - protected InfraApplication(String applicationName, - NodeType nodeType, + protected InfraApplication(InfrastructureApplication application, ClusterSpec.Type clusterSpecType, ClusterSpec.Id clusterSpecId, ServiceType serviceType, int healthPort) { - this.applicationId = createHostedVespaApplicationId(applicationName); - this.capacity = Capacity.fromRequiredNodeType(nodeType); + this.application = application; + this.capacity = Capacity.fromRequiredNodeType(application.nodeType()); this.clusterSpecType = clusterSpecType; this.clusterSpecId = clusterSpecId; this.serviceType = serviceType; @@ -67,7 +56,7 @@ public abstract class InfraApplication implements InfraApplicationApi { @Override public ApplicationId getApplicationId() { - return applicationId; + return application.id(); } @Override @@ -97,16 +86,16 @@ public abstract class InfraApplication implements InfraApplicationApi { } public ApplicationInstanceId getApplicationInstanceId(Zone zone) { - return ApplicationInstanceGenerator.toApplicationInstanceId(applicationId, zone); + return ApplicationInstanceGenerator.toApplicationInstanceId(application.id(), zone); } public TenantId getTenantId() { - return new TenantId(applicationId.tenant().value()); + return new TenantId(application.id().tenant().value()); } public ApplicationInfo makeApplicationInfo(List<HostName> hostnames) { List<HostInfo> hostInfos = hostnames.stream().map(this::makeHostInfo).collect(Collectors.toList()); - return new ApplicationInfo(applicationId, 0, new HostsModel(hostInfos)); + return new ApplicationInfo(application.id(), 0, new HostsModel(hostInfos)); } private HostInfo makeHostInfo(HostName hostname) { @@ -147,7 +136,7 @@ public abstract class InfraApplication implements InfraApplicationApi { if (o == null || getClass() != o.getClass()) return false; InfraApplication that = (InfraApplication) o; return healthPort == that.healthPort && - Objects.equals(applicationId, that.applicationId) && + Objects.equals(application, that.application) && Objects.equals(capacity, that.capacity) && clusterSpecType == that.clusterSpecType && Objects.equals(clusterSpecId, that.clusterSpecId) && @@ -156,13 +145,13 @@ public abstract class InfraApplication implements InfraApplicationApi { @Override public int hashCode() { - return Objects.hash(applicationId, capacity, clusterSpecType, clusterSpecId, serviceType, healthPort); + return Objects.hash(application, capacity, clusterSpecType, clusterSpecId, serviceType, healthPort); } @Override public String toString() { return "InfraApplication{" + - "applicationId=" + applicationId + + "application=" + application + ", capacity=" + capacity + ", clusterSpecType=" + clusterSpecType + ", clusterSpecId=" + clusterSpecId + diff --git a/service-monitor/src/main/java/com/yahoo/vespa/service/duper/ProxyHostApplication.java b/service-monitor/src/main/java/com/yahoo/vespa/service/duper/ProxyHostApplication.java index f65dfd5577c..1819548c6cc 100644 --- a/service-monitor/src/main/java/com/yahoo/vespa/service/duper/ProxyHostApplication.java +++ b/service-monitor/src/main/java/com/yahoo/vespa/service/duper/ProxyHostApplication.java @@ -1,10 +1,10 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.service.duper; -import com.yahoo.config.provision.NodeType; +import com.yahoo.vespa.applicationmodel.InfrastructureApplication; public class ProxyHostApplication extends HostAdminApplication { public ProxyHostApplication() { - super("proxy-host", NodeType.proxyhost); + super(InfrastructureApplication.PROXY_HOST); } } diff --git a/service-monitor/src/main/java/com/yahoo/vespa/service/duper/TenantHostApplication.java b/service-monitor/src/main/java/com/yahoo/vespa/service/duper/TenantHostApplication.java index 7e834a15672..312dd5b64a7 100644 --- a/service-monitor/src/main/java/com/yahoo/vespa/service/duper/TenantHostApplication.java +++ b/service-monitor/src/main/java/com/yahoo/vespa/service/duper/TenantHostApplication.java @@ -1,10 +1,10 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.service.duper; -import com.yahoo.config.provision.NodeType; +import com.yahoo.vespa.applicationmodel.InfrastructureApplication; public class TenantHostApplication extends HostAdminApplication { public TenantHostApplication() { - super("tenant-host", NodeType.host); + super(InfrastructureApplication.TENANT_HOST); } } |