summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJon Bratseth <bratseth@yahoo-inc.com>2017-08-28 09:33:13 +0200
committerJon Bratseth <bratseth@yahoo-inc.com>2017-08-28 09:33:13 +0200
commitfc2f74f461fe2a049f3c7c362f83b48c0d3ae68b (patch)
treef37c4837ee3bb13eb0d1a3d3f5f1bce9eb52d208
parentde0d1ef384f75c8c0fc08503d75cfcaa5e494a5a (diff)
Allocation consistency between model versions
-rw-r--r--config-application-package/src/test/java/com/yahoo/config/application/OverrideProcessorTest.java3
-rw-r--r--config-model-api/src/main/java/com/yahoo/config/application/api/ApplicationFile.java2
-rw-r--r--config-model-api/src/main/java/com/yahoo/config/application/api/ApplicationPackage.java12
-rw-r--r--config-model-api/src/main/java/com/yahoo/config/model/api/Model.java26
-rw-r--r--config-model-api/src/main/java/com/yahoo/config/model/api/ModelContext.java8
-rw-r--r--config-model/src/main/java/com/yahoo/config/model/test/MockApplicationPackage.java1
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/HostResource.java2
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/VespaModel.java14
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/test/VespaModelTestCase.java2
-rw-r--r--config-provisioning/src/main/java/com/yahoo/config/provision/HostSpec.java16
-rw-r--r--config-provisioning/src/main/java/com/yahoo/config/provision/ProvisionInfo.java55
-rw-r--r--config-provisioning/src/test/java/com/yahoo/config/provision/ProvisionInfoTest.java16
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/deploy/ZooKeeperClient.java11
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/deploy/ZooKeeperDeployer.java10
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/modelfactory/ActivatedModelsBuilder.java2
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/session/LocalSession.java3
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/session/SessionPreparer.java47
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/session/SessionZooKeeperClient.java5
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/zookeeper/ConfigCurator.java2
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/zookeeper/ZKApplicationPackage.java94
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/zookeeper/ZKLiveApp.java7
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/deploy/ZooKeeperClientTest.java23
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/deploy/ZooKeeperDeployerTest.java3
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/SessionActiveHandlerTest.java2
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/provision/StaticProvisionerTest.java4
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/session/LocalSessionTest.java2
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/tenant/TenantRequestHandlerTest.java3
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/zookeeper/ZKApplicationPackageTest.java3
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/CapacityPolicies.java5
29 files changed, 211 insertions, 172 deletions
diff --git a/config-application-package/src/test/java/com/yahoo/config/application/OverrideProcessorTest.java b/config-application-package/src/test/java/com/yahoo/config/application/OverrideProcessorTest.java
index b80372ec9ff..32a1c4f847f 100644
--- a/config-application-package/src/test/java/com/yahoo/config/application/OverrideProcessorTest.java
+++ b/config-application-package/src/test/java/com/yahoo/config/application/OverrideProcessorTest.java
@@ -15,8 +15,7 @@ import java.io.IOException;
import java.io.StringReader;
/**
- * @author lulf
- * @since 5.22
+ * @author Ulf Lilleengen
*/
public class OverrideProcessorTest {
diff --git a/config-model-api/src/main/java/com/yahoo/config/application/api/ApplicationFile.java b/config-model-api/src/main/java/com/yahoo/config/application/api/ApplicationFile.java
index bcc8d222ca5..0384a5c7a1c 100644
--- a/config-model-api/src/main/java/com/yahoo/config/application/api/ApplicationFile.java
+++ b/config-model-api/src/main/java/com/yahoo/config/application/api/ApplicationFile.java
@@ -11,7 +11,7 @@ import java.util.List;
* An application file represents a file within an application package. This class can be used to traverse the entire
* application package file structure, as well as read and write files to it, and create directories.
*
- * @author Ulf Lillengen
+ * @author Ulf Lilleengen
*/
public abstract class ApplicationFile implements Comparable<ApplicationFile> {
diff --git a/config-model-api/src/main/java/com/yahoo/config/application/api/ApplicationPackage.java b/config-model-api/src/main/java/com/yahoo/config/application/api/ApplicationPackage.java
index 795e87b7690..23bbdd511b7 100644
--- a/config-model-api/src/main/java/com/yahoo/config/application/api/ApplicationPackage.java
+++ b/config-model-api/src/main/java/com/yahoo/config/application/api/ApplicationPackage.java
@@ -228,10 +228,22 @@ public interface ApplicationPackage {
throw new UnsupportedOperationException("This application package cannot write its metadata");
}
+ /**
+ * Returns the single host allocation info of this, or an empty map if no allocation is available
+ *
+ * @deprecated please use #getProvisionInfo
+ */
+ // TODO: Remove on Vespa 7
+ @Deprecated
default Map<Version, ProvisionInfo> getProvisionInfoMap() {
return Collections.emptyMap();
}
+ /** Returns the host allocation info of this, or empty if no allocation is available */
+ default Optional<ProvisionInfo> getProvisionInfo() {
+ return Optional.empty();
+ }
+
default Map<Version, FileRegistry> getFileRegistryMap() {
return Collections.emptyMap();
}
diff --git a/config-model-api/src/main/java/com/yahoo/config/model/api/Model.java b/config-model-api/src/main/java/com/yahoo/config/model/api/Model.java
index 0c038077fe4..db589ef5d21 100644
--- a/config-model-api/src/main/java/com/yahoo/config/model/api/Model.java
+++ b/config-model-api/src/main/java/com/yahoo/config/model/api/Model.java
@@ -16,8 +16,7 @@ import java.util.Collection;
* A {@link Model} represents the interface towards the model of an entire tenant, and defines methods
* for querying this model.
*
- * @author lulf
- * @since 5.1
+ * @author Ulf Lilleengen
*/
public interface Model {
@@ -60,9 +59,20 @@ public interface Model {
/**
* Get the provisioning info for this model.
+ *
* @return {@link ProvisionInfo} instance, if available.
+ * @deprecated use provisionInfo
*/
- Optional<ProvisionInfo> getProvisionInfo();
+ @Deprecated
+ // TODO: Remove this (and the implementation below) when no version older than 6.142 is deployed anywhere
+ default Optional<ProvisionInfo> getProvisionInfo() {
+ return Optional.of(provisionInfo());
+ }
+
+ @SuppressWarnings("deprecation")
+ default ProvisionInfo provisionInfo() {
+ return getProvisionInfo().get();
+ }
/**
* Returns whether this application allows serving config request for a different version.
@@ -71,11 +81,6 @@ public interface Model {
*/
default boolean allowModelVersionMismatch(Instant now) { return false; }
- /** @deprecated pass now. */
- // TODO: Remove this when no version older than 6.115 is deployed anywhere
- @Deprecated
- default boolean allowModelVersionMismatch() { return allowModelVersionMismatch(Clock.systemUTC().instant()); }
-
/**
* Returns whether old config models should be loaded (default) or not.
* Skipping old config models is a validation override which is useful when the old model
@@ -88,9 +93,4 @@ public interface Model {
*/
default boolean skipOldConfigModels(Instant now) { return false; }
- /** @deprecated pass now. */
- // TODO: Remove this when no version older than 6.115 is deployed anywhere
- @Deprecated
- default boolean skipOldConfigModels() { return skipOldConfigModels(Clock.systemUTC().instant()); }
-
}
diff --git a/config-model-api/src/main/java/com/yahoo/config/model/api/ModelContext.java b/config-model-api/src/main/java/com/yahoo/config/model/api/ModelContext.java
index 5afc570d81b..5b79415c132 100644
--- a/config-model-api/src/main/java/com/yahoo/config/model/api/ModelContext.java
+++ b/config-model-api/src/main/java/com/yahoo/config/model/api/ModelContext.java
@@ -17,7 +17,7 @@ import java.util.Set;
/**
* Model context containing state provided to model factories.
*
- * @author lulf
+ * @author Ulf Lilleengen
*/
public interface ModelContext {
@@ -31,11 +31,6 @@ public interface ModelContext {
Properties properties();
default Optional<File> appDir() { return Optional.empty();}
- /** @deprecated TODO: Remove this when no config models older than 6.98 are used */
- @SuppressWarnings("unused")
- @Deprecated
- default Optional<com.yahoo.config.provision.Version> vespaVersion() { return Optional.empty(); }
-
/** The Vespa version this model is built for */
Version modelVespaVersion();
@@ -50,4 +45,5 @@ public interface ModelContext {
Zone zone();
Set<Rotation> rotations();
}
+
}
diff --git a/config-model/src/main/java/com/yahoo/config/model/test/MockApplicationPackage.java b/config-model/src/main/java/com/yahoo/config/model/test/MockApplicationPackage.java
index 133d94c745b..8b97eb2503e 100644
--- a/config-model/src/main/java/com/yahoo/config/model/test/MockApplicationPackage.java
+++ b/config-model/src/main/java/com/yahoo/config/model/test/MockApplicationPackage.java
@@ -25,6 +25,7 @@ import java.util.*;
* @author tonytv
*/
public class MockApplicationPackage implements ApplicationPackage {
+
public static final String MUSIC_SEARCHDEFINITION = createSearchDefinition("music", "foo");
public static final String BOOK_SEARCHDEFINITION = createSearchDefinition("book", "bar");
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/HostResource.java b/config-model/src/main/java/com/yahoo/vespa/model/HostResource.java
index bc890755ca9..5e74a2ebc8a 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/HostResource.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/HostResource.java
@@ -22,7 +22,7 @@ import java.util.stream.Collectors;
* TODO: Merge with {@link Host}
* Host resources are ordered by their host order.
*
- * @author Ulf Lillengen
+ * @author Ulf Lilleengen
*/
public class HostResource implements Comparable<HostResource> {
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/VespaModel.java b/config-model/src/main/java/com/yahoo/vespa/model/VespaModel.java
index c61435ca831..d790e5c67b5 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/VespaModel.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/VespaModel.java
@@ -83,7 +83,7 @@ public final class VespaModel extends AbstractConfigProducerRoot implements Seri
public static final Logger log = Logger.getLogger(VespaModel.class.getPackage().toString());
private ConfigModelRepo configModelRepo = new ConfigModelRepo();
- private final Optional<ProvisionInfo> info;
+ private final ProvisionInfo provisionInfo;
/**
* The config id for the root config producer
@@ -146,7 +146,7 @@ public final class VespaModel extends AbstractConfigProducerRoot implements Seri
if (complete) { // create a a completed, frozen model
configModelRepo.readConfigModels(deployState, builder, root, configModelRegistry);
addServiceClusters(deployState.getApplicationPackage(), builder);
- this.info = Optional.of(createProvisionInfo()); // must happen after the two lines above
+ this.provisionInfo = ProvisionInfo.withHosts(root.getHostSystem().getHostSpecs()); // must happen after the two lines above
setupRouting();
this.fileDistributor = root.getFileDistributionConfigProducer().getFileDistributor();
getAdmin().addPerHostServices(getHostSystem().getHosts(), deployState.getProperties());
@@ -157,7 +157,7 @@ public final class VespaModel extends AbstractConfigProducerRoot implements Seri
this.deployState = null;
}
else { // create a model with no services instantiated and the given file distributor
- this.info = Optional.of(createProvisionInfo());
+ this.provisionInfo = ProvisionInfo.withHosts(root.getHostSystem().getHostSpecs());
this.fileDistributor = fileDistributor;
}
}
@@ -167,10 +167,6 @@ public final class VespaModel extends AbstractConfigProducerRoot implements Seri
return new VespaModel(new NullConfigModelRegistry(), deployState, false, new FileDistributor(deployState.getFileRegistry()));
}
- private ProvisionInfo createProvisionInfo() {
- return ProvisionInfo.withHosts(root.getHostSystem().getHostSpecs());
- }
-
private void validateWrapExceptions() {
try {
validate();
@@ -421,8 +417,8 @@ public final class VespaModel extends AbstractConfigProducerRoot implements Seri
}
@Override
- public Optional<ProvisionInfo> getProvisionInfo() {
- return info;
+ public ProvisionInfo provisionInfo() {
+ return provisionInfo;
}
private static Set<ConfigKey<?>> configsProduced(ConfigProducer cp) {
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/test/VespaModelTestCase.java b/config-model/src/test/java/com/yahoo/vespa/model/test/VespaModelTestCase.java
index 8102f358830..b35acffaf06 100644
--- a/config-model/src/test/java/com/yahoo/vespa/model/test/VespaModelTestCase.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/test/VespaModelTestCase.java
@@ -286,7 +286,7 @@ public class VespaModelTestCase {
.build())
.build();
VespaModel model = new VespaModel(new NullConfigModelRegistry(), deployState);
- ProvisionInfo info = model.getProvisionInfo().get();
+ ProvisionInfo info = model.provisionInfo();
assertEquals("Admin version 3 is ignored, and there are no other hosts to borrow for admin services", 0, info.getHosts().size());
}
diff --git a/config-provisioning/src/main/java/com/yahoo/config/provision/HostSpec.java b/config-provisioning/src/main/java/com/yahoo/config/provision/HostSpec.java
index 5d6b3fcaca4..a94660e142e 100644
--- a/config-provisioning/src/main/java/com/yahoo/config/provision/HostSpec.java
+++ b/config-provisioning/src/main/java/com/yahoo/config/provision/HostSpec.java
@@ -5,11 +5,13 @@ import com.google.common.collect.ImmutableList;
import java.util.ArrayList;
import java.util.List;
+import java.util.Objects;
import java.util.Optional;
/**
* A specification of a host and its role.
- * The identity of a host is determined by its name.
+ * This is a value object: Immutable and the identity is determined by all the content.
+ * Host specs are ordered by host name.
*
* @author hmusum
*/
@@ -19,7 +21,7 @@ public class HostSpec implements Comparable<HostSpec> {
private final String hostname;
/** Aliases of this host */
- private final List<String> aliases;
+ private final ImmutableList<String> aliases;
/** The current membership role of this host in the cluster it belongs to */
private final Optional<ClusterMembership> membership;
@@ -70,14 +72,20 @@ public class HostSpec implements Comparable<HostSpec> {
@Override
public boolean equals(Object o) {
+ if (o == this) return true;
if ( ! (o instanceof HostSpec)) return false;
+
HostSpec other = (HostSpec) o;
- return this.hostname().equals(other.hostname());
+ if ( ! this.hostname.equals(other.hostname)) return false;
+ if ( ! this.aliases.equals(other.aliases)) return false;
+ if ( ! this.membership.equals(other.membership)) return false;
+ if ( ! this.flavor.equals(other.flavor)) return false;
+ return true;
}
@Override
public int hashCode() {
- return hostname.hashCode();
+ return Objects.hash(hostname, aliases, membership, flavor);
}
@Override
diff --git a/config-provisioning/src/main/java/com/yahoo/config/provision/ProvisionInfo.java b/config-provisioning/src/main/java/com/yahoo/config/provision/ProvisionInfo.java
index 8bef1f7c9b7..4506f52e085 100644
--- a/config-provisioning/src/main/java/com/yahoo/config/provision/ProvisionInfo.java
+++ b/config-provisioning/src/main/java/com/yahoo/config/provision/ProvisionInfo.java
@@ -1,6 +1,7 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.config.provision;
+import com.google.common.collect.ImmutableSet;
import com.yahoo.slime.ArrayTraverser;
import com.yahoo.slime.Cursor;
import com.yahoo.slime.Inspector;
@@ -14,10 +15,12 @@ import java.util.Optional;
import java.util.Set;
/**
- * Information about hosts provisioned for an application, and (de)serialization of this information to/from JSON.
+ * The hosts allocated to an application (a better name would be "AllocatedHosts").
+ * This can be serialized to/from JSON.
+ * This is immutable.
*
- * @author lulf
- * @since 5.12
+ * @author Ulf Lilleengen
+ * @author bratseth
*/
public class ProvisionInfo {
@@ -28,10 +31,10 @@ public class ProvisionInfo {
private static final String hostSpecFlavor = "flavor";
private static final String hostSpecVespaVersion = "vespaVersion";
- private final Set<HostSpec> hosts = new LinkedHashSet<>();
+ private final ImmutableSet<HostSpec> hosts;
private ProvisionInfo(Set<HostSpec> hosts) {
- this.hosts.addAll(hosts);
+ this.hosts = ImmutableSet.copyOf(hosts);
}
public static ProvisionInfo withHosts(Set<HostSpec> hosts) {
@@ -40,13 +43,11 @@ public class ProvisionInfo {
private void toSlime(Cursor cursor) {
Cursor array = cursor.setArray(mappingKey);
- for (HostSpec host : hosts) {
- Cursor object = array.addObject();
- serializeHostSpec(object.setObject(hostSpecKey), host);
- }
+ for (HostSpec host : hosts)
+ toSlime(host, array.addObject().setObject(hostSpecKey));
}
- private void serializeHostSpec(Cursor cursor, HostSpec host) {
+ private void toSlime(HostSpec host, Cursor cursor) {
cursor.setString(hostSpecHostName, host.hostname());
if (host.membership().isPresent()) {
cursor.setString(hostSpecMembership, host.membership().get().stringValue());
@@ -56,9 +57,8 @@ public class ProvisionInfo {
cursor.setString(hostSpecFlavor, host.flavor().get().name());
}
- public Set<HostSpec> getHosts() {
- return Collections.unmodifiableSet(hosts);
- }
+ /** Returns the hosts of this allocation */
+ public Set<HostSpec> getHosts() { return hosts; }
private static ProvisionInfo fromSlime(Inspector inspector, Optional<NodeFlavors> nodeFlavors) {
Inspector array = inspector.field(mappingKey);
@@ -66,27 +66,27 @@ public class ProvisionInfo {
array.traverse(new ArrayTraverser() {
@Override
public void entry(int i, Inspector inspector) {
- hosts.add(deserializeHostSpec(inspector.field(hostSpecKey), nodeFlavors));
+ hosts.add(hostsFromSlime(inspector.field(hostSpecKey), nodeFlavors));
}
});
return new ProvisionInfo(hosts);
}
- private static HostSpec deserializeHostSpec(Inspector object, Optional<NodeFlavors> nodeFlavors) {
+ private static HostSpec hostsFromSlime(Inspector object, Optional<NodeFlavors> nodeFlavors) {
Optional<ClusterMembership> membership =
- object.field(hostSpecMembership).valid() ? Optional.of(readMembership(object)) : Optional.empty();
+ object.field(hostSpecMembership).valid() ? Optional.of(membershipFromSlime(object)) : Optional.empty();
Optional<Flavor> flavor =
- object.field(hostSpecFlavor).valid() ? readFlavor(object, nodeFlavors) : Optional.empty();
+ object.field(hostSpecFlavor).valid() ? flavorFromSlime(object, nodeFlavors) : Optional.empty();
return new HostSpec(object.field(hostSpecHostName).asString(),Collections.emptyList(), flavor, membership);
}
- private static ClusterMembership readMembership(Inspector object) {
+ private static ClusterMembership membershipFromSlime(Inspector object) {
return ClusterMembership.from(object.field(hostSpecMembership).asString(),
com.yahoo.component.Version.fromString(object.field(hostSpecVespaVersion).asString()));
}
- private static Optional<Flavor> readFlavor(Inspector object, Optional<NodeFlavors> nodeFlavors) {
+ private static Optional<Flavor> flavorFromSlime(Inspector object, Optional<NodeFlavors> nodeFlavors) {
return nodeFlavors.map(flavorMapper -> flavorMapper.getFlavor(object.field(hostSpecFlavor).asString()))
.orElse(Optional.empty());
}
@@ -100,12 +100,17 @@ public class ProvisionInfo {
public static ProvisionInfo fromJson(byte[] json, Optional<NodeFlavors> nodeFlavors) {
return fromSlime(SlimeUtils.jsonToSlime(json).get(), nodeFlavors);
}
-
- public ProvisionInfo merge(ProvisionInfo provisionInfo) {
- Set<HostSpec> mergedSet = new LinkedHashSet<>();
- mergedSet.addAll(this.hosts);
- mergedSet.addAll(provisionInfo.getHosts());
- return ProvisionInfo.withHosts(mergedSet);
+
+ @Override
+ public boolean equals(Object other) {
+ if (other == this) return true;
+ if ( ! (other instanceof ProvisionInfo)) return false;
+ return ((ProvisionInfo) other).hosts.equals(this.hosts);
+ }
+
+ @Override
+ public int hashCode() {
+ return hosts.hashCode();
}
}
diff --git a/config-provisioning/src/test/java/com/yahoo/config/provision/ProvisionInfoTest.java b/config-provisioning/src/test/java/com/yahoo/config/provision/ProvisionInfoTest.java
index 4fa69eb77e0..435b6e3a28a 100644
--- a/config-provisioning/src/test/java/com/yahoo/config/provision/ProvisionInfoTest.java
+++ b/config-provisioning/src/test/java/com/yahoo/config/provision/ProvisionInfoTest.java
@@ -13,8 +13,7 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
/**
- * @author lulf
- * @since 5.12
+ * @author Ulf Lilleengen
*/
public class ProvisionInfoTest {
@@ -32,19 +31,6 @@ public class ProvisionInfoTest {
assertProvisionInfo(info);
}
- @Test
- public void testProvisionInfoMerging() throws IOException {
- Set<HostSpec> hostsA = new LinkedHashSet<>(Collections.singleton(h1));
- Set<HostSpec> hostsB = new LinkedHashSet<>();
- hostsB.add(h2);
- hostsB.add(h3);
-
- ProvisionInfo infoA = ProvisionInfo.withHosts(hostsA);
- ProvisionInfo infoB = ProvisionInfo.withHosts(hostsB);
- assertProvisionInfo(infoA.merge(infoB));
- assertProvisionInfo(infoB.merge(infoA));
- }
-
private void assertProvisionInfo(ProvisionInfo info) throws IOException {
ProvisionInfo serializedInfo = ProvisionInfo.fromJson(info.toJson(), Optional.empty());
assertEquals(info.getHosts().size(), serializedInfo.getHosts().size());
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/deploy/ZooKeeperClient.java b/configserver/src/main/java/com/yahoo/vespa/config/server/deploy/ZooKeeperClient.java
index ea278596e80..b2bcba94662 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/deploy/ZooKeeperClient.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/deploy/ZooKeeperClient.java
@@ -25,7 +25,6 @@ import java.util.*;
* A class used for reading and writing application data to zookeeper.
*
* @author hmusum
- * @since 5.1
*/
public class ZooKeeperClient {
@@ -356,9 +355,8 @@ public class ZooKeeperClient {
}
}
- private void feedProvisionInfo(Version version, ProvisionInfo info) throws IOException {
- byte[] json = info.toJson();
- configCurator.putData(rootPath.append(ZKApplicationPackage.allocatedHostsNode).append(version.toSerializedForm()).getAbsolute(), json);
+ public void feedProvisionInfo(ProvisionInfo info) throws IOException {
+ configCurator.putData(rootPath.append(ZKApplicationPackage.allocatedHostsNode).getAbsolute(), info.toJson());
}
public void feedZKFileRegistries(Map<Version, FileRegistry> fileRegistryMap) {
@@ -367,9 +365,4 @@ public class ZooKeeperClient {
}
}
- public void feedProvisionInfos(Map<Version, ProvisionInfo> provisionInfoMap) throws IOException {
- for (Map.Entry<Version, ProvisionInfo> versionProvisionInfoEntry : provisionInfoMap.entrySet()) {
- feedProvisionInfo(versionProvisionInfoEntry.getKey(), versionProvisionInfoEntry.getValue());
- }
- }
}
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/deploy/ZooKeeperDeployer.java b/configserver/src/main/java/com/yahoo/vespa/config/server/deploy/ZooKeeperDeployer.java
index 246d7226cfd..9c0d7f69d19 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/deploy/ZooKeeperDeployer.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/deploy/ZooKeeperDeployer.java
@@ -14,7 +14,6 @@ import java.util.Map;
* Initialize must be called before each deploy.
*
* @author lulf
- * @since 5.1
*/
public class ZooKeeperDeployer {
@@ -28,15 +27,16 @@ public class ZooKeeperDeployer {
* Deploys an application package to zookeeper. initialize() must be called before calling this method.
*
* @param applicationPackage The application package to persist.
- * @param fileRegistryMap The file registries to persist.
- * @param provisionInfoMap The provisioning infos to persist.
+ * @param fileRegistryMap the file registries to persist.
+ * @param provisionInfo the provisioning info to persist.
* @throws IOException if deploying fails
*/
- public void deploy(ApplicationPackage applicationPackage, Map<Version, FileRegistry> fileRegistryMap, Map<Version, ProvisionInfo> provisionInfoMap) throws IOException {
+ public void deploy(ApplicationPackage applicationPackage, Map<Version, FileRegistry> fileRegistryMap,
+ ProvisionInfo provisionInfo) throws IOException {
zooKeeperClient.setupZooKeeper();
zooKeeperClient.feedZooKeeper(applicationPackage);
zooKeeperClient.feedZKFileRegistries(fileRegistryMap);
- zooKeeperClient.feedProvisionInfos(provisionInfoMap);
+ zooKeeperClient.feedProvisionInfo(provisionInfo);
}
public void cleanup() {
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/modelfactory/ActivatedModelsBuilder.java b/configserver/src/main/java/com/yahoo/vespa/config/server/modelfactory/ActivatedModelsBuilder.java
index a805d335c2e..86187a08d17 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/modelfactory/ActivatedModelsBuilder.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/modelfactory/ActivatedModelsBuilder.java
@@ -87,7 +87,7 @@ public class ActivatedModelsBuilder extends ModelsBuilder<Application> {
logger,
configDefinitionRepo,
getForVersionOrLatest(applicationPackage.getFileRegistryMap(), modelFactory.getVersion()).orElse(new MockFileRegistry()),
- createHostProvisioner(getForVersionOrLatest(applicationPackage.getProvisionInfoMap(), modelFactory.getVersion())),
+ createHostProvisioner(applicationPackage.getProvisionInfo()),
createModelContextProperties(applicationId),
Optional.empty(),
new com.yahoo.component.Version(modelFactory.getVersion().toString()),
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/session/LocalSession.java b/configserver/src/main/java/com/yahoo/vespa/config/server/session/LocalSession.java
index a222182f87a..0b8f1f67e79 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/session/LocalSession.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/session/LocalSession.java
@@ -30,8 +30,7 @@ import java.util.Optional;
* prepared. Deleting a local session will ensure that the local filesystem state and global zookeeper state is
* cleaned for this session.
*
- * @author lulf
- * @since 5.1
+ * @author Ulf Lilleengen
*/
// This is really the store of an application, whether it is active or in an edit session
// TODO: Separate the "application store" and "session" aspects - the latter belongs in the HTTP layer
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/session/SessionPreparer.java b/configserver/src/main/java/com/yahoo/vespa/config/server/session/SessionPreparer.java
index 0b76c57e142..3b96069c4e7 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/session/SessionPreparer.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/session/SessionPreparer.java
@@ -42,8 +42,7 @@ import javax.xml.transform.TransformerException;
/**
* A SessionPreparer is responsible for preparing a session given an application package.
*
- * @author lulf
- * @since 5.1
+ * @author Ulf Lilleengen
*/
public class SessionPreparer {
@@ -195,7 +194,7 @@ public class SessionPreparer {
vespaVersion,
logger,
prepareResult.getFileRegistries(),
- prepareResult.getProvisionInfos());
+ prepareResult.getProvisionInfo());
checkTimeout("write state to zookeeper");
}
@@ -236,10 +235,10 @@ public class SessionPreparer {
com.yahoo.component.Version vespaVersion,
DeployLogger deployLogger,
Map<Version, FileRegistry> fileRegistryMap,
- Map<Version, ProvisionInfo> provisionInfoMap) {
+ ProvisionInfo provisionInfo) {
ZooKeeperDeployer zkDeployer = zooKeeperClient.createDeployer(deployLogger);
try {
- zkDeployer.deploy(applicationPackage, fileRegistryMap, provisionInfoMap);
+ zkDeployer.deploy(applicationPackage, fileRegistryMap, provisionInfo);
zooKeeperClient.writeApplicationId(applicationId);
zooKeeperClient.writeVespaVersion(vespaVersion);
} catch (RuntimeException | IOException e) {
@@ -252,19 +251,20 @@ public class SessionPreparer {
private static class PrepareResult {
private final ImmutableList<PreparedModelsBuilder.PreparedModelResult> results;
+
+ private final ReconciliatedHostAllocations reconciliatedHostAllocations;
public PrepareResult(List<PreparedModelsBuilder.PreparedModelResult> results) {
this.results = ImmutableList.copyOf(results);
+ reconciliatedHostAllocations = new ReconciliatedHostAllocations(results);
}
/** Returns the results for each model as an immutable list */
public List<PreparedModelsBuilder.PreparedModelResult> asList() { return results; }
- public Map<Version, ProvisionInfo> getProvisionInfos() {
- return results.stream()
- .filter(result -> result.model.getProvisionInfo().isPresent())
- .collect(Collectors.toMap((prepareResult -> prepareResult.version),
- (prepareResult -> prepareResult.model.getProvisionInfo().get())));
+ /** Returns the host allocations resulting from this preparation. */
+ public ProvisionInfo getProvisionInfo() {
+ return reconciliatedHostAllocations.allocatedHosts();
}
public Map<Version, FileRegistry> getFileRegistries() {
@@ -290,4 +290,31 @@ public class SessionPreparer {
}
+ /**
+ * During model building each model version will request nodes allocated (from the node allocator)
+ * for each cluster specified by that model. As allocations are stable this should usually
+ * result in the same allocations for the same clusters across all model versions,
+ * otherwise we should fail this preparation as such inconsistencies lead to undefined behavior,
+ * and there is really just one true allocation (for a given cluster) to be activated in the node repository.
+ *
+ * However, these disagreements between allocations in each model version are allowed:
+ * - A node may be retired in some model version but not another. This allows model versions to change cluster sizes,
+ * and is ok because the system will converge on the latest version's opinion
+ * - Clusters may be present on some version but not on another. This does not lead to inconsistency
+ * and allows new model versions to introduce new clusters.
+ *
+ * For each cluster, the newest model version which has that cluster decides the correct retirement status of nodes
+ * (and all model versions having the cluster must have the same nodes).
+ *
+ * This class ensures these constraints and returns a reconciliated set of nodes which should be activated,
+ * given a set of model activation results.
+ */
+ private static final class ReconciliatedHostAllocations {
+
+ public ReconciliatedHostAllocations(List<PreparedModelsBuilder.PreparedModelResult> results) {
+
+ }
+
+ }
+
}
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/session/SessionZooKeeperClient.java b/configserver/src/main/java/com/yahoo/vespa/config/server/session/SessionZooKeeperClient.java
index a677c5cb7f9..3bd60d3d96c 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/session/SessionZooKeeperClient.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/session/SessionZooKeeperClient.java
@@ -190,9 +190,8 @@ public class SessionZooKeeperClient {
}
ProvisionInfo getProvisionInfo() {
- return loadApplicationPackage().getProvisionInfoMap().values().stream()
- .reduce((infoA, infoB) -> infoA.merge(infoB))
- .orElseThrow(() -> new IllegalStateException("Trying to read provision info, but no provision info exists"));
+ return loadApplicationPackage().getProvisionInfo()
+ .orElseThrow(() -> new IllegalStateException("Provision info does not exists"));
}
public ZooKeeperDeployer createDeployer(DeployLogger logger) {
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/zookeeper/ConfigCurator.java b/configserver/src/main/java/com/yahoo/vespa/config/server/zookeeper/ConfigCurator.java
index 80c1c44546f..c09fe5ae4bb 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/zookeeper/ConfigCurator.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/zookeeper/ConfigCurator.java
@@ -146,7 +146,7 @@ public class ConfigCurator {
/**
* Returns the data at a path, or null if the path does not exist.
*
- * @param path a String with a pathname.
+ * @param path a String with a pathname.
* @return a byte array with data.
*/
public byte[] getBytes(String path) {
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/zookeeper/ZKApplicationPackage.java b/configserver/src/main/java/com/yahoo/vespa/config/server/zookeeper/ZKApplicationPackage.java
index 4f591278a38..4aa4fc32483 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/zookeeper/ZKApplicationPackage.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/zookeeper/ZKApplicationPackage.java
@@ -2,6 +2,7 @@
package com.yahoo.vespa.config.server.zookeeper;
import com.google.common.base.Joiner;
+import com.yahoo.component.Version;
import com.yahoo.config.application.api.ApplicationMetaData;
import com.yahoo.config.application.api.ComponentInfo;
import com.yahoo.config.application.api.FileRegistry;
@@ -12,7 +13,6 @@ import com.yahoo.config.application.api.ApplicationPackage;
import com.yahoo.config.model.application.provider.*;
import com.yahoo.config.provision.NodeFlavors;
import com.yahoo.config.provision.ProvisionInfo;
-import com.yahoo.config.provision.Version;
import com.yahoo.io.IOUtils;
import com.yahoo.path.Path;
import com.yahoo.io.reader.NamedReader;
@@ -24,7 +24,13 @@ import com.yahoo.vespa.config.util.ConfigUtils;
import java.io.File;
import java.io.Reader;
import java.io.StringReader;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
/**
* Represents an application residing in zookeeper.
@@ -35,9 +41,9 @@ public class ZKApplicationPackage implements ApplicationPackage {
private ZKLiveApp liveApp;
- private final Map<Version, PreGeneratedFileRegistry> fileRegistryMap = new HashMap<>();
- private final Map<Version, ProvisionInfo> provisionInfoMap = new HashMap<>();
- private static final Version legacyVersion = Version.fromIntValues(0, 0, 0);
+ private final Map<com.yahoo.config.provision.Version, PreGeneratedFileRegistry> fileRegistryMap = new HashMap<>();
+ private final Optional<ProvisionInfo> provisionInfo;
+ private static final com.yahoo.config.provision.Version legacyVersion = com.yahoo.config.provision.Version.fromIntValues(0, 0, 0);
public static final String fileRegistryNode = "fileregistry";
public static final String allocatedHostsNode = "allocatedHosts";
@@ -48,32 +54,54 @@ public class ZKApplicationPackage implements ApplicationPackage {
liveApp = new ZKLiveApp(zk, appPath);
metaData = readMetaDataFromLiveApp(liveApp);
importFileRegistries(fileRegistryNode);
- importProvisionInfos(allocatedHostsNode, nodeFlavors);
+ provisionInfo = importProvisionInfos(allocatedHostsNode, nodeFlavors);
}
- private void importProvisionInfos(String allocatedHostsNode, Optional<NodeFlavors> nodeFlavors) {
- List<String> provisionInfoNodes = liveApp.getChildren(allocatedHostsNode);
- if (provisionInfoNodes.isEmpty()) {
- Optional<ProvisionInfo> provisionInfo = importProvisionInfo(allocatedHostsNode, nodeFlavors);
- provisionInfo.ifPresent(info -> provisionInfoMap.put(legacyVersion, info));
- } else {
- provisionInfoNodes.stream()
- .forEach(versionStr -> {
- Version version = Version.fromString(versionStr);
- Optional<ProvisionInfo> provisionInfo = importProvisionInfo(Joiner.on("/").join(allocatedHostsNode, versionStr),
- nodeFlavors);
- provisionInfo.ifPresent(info -> provisionInfoMap.put(version, info));
- });
+ private Optional<ProvisionInfo> importProvisionInfos(String allocatedHostsPath, Optional<NodeFlavors> nodeFlavors) {
+ if ( ! liveApp.exists(allocatedHostsPath)) return Optional.empty();
+ Optional<ProvisionInfo> provisionInfo = readProvisionInfo(allocatedHostsPath, nodeFlavors);
+ if ( ! provisionInfo.isPresent()) { // Read from legacy location. TODO: Remove when 6.142 is in production everywhere
+ List<String> provisionInfoByVersionNodes = liveApp.getChildren(allocatedHostsPath);
+ provisionInfo = newestOf(readProvisionInfosByVersion(provisionInfoByVersionNodes, nodeFlavors));
}
+ return provisionInfo;
+ }
+
+ private Map<Version, ProvisionInfo> readProvisionInfosByVersion(List<String> provisionInfoByVersionNodes, Optional<NodeFlavors> nodeFlavors) {
+ Map<Version, ProvisionInfo> provisionInfoMap = new HashMap<>();
+ provisionInfoByVersionNodes.stream()
+ .forEach(versionStr -> {
+ Version version = Version.fromString(versionStr);
+ Optional<ProvisionInfo> provisionInfo = readProvisionInfo(Joiner.on("/").join(allocatedHostsNode, versionStr),
+ nodeFlavors);
+ provisionInfo.ifPresent(info -> provisionInfoMap.put(version, info));
+ });
+ return provisionInfoMap;
}
- private Optional<ProvisionInfo> importProvisionInfo(String provisionInfoNode, Optional<NodeFlavors> nodeFlavors) {
- try {
- if (liveApp.exists(provisionInfoNode)) {
- return Optional.of(ProvisionInfo.fromJson(liveApp.getBytes(provisionInfoNode), nodeFlavors));
- } else {
- return Optional.empty();
+ private Optional<ProvisionInfo> newestOf(Map<Version, ProvisionInfo> provisionInfoMap) {
+ if (provisionInfoMap.isEmpty()) return Optional.empty();
+ Version newestVersion = null;
+ ProvisionInfo newestInfo = null;
+ for (Map.Entry<Version, ProvisionInfo> entry : provisionInfoMap.entrySet()) {
+ if (newestVersion == null || newestVersion.isBefore(entry.getKey())) {
+ newestVersion = entry.getKey();
+ newestInfo = entry.getValue();
}
+ }
+ return Optional.of(newestInfo);
+ }
+
+ /**
+ * Reads provision info at the given node.
+ *
+ * @return the provision info at this node or empty if there is no data at this path
+ */
+ private Optional<ProvisionInfo> readProvisionInfo(String provisionInfoPath, Optional<NodeFlavors> nodeFlavors) {
+ try {
+ byte[] data = liveApp.getBytes(provisionInfoPath);
+ if (data.length == 0) return Optional.empty(); // TODO: Remove this line (and make return non-optional) when 6.142 is in production everywhere
+ return Optional.of(ProvisionInfo.fromJson(data, nodeFlavors));
} catch (Exception e) {
throw new RuntimeException("Unable to read provision info", e);
}
@@ -85,9 +113,9 @@ public class ZKApplicationPackage implements ApplicationPackage {
fileRegistryMap.put(legacyVersion, importFileRegistry(fileRegistryNode));
} else {
fileRegistryNodes.stream()
- .forEach(versionStr -> {
- Version version = Version.fromString(versionStr);
- fileRegistryMap.put(version, importFileRegistry(Joiner.on("/").join(fileRegistryNode, versionStr)));
+ .forEach(version -> {
+ fileRegistryMap.put(com.yahoo.config.provision.Version.fromString(version),
+ importFileRegistry(Joiner.on("/").join(fileRegistryNode, version)));
});
}
}
@@ -147,16 +175,16 @@ public class ZKApplicationPackage implements ApplicationPackage {
return ret;
}
- public Map<Version, ProvisionInfo> getProvisionInfoMap() {
- return Collections.unmodifiableMap(provisionInfoMap);
+ public Optional<ProvisionInfo> getProvisionInfo() {
+ return provisionInfo;
}
@Override
- public Map<Version, FileRegistry> getFileRegistryMap() {
+ public Map<com.yahoo.config.provision.Version, FileRegistry> getFileRegistryMap() {
return Collections.unmodifiableMap(fileRegistryMap);
}
- private Optional<PreGeneratedFileRegistry> getPreGeneratedFileRegistry(Version vespaVersion) {
+ private Optional<PreGeneratedFileRegistry> getPreGeneratedFileRegistry(com.yahoo.config.provision.Version vespaVersion) {
// Assumes at least one file registry, which we always have.
Optional<PreGeneratedFileRegistry> fileRegistry = Optional.ofNullable(fileRegistryMap.get(vespaVersion));
if (!fileRegistry.isPresent()) {
@@ -243,7 +271,7 @@ public class ZKApplicationPackage implements ApplicationPackage {
}
@Override
- public List<ComponentInfo> getComponentsInfo(Version vespaVersion) {
+ public List<ComponentInfo> getComponentsInfo(com.yahoo.config.provision.Version vespaVersion) {
List<ComponentInfo> components = new ArrayList<>();
PreGeneratedFileRegistry fileRegistry = getPreGeneratedFileRegistry(vespaVersion).get();
for (String path : fileRegistry.getPaths()) {
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/zookeeper/ZKLiveApp.java b/configserver/src/main/java/com/yahoo/vespa/config/server/zookeeper/ZKLiveApp.java
index 88748cb7689..8084be1cefa 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/zookeeper/ZKLiveApp.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/zookeeper/ZKLiveApp.java
@@ -173,14 +173,11 @@ public class ZKLiveApp {
* Returns the full list of children (file names) in the given path.
*
* @param path a path relative to the currently active application
- * @return a list of file names
+ * @return a list of file names, which is empty (never null) if the path does not exist
*/
public List<String> getChildren(String path) {
String fullPath = getFullPath(path);
- if (! zk.exists(fullPath)) {
- log.fine("ZKApplicationPackage: " + fullPath + " is not a valid dir");
- return Collections.emptyList();
- }
+ if (! zk.exists(fullPath)) return Collections.emptyList();
return zk.getChildren(fullPath);
}
diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/deploy/ZooKeeperClientTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/deploy/ZooKeeperClientTest.java
index ac029c12b17..933c1e1d64d 100644
--- a/configserver/src/test/java/com/yahoo/vespa/config/server/deploy/ZooKeeperClientTest.java
+++ b/configserver/src/test/java/com/yahoo/vespa/config/server/deploy/ZooKeeperClientTest.java
@@ -1,6 +1,7 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.config.server.deploy;
+import com.google.common.collect.ImmutableSet;
import com.yahoo.config.application.api.ApplicationMetaData;
import com.yahoo.config.application.api.ApplicationPackage;
import com.yahoo.config.application.api.FileRegistry;
@@ -174,23 +175,15 @@ public class ZooKeeperClientTest extends TestWithCurator {
Path app = Path.fromString("/1");
ZooKeeperClient zooKeeperClient = new ZooKeeperClient(zk, logger, true, app);
zooKeeperClient.setupZooKeeper();
- zooKeeperClient.feedProvisionInfos(createProvisionInfos());
+ HostSpec host1 = new HostSpec("host1.yahoo.com", Collections.emptyList());
+ HostSpec host2 = new HostSpec("host2.yahoo.com", Collections.emptyList());
+ ImmutableSet<HostSpec> hosts = ImmutableSet.of(host1, host2);
+ zooKeeperClient.feedProvisionInfo(ProvisionInfo.withHosts(hosts));
Path hostsPath = app.append(ZKApplicationPackage.allocatedHostsNode);
assertTrue(zk.exists(hostsPath.getAbsolute()));
- assertEquals(0, zk.getBytes(hostsPath.getAbsolute()).length); // Changed from null
- assertTrue(zk.exists(hostsPath.append("1.2.3").getAbsolute()));
- assertTrue(zk.exists(hostsPath.append("3.2.1").getAbsolute()));
- assertTrue(zk.getBytes(hostsPath.append("1.2.3").getAbsolute()).length > 0);
- assertTrue(zk.getBytes(hostsPath.append("3.2.1").getAbsolute()).length > 0);
- }
-
- private Map<Version, ProvisionInfo> createProvisionInfos() {
- Map<Version, ProvisionInfo> provisionInfoMap = new HashMap<>();
- ProvisionInfo a = ProvisionInfo.withHosts(Collections.singleton(new HostSpec("host.yahoo.com", Collections.emptyList())));
- ProvisionInfo b = ProvisionInfo.withHosts(Collections.singleton(new HostSpec("host2.yahoo.com", Collections.emptyList())));
- provisionInfoMap.put(Version.fromIntValues(1, 2, 3), a);
- provisionInfoMap.put(Version.fromIntValues(3, 2, 1), b);
- return provisionInfoMap;
+
+ ProvisionInfo deserialized = ProvisionInfo.fromJson(zk.getBytes(hostsPath.getAbsolute()), Optional.empty());
+ assertEquals(hosts, deserialized.getHosts());
}
}
diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/deploy/ZooKeeperDeployerTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/deploy/ZooKeeperDeployerTest.java
index 9c7f12c2147..b7bd7918e02 100644
--- a/configserver/src/test/java/com/yahoo/vespa/config/server/deploy/ZooKeeperDeployerTest.java
+++ b/configserver/src/test/java/com/yahoo/vespa/config/server/deploy/ZooKeeperDeployerTest.java
@@ -4,6 +4,7 @@ package com.yahoo.vespa.config.server.deploy;
import com.yahoo.config.application.api.ApplicationPackage;
import com.yahoo.config.application.api.DeployLogger;
import com.yahoo.config.model.application.provider.*;
+import com.yahoo.config.provision.ProvisionInfo;
import com.yahoo.config.provision.Version;
import com.yahoo.io.IOUtils;
import com.yahoo.path.Path;
@@ -52,7 +53,7 @@ public class ZooKeeperDeployerTest {
ZooKeeperClient client = new ZooKeeperClient(configCurator, logger, true, appPath);
ZooKeeperDeployer deployer = new ZooKeeperDeployer(client);
- deployer.deploy(applicationPackage, Collections.singletonMap(Version.fromIntValues(1, 0, 0), new MockFileRegistry()), Collections.emptyMap());
+ deployer.deploy(applicationPackage, Collections.singletonMap(Version.fromIntValues(1, 0, 0), new MockFileRegistry()), ProvisionInfo.withHosts(Collections.emptySet()));
assertTrue(configCurator.exists(appPath.getAbsolute()));
}
diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/SessionActiveHandlerTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/SessionActiveHandlerTest.java
index 5e10f364aeb..1719b71b071 100644
--- a/configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/SessionActiveHandlerTest.java
+++ b/configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/SessionActiveHandlerTest.java
@@ -218,7 +218,7 @@ public class SessionActiveHandlerTest extends SessionHandlerTest {
ZooKeeperClient zkC = new ZooKeeperClient(configCurator, new BaseDeployLogger(), false, pathProvider.getSessionDirs().append(String.valueOf(sessionId)));
VespaModelFactory modelFactory = new VespaModelFactory(new NullConfigModelRegistry());
zkC.feedZKFileRegistries(Collections.singletonMap(modelFactory.getVersion(), new MockFileRegistry()));
- zkC.feedProvisionInfos(Collections.singletonMap(modelFactory.getVersion(), ProvisionInfo.withHosts(Collections.emptySet())));
+ zkC.feedProvisionInfo(ProvisionInfo.withHosts(Collections.emptySet()));
TestComponentRegistry componentRegistry = new TestComponentRegistry.Builder()
.curator(curator)
.configCurator(configCurator)
diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/provision/StaticProvisionerTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/provision/StaticProvisionerTest.java
index c54514eb097..2b936a42574 100644
--- a/configserver/src/test/java/com/yahoo/vespa/config/server/provision/StaticProvisionerTest.java
+++ b/configserver/src/test/java/com/yahoo/vespa/config/server/provision/StaticProvisionerTest.java
@@ -20,7 +20,7 @@ import java.io.IOException;
import static org.junit.Assert.assertEquals;
/**
- * @author lulf
+ * @author Ulf Lilleengen
*/
public class StaticProvisionerTest {
@@ -30,7 +30,7 @@ public class StaticProvisionerTest {
InMemoryProvisioner inMemoryHostProvisioner = new InMemoryProvisioner(false, "host1.yahoo.com", "host2.yahoo.com", "host3.yahoo.com", "host4.yahoo.com");
VespaModel firstModel = createModel(app, inMemoryHostProvisioner);
- StaticProvisioner staticProvisioner = new StaticProvisioner(firstModel.getProvisionInfo().get());
+ StaticProvisioner staticProvisioner = new StaticProvisioner(firstModel.provisionInfo());
VespaModel secondModel = createModel(app, staticProvisioner);
assertModelConfig(firstModel, secondModel);
diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/session/LocalSessionTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/session/LocalSessionTest.java
index f0086eabd26..f4be4d31943 100644
--- a/configserver/src/test/java/com/yahoo/vespa/config/server/session/LocalSessionTest.java
+++ b/configserver/src/test/java/com/yahoo/vespa/config/server/session/LocalSessionTest.java
@@ -160,7 +160,7 @@ public class LocalSessionTest {
zkc.createWriteStatusTransaction(Session.Status.NEW).commit();
ZooKeeperClient zkClient = new ZooKeeperClient(configCurator, new BaseDeployLogger(), false, appPath);
if (provisionInfo.isPresent()) {
- zkClient.feedProvisionInfos(Collections.singletonMap(Version.fromIntValues(0, 0, 0), provisionInfo.get()));
+ zkClient.feedProvisionInfo(provisionInfo.get());
}
zkClient.feedZKFileRegistries(Collections.singletonMap(Version.fromIntValues(0, 0, 0), new MockFileRegistry()));
File sessionDir = new File(tenantFileSystemDirs.path(), String.valueOf(sessionId));
diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/tenant/TenantRequestHandlerTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/tenant/TenantRequestHandlerTest.java
index 65f546e149a..3dccee1572c 100644
--- a/configserver/src/test/java/com/yahoo/vespa/config/server/tenant/TenantRequestHandlerTest.java
+++ b/configserver/src/test/java/com/yahoo/vespa/config/server/tenant/TenantRequestHandlerTest.java
@@ -8,6 +8,7 @@ import com.yahoo.config.model.application.provider.BaseDeployLogger;
import com.yahoo.config.model.application.provider.FilesApplicationPackage;
import com.yahoo.config.model.application.provider.MockFileRegistry;
import com.yahoo.config.provision.ApplicationName;
+import com.yahoo.config.provision.ProvisionInfo;
import com.yahoo.config.provision.Version;
import com.yahoo.io.IOUtils;
import com.yahoo.path.Path;
@@ -94,7 +95,7 @@ public class TenantRequestHandlerTest extends TestWithCurator {
File app = tempFolder.newFolder();
IOUtils.copyDirectory(appDir, app);
ZooKeeperDeployer deployer = zkc.createDeployer(new BaseDeployLogger());
- deployer.deploy(FilesApplicationPackage.fromFile(appDir), Collections.singletonMap(vespaVersion, new MockFileRegistry()), Collections.emptyMap());
+ deployer.deploy(FilesApplicationPackage.fromFile(appDir), Collections.singletonMap(vespaVersion, new MockFileRegistry()), ProvisionInfo.withHosts(Collections.emptySet()));
}
private ApplicationSet reloadConfig(long id, Clock clock) {
diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/zookeeper/ZKApplicationPackageTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/zookeeper/ZKApplicationPackageTest.java
index abc77a91c51..9e91b97806d 100644
--- a/configserver/src/test/java/com/yahoo/vespa/config/server/zookeeper/ZKApplicationPackageTest.java
+++ b/configserver/src/test/java/com/yahoo/vespa/config/server/zookeeper/ZKApplicationPackageTest.java
@@ -64,8 +64,7 @@ public class ZKApplicationPackageTest extends TestWithCurator {
assertTrue(zkApp.getFileRegistryMap().containsKey(goodVersion));
assertFalse(zkApp.getFileRegistryMap().containsKey(Version.fromIntValues(0, 0, 0)));
assertThat(zkApp.getFileRegistryMap().get(goodVersion).fileSourceHost(), is("dummyfiles"));
- assertTrue(zkApp.getProvisionInfoMap().containsKey(goodVersion));
- ProvisionInfo readInfo = zkApp.getProvisionInfoMap().get(goodVersion);
+ ProvisionInfo readInfo = zkApp.getProvisionInfo().get();
assertThat(Utf8.toString(readInfo.toJson()), is(Utf8.toString(provisionInfo.toJson())));
assertThat(readInfo.getHosts().iterator().next().flavor(), is(TEST_FLAVOR));
assertTrue(zkApp.getDeployment().isPresent());
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/CapacityPolicies.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/CapacityPolicies.java
index 914658302b6..e2ff17ba782 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/CapacityPolicies.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/CapacityPolicies.java
@@ -24,7 +24,6 @@ public class CapacityPolicies {
this.flavors = flavors;
}
- /** provides capacity defaults for various environments */
public int decideSize(Capacity requestedCapacity) {
int requestedNodes = requestedCapacity.nodeCount();
if (requestedCapacity.isRequired()) return requestedNodes;
@@ -39,10 +38,10 @@ public class CapacityPolicies {
}
public Flavor decideFlavor(Capacity requestedCapacity, ClusterSpec cluster, Optional<String> defaultFlavorOverride) {
- // for now, always use requested docker flavor when requested
+ // for now, always use the requested flavor if a docker flavor is requested
Optional<String> requestedFlavor = requestedCapacity.flavor();
if (requestedFlavor.isPresent() &&
- flavors.getFlavorOrThrow(requestedFlavor.get()).getType() == Flavor.Type.DOCKER_CONTAINER)
+ flavors.getFlavorOrThrow(requestedFlavor.get()).getType() == Flavor.Type.DOCKER_CONTAINER)
return flavors.getFlavorOrThrow(requestedFlavor.get());
String defaultFlavorName = defaultFlavorOverride.isPresent() ?