diff options
18 files changed, 74 insertions, 357 deletions
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 e6fef42d67e..d8c017b7775 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 @@ -49,7 +49,7 @@ public interface ModelContext { String athenzDnsSuffix(); boolean hostedVespa(); Zone zone(); - Set<Rotation> rotations(); + default Set<Rotation> rotations() { return Set.of(); } // TODO(mpolden): Remove once 7.122 is the oldest config model Set<ContainerEndpoint> endpoints(); boolean isBootstrap(); boolean isFirstTimeDeployment(); diff --git a/config-model/src/main/java/com/yahoo/config/model/deploy/DeployState.java b/config-model/src/main/java/com/yahoo/config/model/deploy/DeployState.java index e8e12888768..0f43be96e73 100644 --- a/config-model/src/main/java/com/yahoo/config/model/deploy/DeployState.java +++ b/config-model/src/main/java/com/yahoo/config/model/deploy/DeployState.java @@ -71,7 +71,6 @@ public class DeployState implements ConfigDefinitionStore { private final Optional<Model> previousModel; private final ModelContext.Properties properties; private final Version vespaVersion; - private final Set<Rotation> rotations; private final Set<ContainerEndpoint> endpoints; private final Zone zone; private final QueryProfiles queryProfiles; @@ -105,7 +104,6 @@ public class DeployState implements ConfigDefinitionStore { Optional<ApplicationPackage> permanentApplicationPackage, Optional<ConfigDefinitionRepo> configDefinitionRepo, java.util.Optional<Model> previousModel, - Set<Rotation> rotations, Set<ContainerEndpoint> endpoints, Collection<MlModelImporter> modelImporters, Zone zone, @@ -125,7 +123,6 @@ public class DeployState implements ConfigDefinitionStore { this.documentModel = searchDocumentModel.getDocumentModel(); this.permanentApplicationPackage = permanentApplicationPackage; this.configDefinitionRepo = configDefinitionRepo; - this.rotations = rotations; this.endpoints = Set.copyOf(endpoints); this.zone = zone; this.queryProfiles = queryProfiles; // TODO: Remove this by seeing how pagetemplates are propagated @@ -242,10 +239,6 @@ public class DeployState implements ConfigDefinitionStore { return properties.hostedVespa(); } - public Set<Rotation> getRotations() { - return this.rotations; // todo: consider returning a copy or immutable view - } - public Set<ContainerEndpoint> getEndpoints() { return endpoints; } @@ -293,7 +286,6 @@ public class DeployState implements ConfigDefinitionStore { private Version version = new Version(1, 0, 0); private Optional<ConfigDefinitionRepo> configDefinitionRepo = Optional.empty(); private Optional<Model> previousModel = Optional.empty(); - private Set<Rotation> rotations = new HashSet<>(); private Set<ContainerEndpoint> endpoints = Set.of(); private Collection<MlModelImporter> modelImporters = Collections.emptyList(); private Zone zone = Zone.defaultZone(); @@ -346,11 +338,6 @@ public class DeployState implements ConfigDefinitionStore { return this; } - public Builder rotations(Set<Rotation> rotations) { - this.rotations = rotations; - return this; - } - public Builder endpoints(Set<ContainerEndpoint> endpoints) { this.endpoints = endpoints; return this; @@ -396,7 +383,6 @@ public class DeployState implements ConfigDefinitionStore { permanentApplicationPackage, configDefinitionRepo, previousModel, - rotations, endpoints, modelImporters, zone, diff --git a/config-model/src/main/java/com/yahoo/config/model/deploy/TestProperties.java b/config-model/src/main/java/com/yahoo/config/model/deploy/TestProperties.java index c304e7efa09..dc64bec964e 100644 --- a/config-model/src/main/java/com/yahoo/config/model/deploy/TestProperties.java +++ b/config-model/src/main/java/com/yahoo/config/model/deploy/TestProperties.java @@ -8,7 +8,6 @@ import com.yahoo.config.model.api.ModelContext; import com.yahoo.config.model.api.TlsSecrets; import com.yahoo.config.provision.ApplicationId; import com.yahoo.config.provision.HostName; -import com.yahoo.config.provision.Rotation; import com.yahoo.config.provision.Zone; import java.net.URI; @@ -25,6 +24,7 @@ import java.util.Set; * @author hakonhall */ public class TestProperties implements ModelContext.Properties { + private boolean multitenant = false; private ApplicationId applicationId = ApplicationId.defaultId(); private List<ConfigServerSpec> configServerSpecs = Collections.emptyList(); @@ -33,7 +33,6 @@ public class TestProperties implements ModelContext.Properties { private String athenzDnsSuffix = null; private boolean hostedVespa = false; private Zone zone; - private Set<Rotation> rotations; private Set<ContainerEndpoint> endpoints = Collections.emptySet(); private boolean isBootstrap = false; private boolean isFirstTimeDeployment = false; @@ -51,7 +50,6 @@ public class TestProperties implements ModelContext.Properties { @Override public String athenzDnsSuffix() { return athenzDnsSuffix; } @Override public boolean hostedVespa() { return hostedVespa; } @Override public Zone zone() { return zone; } - @Override public Set<Rotation> rotations() { return rotations; } @Override public Set<ContainerEndpoint> endpoints() { return endpoints; } @Override public boolean isBootstrap() { return isBootstrap; } diff --git a/config-model/src/main/java/com/yahoo/vespa/model/VespaModelFactory.java b/config-model/src/main/java/com/yahoo/vespa/model/VespaModelFactory.java index ca5c188ddb1..1dc0b838470 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/VespaModelFactory.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/VespaModelFactory.java @@ -140,7 +140,6 @@ public class VespaModelFactory implements ModelFactory { .properties(modelContext.properties()) .vespaVersion(version()) .modelHostProvisioner(createHostProvisioner(modelContext)) - .rotations(modelContext.properties().rotations()) .endpoints(modelContext.properties().endpoints()) .modelImporters(modelImporters) .zone(zone) 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 1c0645aef2b..efc566f2dec 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 @@ -24,7 +24,6 @@ import com.yahoo.config.provision.ClusterSpec; import com.yahoo.config.provision.Environment; import com.yahoo.config.provision.HostName; import com.yahoo.config.provision.NodeType; -import com.yahoo.config.provision.Rotation; import com.yahoo.config.provision.SystemName; import com.yahoo.config.provision.Zone; import com.yahoo.search.rendering.RendererRegistry; @@ -79,7 +78,6 @@ import org.w3c.dom.Node; import java.net.URI; import java.util.ArrayList; import java.util.Collections; -import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Optional; @@ -223,14 +221,13 @@ public class ContainerModelBuilder extends ConfigModelBuilder<ContainerModel> { context.getDeployState().getProperties().athenzDnsSuffix(), context.getDeployState().zone(), deploymentSpec); - addRotationProperties(cluster, context.getDeployState().zone(), context.getDeployState().getRotations(), context.getDeployState().getEndpoints(), deploymentSpec); + addRotationProperties(cluster, context.getDeployState().zone(), context.getDeployState().getEndpoints(), deploymentSpec); }); } - private void addRotationProperties(ApplicationContainerCluster cluster, Zone zone, Set<Rotation> rotations, Set<ContainerEndpoint> endpoints, DeploymentSpec spec) { - Optional<String> globalServiceId = spec.instance(app.getApplicationId().instance()).flatMap(instance -> instance.globalServiceId()); + private void addRotationProperties(ApplicationContainerCluster cluster, Zone zone, Set<ContainerEndpoint> endpoints, DeploymentSpec spec) { cluster.getContainers().forEach(container -> { - setRotations(container, rotations, endpoints, globalServiceId, cluster.getName()); + setRotations(container, endpoints, cluster.getName()); container.setProp("activeRotation", Boolean.toString(zoneHasActiveRotation(zone, spec))); }); } @@ -243,26 +240,11 @@ public class ContainerModelBuilder extends ConfigModelBuilder<ContainerModel> { declaredZone.active()); } - private void setRotations(Container container, - Set<Rotation> rotations, - Set<ContainerEndpoint> endpoints, - Optional<String> globalServiceId, - String containerClusterName) { - final Set<String> rotationsProperty = new HashSet<>(); - - // Add the legacy rotations to the list of available rotations. Using the same test - // as was used before to mirror the old business logic for global-service-id. - if ( ! rotations.isEmpty() && globalServiceId.isPresent()) { - if (containerClusterName.equals(globalServiceId.get())) { - rotations.stream().map(Rotation::getId).forEach(rotationsProperty::add); - } - } - - // For ContainerEndpoints this is more straight-forward, just add all that are present - endpoints.stream() - .filter(endpoint -> endpoint.clusterId().equals(containerClusterName)) - .flatMap(endpoint -> endpoint.names().stream()) - .forEach(rotationsProperty::add); + private void setRotations(Container container, Set<ContainerEndpoint> endpoints, String containerClusterName) { + var rotationsProperty = endpoints.stream() + .filter(endpoint -> endpoint.clusterId().equals(containerClusterName)) + .flatMap(endpoint -> endpoint.names().stream()) + .collect(Collectors.toUnmodifiableSet()); // Build the comma delimited list of endpoints this container should be known as. // Confusingly called 'rotations' for legacy reasons. diff --git a/config-model/src/test/java/com/yahoo/config/model/deploy/DeployStateTest.java b/config-model/src/test/java/com/yahoo/config/model/deploy/DeployStateTest.java index 383446228cc..d243a2dacf6 100644 --- a/config-model/src/test/java/com/yahoo/config/model/deploy/DeployStateTest.java +++ b/config-model/src/test/java/com/yahoo/config/model/deploy/DeployStateTest.java @@ -3,13 +3,13 @@ package com.yahoo.config.model.deploy; import com.yahoo.config.application.api.ApplicationPackage; import com.yahoo.config.model.api.ConfigDefinitionRepo; +import com.yahoo.config.model.api.ContainerEndpoint; import com.yahoo.config.model.api.HostProvisioner; import com.yahoo.config.model.api.ModelContext; import com.yahoo.config.model.application.provider.FilesApplicationPackage; import com.yahoo.config.model.provision.InMemoryProvisioner; import com.yahoo.config.model.test.MockApplicationPackage; import com.yahoo.config.provision.ApplicationId; -import com.yahoo.config.provision.Rotation; import com.yahoo.vespa.config.ConfigDefinition; import com.yahoo.vespa.config.ConfigDefinitionKey; import com.yahoo.vespa.model.VespaModel; @@ -18,16 +18,17 @@ import org.xml.sax.SAXException; import java.io.File; import java.io.IOException; -import java.util.HashSet; import java.util.LinkedHashMap; +import java.util.List; import java.util.Map; import java.util.Optional; import java.util.Set; -import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; /** * @author Ulf Lilleengen @@ -108,13 +109,10 @@ public class DeployStateTest { } @Test - public void testRotations() { - Set<Rotation> rotations = new HashSet<>(); - assertThat(new DeployState.Builder().rotations(rotations).build().getRotations().size(), is(0)); - for (String name : new String[]{"rotation-001.vespa.a02.yahoodns.net", "rotation-002.vespa.a02.yahoodns.net"}) { - rotations.add(new Rotation(name)); - } - assertThat(new DeployState.Builder().rotations(rotations).build().getRotations(), equalTo(rotations)); + public void testContainerEndpoints() { + assertTrue(new DeployState.Builder().endpoints(Set.of()).build().getEndpoints().isEmpty()); + var endpoints = Set.of(new ContainerEndpoint("c1", List.of("c1.example.com", "c1-alias.example.com"))); + assertEquals(endpoints, new DeployState.Builder().endpoints(endpoints).build().getEndpoints()); } private DeployState createDeployState(ApplicationPackage app, Map<ConfigDefinitionKey, com.yahoo.vespa.config.buildergen.ConfigDefinition> defs) { diff --git a/config-provisioning/src/main/java/com/yahoo/config/provision/Rotation.java b/config-provisioning/src/main/java/com/yahoo/config/provision/Rotation.java index 75b7d790eba..d1cf86c6d16 100644 --- a/config-provisioning/src/main/java/com/yahoo/config/provision/Rotation.java +++ b/config-provisioning/src/main/java/com/yahoo/config/provision/Rotation.java @@ -6,6 +6,7 @@ import java.util.Objects; /** * A rotation (virtual endpoint). */ +// TODO(mpolden): Remove once 7.122 is the oldest config model public class Rotation { private final String id; 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 2734e5ad6b8..465344a6d76 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 @@ -53,7 +53,7 @@ import com.yahoo.vespa.config.server.session.RemoteSessionRepo; import com.yahoo.vespa.config.server.session.Session; import com.yahoo.vespa.config.server.session.SessionFactory; import com.yahoo.vespa.config.server.session.SilentDeployLogger; -import com.yahoo.vespa.config.server.tenant.Rotations; +import com.yahoo.vespa.config.server.tenant.ContainerEndpointsCache; import com.yahoo.vespa.config.server.tenant.Tenant; import com.yahoo.vespa.config.server.tenant.TenantRepository; import com.yahoo.vespa.curator.Lock; @@ -70,10 +70,8 @@ import java.time.Duration; import java.time.Instant; import java.util.Arrays; import java.util.Collection; -import java.util.HashMap; import java.util.HashSet; import java.util.List; -import java.util.Map; import java.util.Optional; import java.util.Set; import java.util.logging.Level; @@ -370,7 +368,7 @@ public class ApplicationRepository implements com.yahoo.config.provision.Deploye }).orElse(true); NestedTransaction transaction = new NestedTransaction(); - transaction.add(new Rotations(tenant.getCurator(), tenant.getPath()).delete(applicationId)); // TODO: Not unit tested + transaction.add(new ContainerEndpointsCache(tenant.getPath(), tenant.getCurator()).delete(applicationId)); // TODO: Not unit tested // (When rotations are updated in zk, we need to redeploy the zone app, on the right config server // this is done asynchronously in application maintenance by the node repository) transaction.add(tenantApplications.createDeleteTransaction(applicationId)); diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/deploy/ModelContextImpl.java b/configserver/src/main/java/com/yahoo/vespa/config/server/deploy/ModelContextImpl.java index 9cba549838e..694ab8f037e 100644 --- a/configserver/src/main/java/com/yahoo/vespa/config/server/deploy/ModelContextImpl.java +++ b/configserver/src/main/java/com/yahoo/vespa/config/server/deploy/ModelContextImpl.java @@ -14,7 +14,6 @@ import com.yahoo.config.model.api.ModelContext; import com.yahoo.config.model.api.TlsSecrets; import com.yahoo.config.provision.ApplicationId; import com.yahoo.config.provision.HostName; -import com.yahoo.config.provision.Rotation; import com.yahoo.config.provision.Zone; import com.yahoo.vespa.flags.FetchVector; import com.yahoo.vespa.flags.FlagSource; @@ -127,7 +126,6 @@ public class ModelContextImpl implements ModelContext { private final String athenzDnsSuffix; private final boolean hostedVespa; private final Zone zone; - private final Set<Rotation> rotations; private final Set<ContainerEndpoint> endpoints; private final boolean isBootstrap; private final boolean isFirstTimeDeployment; @@ -143,7 +141,6 @@ public class ModelContextImpl implements ModelContext { String athenzDnsSuffix, boolean hostedVespa, Zone zone, - Set<Rotation> rotations, Set<ContainerEndpoint> endpoints, boolean isBootstrap, boolean isFirstTimeDeployment, @@ -157,7 +154,6 @@ public class ModelContextImpl implements ModelContext { this.athenzDnsSuffix = athenzDnsSuffix; this.hostedVespa = hostedVespa; this.zone = zone; - this.rotations = rotations; this.endpoints = endpoints; this.isBootstrap = isBootstrap; this.isFirstTimeDeployment = isFirstTimeDeployment; @@ -197,9 +193,6 @@ public class ModelContextImpl implements ModelContext { public Zone zone() { return zone; } @Override - public Set<Rotation> rotations() { return rotations; } - - @Override public Set<ContainerEndpoint> endpoints() { return endpoints; } @Override 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 94cd30de28b..bc6419f230f 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 @@ -27,7 +27,6 @@ import com.yahoo.vespa.config.server.provision.HostProvisionerProvider; import com.yahoo.vespa.config.server.session.SessionZooKeeperClient; import com.yahoo.vespa.config.server.session.SilentDeployLogger; import com.yahoo.vespa.config.server.tenant.ContainerEndpointsCache; -import com.yahoo.vespa.config.server.tenant.Rotations; import com.yahoo.vespa.config.server.tenant.TenantRepository; import com.yahoo.vespa.config.server.tenant.TlsSecretsKeys; import com.yahoo.vespa.curator.Curator; @@ -132,7 +131,6 @@ public class ActivatedModelsBuilder extends ModelsBuilder<Application> { configserverConfig.athenzDnsSuffix(), configserverConfig.hostedVespa(), zone(), - new Rotations(curator, TenantRepository.getTenantPath(tenant)).readRotationsFromZooKeeper(applicationId), ImmutableSet.copyOf(new ContainerEndpointsCache(TenantRepository.getTenantPath(tenant), curator).read(applicationId)), false, // We may be bootstrapping, but we only know and care during prepare false, // Always false, assume no one uses it when activating diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/session/PrepareParams.java b/configserver/src/main/java/com/yahoo/vespa/config/server/session/PrepareParams.java index a21e12a5d42..ab3e0e863ce 100644 --- a/configserver/src/main/java/com/yahoo/vespa/config/server/session/PrepareParams.java +++ b/configserver/src/main/java/com/yahoo/vespa/config/server/session/PrepareParams.java @@ -2,23 +2,20 @@ package com.yahoo.vespa.config.server.session; import com.yahoo.component.Version; +import com.yahoo.config.model.api.ContainerEndpoint; import com.yahoo.config.provision.ApplicationId; -import com.yahoo.config.provision.Rotation; import com.yahoo.config.provision.TenantName; import com.yahoo.container.jdisc.HttpRequest; import com.yahoo.slime.Slime; import com.yahoo.vespa.config.SlimeUtils; import com.yahoo.vespa.config.server.TimeoutBudget; import com.yahoo.vespa.config.server.http.SessionHandler; -import com.yahoo.config.model.api.ContainerEndpoint; import com.yahoo.vespa.config.server.tenant.ContainerEndpointSerializer; import java.time.Clock; import java.time.Duration; -import java.util.LinkedHashSet; import java.util.List; import java.util.Optional; -import java.util.Set; /** * Parameters for prepare. Immutable. @@ -33,7 +30,6 @@ public final class PrepareParams { static final String DRY_RUN_PARAM_NAME = "dryRun"; static final String VERBOSE_PARAM_NAME = "verbose"; static final String VESPA_VERSION_PARAM_NAME = "vespaVersion"; - static final String ROTATIONS_PARAM_NAME = "rotations"; static final String CONTAINER_ENDPOINTS_PARAM_NAME = "containerEndpoints"; static final String TLS_SECRETS_KEY_NAME_PARAM_NAME = "tlsSecretsKeyName"; @@ -44,14 +40,12 @@ public final class PrepareParams { private final boolean verbose; private final boolean isBootstrap; private final Optional<Version> vespaVersion; - private final Set<Rotation> rotations; private final List<ContainerEndpoint> containerEndpoints; private final Optional<String> tlsSecretsKeyName; private PrepareParams(ApplicationId applicationId, TimeoutBudget timeoutBudget, boolean ignoreValidationErrors, boolean dryRun, boolean verbose, boolean isBootstrap, Optional<Version> vespaVersion, - Set<Rotation> rotations, List<ContainerEndpoint> containerEndpoints, - Optional<String> tlsSecretsKeyName) { + List<ContainerEndpoint> containerEndpoints, Optional<String> tlsSecretsKeyName) { this.timeoutBudget = timeoutBudget; this.applicationId = applicationId; this.ignoreValidationErrors = ignoreValidationErrors; @@ -59,11 +53,7 @@ public final class PrepareParams { this.verbose = verbose; this.isBootstrap = isBootstrap; this.vespaVersion = vespaVersion; - this.rotations = rotations; this.containerEndpoints = containerEndpoints; - if ((rotations != null && !rotations.isEmpty()) && !containerEndpoints.isEmpty()) { - throw new IllegalArgumentException("Cannot set both rotations and containerEndpoints"); - } this.tlsSecretsKeyName = tlsSecretsKeyName; } @@ -76,7 +66,6 @@ public final class PrepareParams { private ApplicationId applicationId = ApplicationId.defaultId(); private TimeoutBudget timeoutBudget = new TimeoutBudget(Clock.systemUTC(), Duration.ofSeconds(30)); private Optional<Version> vespaVersion = Optional.empty(); - private Set<Rotation> rotations; private List<ContainerEndpoint> containerEndpoints = List.of(); private Optional<String> tlsSecretsKeyName = Optional.empty(); @@ -126,17 +115,6 @@ public final class PrepareParams { return this; } - public Builder rotations(String rotationsString) { - this.rotations = new LinkedHashSet<>(); - if (rotationsString != null && !rotationsString.isEmpty()) { - String[] rotations = rotationsString.split(","); - for (String s : rotations) { - this.rotations.add(new Rotation(s)); - } - } - return this; - } - public Builder containerEndpoints(String serialized) { if (serialized == null) return this; Slime slime = SlimeUtils.jsonToSlime(serialized); @@ -151,8 +129,8 @@ public final class PrepareParams { } public PrepareParams build() { - return new PrepareParams(applicationId, timeoutBudget, ignoreValidationErrors, dryRun, - verbose, isBootstrap, vespaVersion, rotations, containerEndpoints, tlsSecretsKeyName); + return new PrepareParams(applicationId, timeoutBudget, ignoreValidationErrors, dryRun, + verbose, isBootstrap, vespaVersion, containerEndpoints, tlsSecretsKeyName); } } @@ -164,7 +142,6 @@ public final class PrepareParams { .timeoutBudget(SessionHandler.getTimeoutBudget(request, barrierTimeout)) .applicationId(createApplicationId(request, tenant)) .vespaVersion(request.getProperty(VESPA_VERSION_PARAM_NAME)) - .rotations(request.getProperty(ROTATIONS_PARAM_NAME)) .containerEndpoints(request.getProperty(CONTAINER_ENDPOINTS_PARAM_NAME)) .tlsSecretsKeyName(request.getProperty(TLS_SECRETS_KEY_NAME_PARAM_NAME)) .build(); @@ -197,10 +174,6 @@ public final class PrepareParams { /** Returns the Vespa version the nodes running the prepared system should have, or empty to use the system version */ public Optional<Version> vespaVersion() { return vespaVersion; } - /** Returns the global rotations that should be made available for this deployment */ - // TODO: Remove this once all applications have to switched to containerEndpoints - public Set<Rotation> rotations() { return rotations; } - /** Returns the container endpoints that should be made available for this deployment. One per cluster */ public List<ContainerEndpoint> containerEndpoints() { return containerEndpoints; 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 3ec74a4c3eb..171eab35507 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 @@ -9,16 +9,14 @@ import com.yahoo.component.Version; import com.yahoo.component.Vtag; import com.yahoo.config.application.api.ApplicationPackage; import com.yahoo.config.application.api.DeployLogger; -import com.yahoo.config.application.api.DeploymentInstanceSpec; -import com.yahoo.config.application.api.DeploymentSpec; import com.yahoo.config.application.api.FileRegistry; import com.yahoo.config.model.api.ConfigDefinitionRepo; +import com.yahoo.config.model.api.ContainerEndpoint; import com.yahoo.config.model.api.ModelContext; import com.yahoo.config.model.api.TlsSecrets; import com.yahoo.config.provision.AllocatedHosts; import com.yahoo.config.provision.ApplicationId; import com.yahoo.config.provision.HostName; -import com.yahoo.config.provision.Rotation; import com.yahoo.config.provision.Zone; import com.yahoo.container.jdisc.secretstore.SecretStore; import com.yahoo.lang.SettableOptional; @@ -34,9 +32,7 @@ import com.yahoo.vespa.config.server.http.InvalidApplicationException; import com.yahoo.vespa.config.server.modelfactory.ModelFactoryRegistry; import com.yahoo.vespa.config.server.modelfactory.PreparedModelsBuilder; import com.yahoo.vespa.config.server.provision.HostProvisionerProvider; -import com.yahoo.config.model.api.ContainerEndpoint; import com.yahoo.vespa.config.server.tenant.ContainerEndpointsCache; -import com.yahoo.vespa.config.server.tenant.Rotations; import com.yahoo.vespa.config.server.tenant.TlsSecretsKeys; import com.yahoo.vespa.curator.Curator; import com.yahoo.vespa.flags.FlagSource; @@ -47,7 +43,6 @@ import javax.xml.transform.TransformerException; import java.io.IOException; import java.net.URI; import java.time.Instant; -import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Optional; @@ -118,13 +113,8 @@ public class SessionPreparer { preparation.makeResult(allocatedHosts); if ( ! params.isDryRun()) { preparation.writeStateZK(); - preparation.writeRotZK(); preparation.writeTlsZK(); - var globalServiceId = context.getApplicationPackage().getDeployment() - .map(DeploymentSpec::fromXml) - .flatMap(spec -> spec.instance(context.getApplicationPackage().getApplicationId().instance())) - .flatMap(DeploymentInstanceSpec::globalServiceId); - preparation.writeContainerEndpointsZK(globalServiceId); + preparation.writeContainerEndpointsZK(); preparation.distribute(); } log.log(LogLevel.DEBUG, () -> "time used " + params.getTimeoutBudget().timesUsed() + @@ -149,9 +139,7 @@ public class SessionPreparer { /** The version of Vespa the application to be prepared specifies for its nodes */ final com.yahoo.component.Version vespaVersion; - final Rotations rotations; // TODO: Remove this once we have migrated fully to container endpoints final ContainerEndpointsCache containerEndpoints; - final Set<Rotation> rotationsSet; final Set<ContainerEndpoint> endpointsSet; final ModelContext.Properties properties; private final TlsSecretsKeys tlsSecretsKeys; @@ -173,9 +161,7 @@ public class SessionPreparer { this.applicationId = params.getApplicationId(); this.vespaVersion = params.vespaVersion().orElse(Vtag.currentVersion); - this.rotations = new Rotations(curator, tenantPath); this.containerEndpoints = new ContainerEndpointsCache(tenantPath, curator); - this.rotationsSet = getRotations(params.rotations()); this.tlsSecretsKeys = new TlsSecretsKeys(curator, tenantPath, secretStore); this.tlsSecrets = tlsSecretsKeys.getTlsSecrets(params.tlsSecretsKeyName(), applicationId); this.endpointsSet = getEndpoints(params.containerEndpoints()); @@ -188,7 +174,6 @@ public class SessionPreparer { configserverConfig.athenzDnsSuffix(), configserverConfig.hostedVespa(), zone, - rotationsSet, endpointsSet, params.isBootstrap(), ! currentActiveApplicationSet.isPresent(), @@ -248,27 +233,14 @@ public class SessionPreparer { checkTimeout("write state to zookeeper"); } - void writeRotZK() { - rotations.writeRotationsToZooKeeper(applicationId, rotationsSet); - checkTimeout("write rotations to zookeeper"); - } - void writeTlsZK() { tlsSecretsKeys.writeTlsSecretsKeyToZooKeeper(applicationId, params.tlsSecretsKeyName().orElse(null)); checkTimeout("write tlsSecretsKey to zookeeper"); } - void writeContainerEndpointsZK(Optional<String> globalServiceId) { + void writeContainerEndpointsZK() { if (!params.containerEndpoints().isEmpty()) { // Use endpoints from parameter when explicitly given containerEndpoints.write(applicationId, params.containerEndpoints()); - } else { // Fall back to writing rotations as container endpoints - if (!rotationsSet.isEmpty()) { - if (globalServiceId.isEmpty()) { - log.log(LogLevel.WARNING, "Want to write rotations " + rotationsSet + " as container endpoints, but " + applicationId + " has no global-service-id. This should not happen"); - return; - } - containerEndpoints.write(applicationId, toContainerEndpoints(globalServiceId.get(), rotationsSet)); - } } checkTimeout("write container endpoints to zookeeper"); } @@ -283,13 +255,6 @@ public class SessionPreparer { return prepareResult.getConfigChangeActions(); } - private Set<Rotation> getRotations(Set<Rotation> rotations) { - if (rotations == null || rotations.isEmpty()) { - rotations = this.rotations.readRotationsFromZooKeeper(applicationId); - } - return rotations; - } - private Set<ContainerEndpoint> getEndpoints(List<ContainerEndpoint> endpoints) { if (endpoints == null || endpoints.isEmpty()) { endpoints = this.containerEndpoints.read(applicationId); @@ -299,13 +264,6 @@ public class SessionPreparer { } - private static List<ContainerEndpoint> toContainerEndpoints(String globalServceId, Set<Rotation> rotations) { - return List.of(new ContainerEndpoint(globalServceId, - rotations.stream() - .map(Rotation::getId) - .collect(Collectors.toUnmodifiableList()))); - } - private void writeStateToZooKeeper(SessionZooKeeperClient zooKeeperClient, ApplicationPackage applicationPackage, ApplicationId applicationId, diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/tenant/ContainerEndpointsCache.java b/configserver/src/main/java/com/yahoo/vespa/config/server/tenant/ContainerEndpointsCache.java index 9bce1224d96..65ebb38c2d0 100644 --- a/configserver/src/main/java/com/yahoo/vespa/config/server/tenant/ContainerEndpointsCache.java +++ b/configserver/src/main/java/com/yahoo/vespa/config/server/tenant/ContainerEndpointsCache.java @@ -6,6 +6,8 @@ import com.yahoo.config.provision.ApplicationId; import com.yahoo.path.Path; import com.yahoo.vespa.config.SlimeUtils; import com.yahoo.vespa.curator.Curator; +import com.yahoo.vespa.curator.transaction.CuratorOperations; +import com.yahoo.vespa.curator.transaction.CuratorTransaction; import java.io.IOException; import java.io.UncheckedIOException; @@ -13,15 +15,12 @@ import java.util.List; /** - * Persists assignment of rotations to an application to ZooKeeper. + * Persists assignment of rotations to an application in ZooKeeper. + * * The entries are {@link ContainerEndpoint} instances, which keep track of the container * cluster that is the target, the endpoint name, and the rotation used to * give availability to that cluster. * - * This is v2 of that storage in a new directory. Previously we only stored - * the name of the rotation, since all the other information could be - * calculated runtime. - * * @author ogronnesby */ public class ContainerEndpointsCache { @@ -35,27 +34,32 @@ public class ContainerEndpointsCache { } public List<ContainerEndpoint> read(ApplicationId applicationId) { - final var optionalData = curator.getData(applicationPath(applicationId)); - return optionalData - .map(SlimeUtils::jsonToSlime) - .map(ContainerEndpointSerializer::endpointListFromSlime) - .orElseGet(List::of); + var optionalData = curator.getData(containerEndpointsPath(applicationId)); + return optionalData.map(SlimeUtils::jsonToSlime) + .map(ContainerEndpointSerializer::endpointListFromSlime) + .orElseGet(List::of); } public void write(ApplicationId applicationId, List<ContainerEndpoint> endpoints) { if (endpoints.isEmpty()) return; - final var slime = ContainerEndpointSerializer.endpointListToSlime(endpoints); + var slime = ContainerEndpointSerializer.endpointListToSlime(endpoints); try { - final var bytes = SlimeUtils.toJsonBytes(slime); - curator.set(applicationPath(applicationId), bytes); + var bytes = SlimeUtils.toJsonBytes(slime); + curator.set(containerEndpointsPath(applicationId), bytes); } catch (IOException e) { throw new UncheckedIOException("Error writing endpoints of: " + applicationId, e); } } - private Path applicationPath(ApplicationId applicationId) { + /** Returns a transaction which deletes these rotations if they exist */ + public CuratorTransaction delete(ApplicationId application) { + if ( ! curator.exists(containerEndpointsPath(application))) return CuratorTransaction.empty(curator); + return CuratorTransaction.from(CuratorOperations.delete(containerEndpointsPath(application).getAbsolute()), curator); + } + + private Path containerEndpointsPath(ApplicationId applicationId) { return cachePath.append(applicationId.serializedForm()); } diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/tenant/Rotations.java b/configserver/src/main/java/com/yahoo/vespa/config/server/tenant/Rotations.java deleted file mode 100644 index 1fb7e9bacc7..00000000000 --- a/configserver/src/main/java/com/yahoo/vespa/config/server/tenant/Rotations.java +++ /dev/null @@ -1,69 +0,0 @@ -// 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.tenant; - -import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.yahoo.config.provision.ApplicationId; -import com.yahoo.config.provision.Rotation; -import com.yahoo.path.Path; - -import com.yahoo.vespa.curator.Curator; -import com.yahoo.vespa.curator.transaction.CuratorOperations; -import com.yahoo.vespa.curator.transaction.CuratorTransaction; - -import java.util.Collections; -import java.util.Optional; -import java.util.Set; -import java.util.stream.Collectors; - -/** - * Rotations for an application. Persisted in ZooKeeper. - * - * @author hmusum - * @author bratseth - */ -// TODO: This should be owned by the correct Tenant object and the rotations set should be contained in this -public class Rotations { - - private final Path path; - private final Curator curator; - - public Rotations(Curator curator, Path tenantPath) { - this.curator = curator; - this.path = tenantPath.append("rotationsCache/"); - } - - public Set<Rotation> readRotationsFromZooKeeper(ApplicationId application) { - try { - Optional<byte[]> data = curator.getData(rotationsOf(application)); - if ( ! data.isPresent() || data.get().length == 0) return Collections.emptySet(); - Set<String> rotationIds = new ObjectMapper().readValue(data.get(), new TypeReference<Set<String>>() {}); - return rotationIds.stream().map(Rotation::new).collect(Collectors.toSet()); - } catch (Exception e) { - throw new RuntimeException("Error reading rotations of " + application, e); - } - } - - public void writeRotationsToZooKeeper(ApplicationId application, Set<Rotation> rotations) { - if (rotations.isEmpty()) return; - try { - Set<String> rotationIds = rotations.stream().map(Rotation::getId).collect(Collectors.toSet()); - byte[] data = new ObjectMapper().writeValueAsBytes(rotationIds); - curator.set(rotationsOf(application), data); - } catch (Exception e) { - throw new RuntimeException("Could not write rotations of " + application, e); - } - } - - /** Returns a transaction which deletes these rotations if they exist */ - public CuratorTransaction delete(ApplicationId application) { - if ( ! curator.exists(rotationsOf(application))) return CuratorTransaction.empty(curator); - return CuratorTransaction.from(CuratorOperations.delete(rotationsOf(application).getAbsolute()), curator); - } - - /** Returns the path storing the rotations data for an application */ - private Path rotationsOf(ApplicationId application) { - return path.append(application.serializedForm()); - } - -} diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/ModelContextImplTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/ModelContextImplTest.java index 3102163df0d..370e0bd3c0e 100644 --- a/configserver/src/test/java/com/yahoo/vespa/config/server/ModelContextImplTest.java +++ b/configserver/src/test/java/com/yahoo/vespa/config/server/ModelContextImplTest.java @@ -8,7 +8,6 @@ import com.yahoo.config.model.application.provider.BaseDeployLogger; import com.yahoo.config.model.application.provider.MockFileRegistry; import com.yahoo.config.model.test.MockApplicationPackage; import com.yahoo.config.provision.ApplicationId; -import com.yahoo.config.provision.Rotation; import com.yahoo.config.provision.Zone; import com.yahoo.vespa.config.server.deploy.ModelContextImpl; import com.yahoo.vespa.flags.InMemoryFlagSource; @@ -30,16 +29,13 @@ import static org.junit.Assert.assertTrue; * @author Ulf Lilleengen */ public class ModelContextImplTest { + @Test public void testModelContextTest() { - final Rotation rotation = new Rotation("this.is.a.mock.rotation"); - final Set<Rotation> rotations = Collections.singleton(rotation); - - final ContainerEndpoint endpoint = new ContainerEndpoint("foo", List.of("a", "b")); - final Set<ContainerEndpoint> endpoints = Collections.singleton(endpoint); - - final InMemoryFlagSource flagSource = new InMemoryFlagSource(); + ContainerEndpoint endpoint = new ContainerEndpoint("foo", List.of("a", "b")); + Set<ContainerEndpoint> endpoints = Collections.singleton(endpoint); + InMemoryFlagSource flagSource = new InMemoryFlagSource(); ModelContext context = new ModelContextImpl( MockApplicationPackage.createEmpty(), @@ -58,7 +54,6 @@ public class ModelContextImplTest { null, false, Zone.defaultZone(), - rotations, endpoints, false, false, @@ -78,8 +73,8 @@ public class ModelContextImplTest { assertTrue(context.properties().multitenant()); assertNotNull(context.properties().zone()); assertFalse(context.properties().hostedVespa()); - assertThat(context.properties().rotations(), equalTo(rotations)); assertThat(context.properties().endpoints(), equalTo(endpoints)); assertThat(context.properties().isFirstTimeDeployment(), equalTo(false)); } + } diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/model/LbServicesProducerTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/model/LbServicesProducerTest.java index bc777659298..9a7cb72804f 100644 --- a/configserver/src/test/java/com/yahoo/vespa/config/server/model/LbServicesProducerTest.java +++ b/configserver/src/test/java/com/yahoo/vespa/config/server/model/LbServicesProducerTest.java @@ -13,7 +13,6 @@ import com.yahoo.config.model.test.MockApplicationPackage; import com.yahoo.config.provision.ApplicationId; import com.yahoo.config.provision.Environment; import com.yahoo.config.provision.RegionName; -import com.yahoo.config.provision.Rotation; import com.yahoo.config.provision.TenantName; import com.yahoo.config.provision.Zone; import com.yahoo.vespa.config.ConfigPayload; @@ -42,17 +41,15 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import static org.junit.Assume.assumeFalse; -import static org.junit.Assume.assumeTrue; /** * @author Ulf Lilleengen */ @RunWith(Parameterized.class) public class LbServicesProducerTest { + private static final String rotation1 = "rotation-1"; private static final String rotation2 = "rotation-2"; - private static final String rotationString = rotation1 + "," + rotation2; - private static final Set<Rotation> rotations = Collections.singleton(new Rotation(rotationString)); private static final Set<ContainerEndpoint> endpoints = Set.of( new ContainerEndpoint("mydisc", List.of("rotation-1", "rotation-2")) ); @@ -70,7 +67,7 @@ public class LbServicesProducerTest { @Test public void testDeterministicGetConfig() throws IOException, SAXException { - Map<TenantName, Set<ApplicationInfo>> testModel = createTestModel(new DeployState.Builder().rotations(rotations)); + Map<TenantName, Set<ApplicationInfo>> testModel = createTestModel(new DeployState.Builder().endpoints(endpoints)); LbServicesConfig last = null; for (int i = 0; i < 100; i++) { testModel = randomizeApplications(testModel, i); @@ -126,25 +123,6 @@ public class LbServicesProducerTest { } @Test - public void testConfigAliasesWithRotations() throws IOException, SAXException { - assumeTrue(useGlobalServiceId); - - Map<TenantName, Set<ApplicationInfo>> testModel = createTestModel(new DeployState.Builder() - .rotations(rotations) - .properties(new TestProperties().setHostedVespa(true))); - RegionName regionName = RegionName.from("us-east-1"); - - var services = getLbServicesConfig(new Zone(Environment.prod, regionName), testModel) - .tenants("foo") - .applications("foo:prod:" + regionName.value() + ":default") - .hosts("foo.foo.yahoo.com") - .services(QRSERVER.serviceName); - - assertThat(services.servicealiases(), contains("service1")); - assertThat("Missing rotations in list: " + services.endpointaliases(), services.endpointaliases(), containsInAnyOrder("foo1.bar1.com", "foo2.bar2.com", rotation1, rotation2)); - } - - @Test public void testConfigAliasesWithEndpoints() throws IOException, SAXException { assumeFalse(useGlobalServiceId); @@ -259,4 +237,5 @@ public class LbServicesProducerTest { assertThat(expected.toString(), is(actual.toString())); assertThat(ConfigPayload.fromInstance(expected).toString(true), is(ConfigPayload.fromInstance(actual).toString(true))); } + } diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/session/PrepareParamsTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/session/PrepareParamsTest.java index f5fd6053b07..3f5d06b7071 100644 --- a/configserver/src/test/java/com/yahoo/vespa/config/server/session/PrepareParamsTest.java +++ b/configserver/src/test/java/com/yahoo/vespa/config/server/session/PrepareParamsTest.java @@ -1,12 +1,10 @@ // 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.session; -import com.yahoo.component.Version; +import com.yahoo.config.model.api.ContainerEndpoint; import com.yahoo.config.provision.ApplicationId; -import com.yahoo.config.provision.Rotation; import com.yahoo.config.provision.TenantName; import com.yahoo.container.jdisc.HttpRequest; -import com.yahoo.config.model.api.ContainerEndpoint; import org.junit.Test; import java.net.URLEncoder; @@ -14,12 +12,8 @@ import java.nio.charset.StandardCharsets; import java.time.Duration; import java.util.List; import java.util.Optional; -import java.util.Set; import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.Matchers.contains; -import static org.hamcrest.Matchers.containsInAnyOrder; -import static org.hamcrest.Matchers.equalTo; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertThat; @@ -30,7 +24,6 @@ import static org.junit.Assert.assertTrue; */ public class PrepareParamsTest { - private static final String rotation = "rotation-042.vespa.a02.yahoodns.net"; private static final String vespaVersion = "6.37.49"; private static final String request = "http://foo:19071/application/v2/tenant/foo/application/bar?" + PrepareParams.DRY_RUN_PARAM_NAME + "=true&" + @@ -49,36 +42,7 @@ public class PrepareParamsTest { assertFalse(prepareParams.ignoreValidationErrors()); assertThat(prepareParams.vespaVersion(), is(Optional.<String>empty())); assertTrue(prepareParams.getTimeoutBudget().hasTimeLeft()); - assertThat(prepareParams.rotations().size(), is(0)); - } - - @Test - public void testCorrectParsingWithRotation() { - PrepareParams prepareParams = createParams(request + "&" + - PrepareParams.ROTATIONS_PARAM_NAME + "=" + rotation, - TenantName.from("foo")); - - assertThat(prepareParams.getApplicationId().serializedForm(), is("foo:baz:default")); - assertTrue(prepareParams.isDryRun()); - assertTrue(prepareParams.isVerbose()); - assertFalse(prepareParams.ignoreValidationErrors()); - Version expectedVersion = Version.fromString(vespaVersion); - assertThat(prepareParams.vespaVersion().get(), is(expectedVersion)); - assertTrue(prepareParams.getTimeoutBudget().hasTimeLeft()); - Set<Rotation> rotations = prepareParams.rotations(); - assertThat(rotations.size(), is(1)); - assertThat(rotations, contains(equalTo(new Rotation(rotation)))); - } - - @Test - public void testCorrectParsingWithSeveralRotations() { - String rotationTwo = "rotation-043.vespa.a02.yahoodns.net"; - String twoRotations = rotation + "," + rotationTwo; - PrepareParams prepareParams = createParams(request + "&" + - PrepareParams.ROTATIONS_PARAM_NAME + "=" + twoRotations, - TenantName.from("foo")); - Set<Rotation> rotations = prepareParams.rotations(); - assertThat(rotations, containsInAnyOrder(new Rotation(rotation), new Rotation(rotationTwo))); + assertThat(prepareParams.containerEndpoints().size(), is(0)); } @Test diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/session/SessionPreparerTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/session/SessionPreparerTest.java index e219c516f95..a099db5ebe8 100644 --- a/configserver/src/test/java/com/yahoo/vespa/config/server/session/SessionPreparerTest.java +++ b/configserver/src/test/java/com/yahoo/vespa/config/server/session/SessionPreparerTest.java @@ -3,7 +3,7 @@ package com.yahoo.vespa.config.server.session; import com.yahoo.component.Version; import com.yahoo.config.application.api.DeployLogger; -import com.yahoo.config.model.api.ModelContext; +import com.yahoo.config.model.api.ContainerEndpoint; import com.yahoo.config.model.api.TlsSecrets; import com.yahoo.config.model.application.provider.BaseDeployLogger; import com.yahoo.config.model.application.provider.FilesApplicationPackage; @@ -17,7 +17,6 @@ import com.yahoo.config.provision.HostSpec; import com.yahoo.config.provision.InstanceName; import com.yahoo.config.provision.ProvisionLogger; import com.yahoo.config.provision.Provisioner; -import com.yahoo.config.provision.Rotation; import com.yahoo.config.provision.TenantName; import com.yahoo.config.provision.exception.LoadBalancerServiceException; import com.yahoo.io.IOUtils; @@ -37,9 +36,7 @@ import com.yahoo.vespa.config.server.http.InvalidApplicationException; import com.yahoo.vespa.config.server.model.TestModelFactory; import com.yahoo.vespa.config.server.modelfactory.ModelFactoryRegistry; import com.yahoo.vespa.config.server.provision.HostProvisionerProvider; -import com.yahoo.config.model.api.ContainerEndpoint; import com.yahoo.vespa.config.server.tenant.ContainerEndpointsCache; -import com.yahoo.vespa.config.server.tenant.Rotations; import com.yahoo.vespa.config.server.tenant.TlsSecretsKeys; import com.yahoo.vespa.config.server.zookeeper.ConfigCurator; import com.yahoo.vespa.curator.mock.MockCurator; @@ -60,7 +57,6 @@ import java.util.Optional; import java.util.Set; import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.Matchers.contains; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertThat; @@ -185,60 +181,10 @@ public class SessionPreparerTest { assertThat(zkc.readApplicationId(), is(origId)); } - private List<ContainerEndpoint> readContainerEndpoints(ApplicationId application) { - return new ContainerEndpointsCache(tenantPath, curator).read(application); - } - - private Set<Rotation> readRotationsFromZK(ApplicationId applicationId) { - return new Rotations(curator, tenantPath).readRotationsFromZooKeeper(applicationId); - } - - @Test - public void require_that_rotations_are_written_in_prepare() throws IOException { - final String rotations = "mediasearch.msbe.global.vespa.yahooapis.com"; - final ApplicationId applicationId = applicationId("test"); - PrepareParams params = new PrepareParams.Builder().applicationId(applicationId).rotations(rotations).build(); - prepare(new File("src/test/resources/deploy/app"), params); - assertThat(readRotationsFromZK(applicationId), contains(new Rotation(rotations))); - } - - @Test - public void require_that_rotations_are_read_from_zookeeper_and_used() throws IOException { - final TestModelFactory modelFactory = new TestModelFactory(version123); - preparer = createPreparer(new ModelFactoryRegistry(Collections.singletonList(modelFactory)), - HostProvisionerProvider.empty()); - - final String rotations = "foo.msbe.global.vespa.yahooapis.com"; - final ApplicationId applicationId = applicationId("test"); - new Rotations(curator, tenantPath).writeRotationsToZooKeeper(applicationId, Collections.singleton(new Rotation(rotations))); - final PrepareParams params = new PrepareParams.Builder().applicationId(applicationId).build(); - final File app = new File("src/test/resources/deploy/app"); - prepare(app, params); - - // check that the rotation from zookeeper were used - final ModelContext modelContext = modelFactory.getModelContext(); - final Set<Rotation> rotationSet = modelContext.properties().rotations(); - assertThat(rotationSet, contains(new Rotation(rotations))); - - // Check that the persisted value is still the same - assertThat(readRotationsFromZK(applicationId), contains(new Rotation(rotations))); - } - - @Test - public void require_that_rotations_are_written_as_container_endpoints() throws Exception { - var rotations = "app1.tenant1.global.vespa.example.com,rotation-042.vespa.global.routing"; - var applicationId = applicationId("test"); - var params = new PrepareParams.Builder().applicationId(applicationId).rotations(rotations).build(); - prepare(new File("src/test/resources/deploy/hosted-app"), params); - - var expected = List.of(new ContainerEndpoint("qrs", - List.of("app1.tenant1.global.vespa.example.com", - "rotation-042.vespa.global.routing"))); - assertEquals(expected, readContainerEndpoints(applicationId)); - } - @Test - public void require_that_container_endpoints_are_written() throws Exception { + public void require_that_container_endpoints_are_written_and_used() throws Exception { + var modelFactory = new TestModelFactory(version123); + preparer = createPreparer(new ModelFactoryRegistry(List.of(modelFactory)), HostProvisionerProvider.empty()); var endpoints = "[\n" + " {\n" + " \"clusterId\": \"foo\",\n" + @@ -268,6 +214,16 @@ public class SessionPreparerTest { List.of("bar.app1.tenant1.global.vespa.example.com", "rotation-043.vespa.global.routing"))); assertEquals(expected, readContainerEndpoints(applicationId)); + + + var modelContext = modelFactory.getModelContext(); + var containerEndpointsFromModel = modelContext.properties().endpoints(); + assertEquals(Set.copyOf(expected), containerEndpointsFromModel); + + // Writing empty container endpoints keeps old value + params = new PrepareParams.Builder().applicationId(applicationId).build(); + prepare(new File("src/test/resources/deploy/hosted-app"), params); + assertEquals(expected, readContainerEndpoints(applicationId)); } @Test @@ -310,6 +266,10 @@ public class SessionPreparerTest { prepare(new File("src/test/resources/deploy/hosted-app"), params); } + private List<ContainerEndpoint> readContainerEndpoints(ApplicationId application) { + return new ContainerEndpointsCache(tenantPath, curator).read(application); + } + private void prepare(File app) throws IOException { prepare(app, new PrepareParams.Builder().build()); } |