From 28ed9c13e8c26e17c0970b6d64f698c351887171 Mon Sep 17 00:00:00 2001 From: Jon Bratseth Date: Tue, 20 Nov 2018 14:17:48 +0100 Subject: Always load earlier major versions Since we have extended the semantics of major-version to also mean "upgrade this application also if you generally don't upgrade", we need to make sure specifying this doesn't cause config models on *earlier* versions to not load. --- .../config/server/modelfactory/ModelsBuilder.java | 23 ++++++++++++-------- .../config/server/session/RemoteSessionTest.java | 25 ++++++++++++++++++++++ 2 files changed, 39 insertions(+), 9 deletions(-) diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/modelfactory/ModelsBuilder.java b/configserver/src/main/java/com/yahoo/vespa/config/server/modelfactory/ModelsBuilder.java index 24309569c9d..92d4471c41c 100644 --- a/configserver/src/main/java/com/yahoo/vespa/config/server/modelfactory/ModelsBuilder.java +++ b/configserver/src/main/java/com/yahoo/vespa/config/server/modelfactory/ModelsBuilder.java @@ -78,10 +78,14 @@ public abstract class ModelsBuilder { Instant now) { Set versions = modelFactoryRegistry.allVersions(); - // If the application specifies a major, load models only for that + // If the application specifies a major, skip models on a newer major Optional requestedMajorVersion = applicationPackage.getMajorVersion(); - if (requestedMajorVersion.isPresent()) - versions = filterByMajorVersion(requestedMajorVersion.get(), versions); + if (requestedMajorVersion.isPresent()) { + versions = keepUpToMajorVersion(requestedMajorVersion.get(), versions); + if (versions.isEmpty()) + throw new UnknownVespaVersionException("No Vespa versions on or before major version " + + requestedMajorVersion.get() + " are present"); + } // Load models by one major version at the time as new major versions are allowed to be non-loadable // in the case where an existing application is incompatible with a new major version @@ -95,7 +99,7 @@ public abstract class ModelsBuilder { List allApplicationModels = new ArrayList<>(); for (int i = 0; i < majorVersions.size(); i++) { try { - allApplicationModels.addAll(buildModelVersions(filterByMajorVersion(majorVersions.get(i), versions), + allApplicationModels.addAll(buildModelVersions(keepMajorVersion(majorVersions.get(i), versions), applicationId, wantedNodeVespaVersion, applicationPackage, allocatedHosts, now)); @@ -181,11 +185,12 @@ public abstract class ModelsBuilder { return versions; } - private Set filterByMajorVersion(int majorVersion, Set versions) { - Set filteredVersions = versions.stream().filter(v -> v.getMajor() == majorVersion).collect(Collectors.toSet()); - if (filteredVersions.isEmpty()) - throw new UnknownVespaVersionException("No Vespa versions matching major version " + majorVersion + " are present"); - return filteredVersions; + private Set keepMajorVersion(int majorVersion, Set versions) { + return versions.stream().filter(v -> v.getMajor() == majorVersion).collect(Collectors.toSet()); + } + + private Set keepUpToMajorVersion(int majorVersion, Set versions) { + return versions.stream().filter(v -> v.getMajor() <= majorVersion).collect(Collectors.toSet()); } private Version findLatest(Set versionSet) { diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/session/RemoteSessionTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/session/RemoteSessionTest.java index ea0b187dee2..7a70e7958f8 100644 --- a/configserver/src/test/java/com/yahoo/vespa/config/server/session/RemoteSessionTest.java +++ b/configserver/src/test/java/com/yahoo/vespa/config/server/session/RemoteSessionTest.java @@ -42,6 +42,7 @@ import static org.junit.Assert.assertTrue; /** * @author Ulf Lilleengen + * @author bratseth */ public class RemoteSessionTest { @@ -187,6 +188,30 @@ public class RemoteSessionTest { // Does not cause an error because model version 3 is skipped } + @Test + public void require_that_an_application_package_can_limit_to_one_higher_major_version() { + ApplicationPackage application = + new MockApplicationPackage.Builder().withServices("") + .withDeploymentSpec("") + .build(); + assertTrue(application.getMajorVersion().isPresent()); + assertEquals(3, (int)application.getMajorVersion().get()); + + MockModelFactory failingFactory = new MockModelFactory(); + failingFactory.vespaVersion = Version.fromIntValues(4, 0, 0); + failingFactory.throwErrorOnLoad = true; + + MockModelFactory okFactory = new MockModelFactory(); + okFactory.vespaVersion = Version.fromIntValues(2, 0, 0); + okFactory.throwErrorOnLoad = false; + + SessionZooKeeperClient zkc = new MockSessionZKClient(curator, tenantName, 3, application); + RemoteSession session = createSession(4, zkc, Arrays.asList(okFactory, failingFactory), failingFactory.clock()); + session.loadPrepared(); + + // Does not cause an error because model version 4 is skipped + } + @Test public void require_that_session_status_is_updated() { SessionZooKeeperClient zkc = new MockSessionZKClient(curator, tenantName, 3); -- cgit v1.2.3