summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Polden <mpolden@mpolden.no>2019-06-20 13:46:22 +0200
committerGitHub <noreply@github.com>2019-06-20 13:46:22 +0200
commit8d1f90e45fe953a3bedfd937448c4a28071639a4 (patch)
tree6b457387c9e1d6cc496d4859afdda3295a6073fb
parent564842bf4ea7047e2b33899fc21a82ee23bb4e4f (diff)
parentd581622b38817f63d2625e689388ab83b225f0da (diff)
Merge pull request #9827 from vespa-engine/ogronnesby/update-container-model-with-container-endpoints
Update ContainerModelBuilder to add rotations
-rw-r--r--config-model-api/src/main/java/com/yahoo/config/model/api/ContainerEndpoint.java (renamed from configserver/src/main/java/com/yahoo/vespa/config/server/tenant/ContainerEndpoint.java)10
-rw-r--r--config-model-api/src/main/java/com/yahoo/config/model/api/ModelContext.java1
-rw-r--r--config-model/src/main/java/com/yahoo/config/model/deploy/DeployState.java15
-rw-r--r--config-model/src/main/java/com/yahoo/config/model/deploy/TestProperties.java4
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/VespaModelFactory.java1
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java29
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilderTest.java47
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/deploy/ModelContextImpl.java7
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/modelfactory/ActivatedModelsBuilder.java3
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/session/PrepareParams.java2
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/session/SessionPreparer.java17
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/tenant/ContainerEndpointSerializer.java4
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/tenant/ContainerEndpointsCache.java1
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/ModelContextImplTest.java8
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/model/LbServicesProducerTest.java98
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/session/PrepareParamsTest.java7
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/session/SessionPreparerTest.java9
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/tenant/ContainerEndpointSerializerTest.java6
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/tenant/ContainerEndpointsCacheTest.java4
19 files changed, 221 insertions, 52 deletions
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/tenant/ContainerEndpoint.java b/config-model-api/src/main/java/com/yahoo/config/model/api/ContainerEndpoint.java
index b0fd3a81732..5641233606e 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/tenant/ContainerEndpoint.java
+++ b/config-model-api/src/main/java/com/yahoo/config/model/api/ContainerEndpoint.java
@@ -1,7 +1,5 @@
// Copyright 2019 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.yahoo.vespa.applicationmodel.ClusterId;
+package com.yahoo.config.model.api;
import java.util.List;
import java.util.Objects;
@@ -15,15 +13,15 @@ import java.util.Objects;
*/
public class ContainerEndpoint {
- private final ClusterId clusterId;
+ private final String clusterId;
private final List<String> names;
- public ContainerEndpoint(ClusterId clusterId, List<String> names) {
+ public ContainerEndpoint(String clusterId, List<String> names) {
this.clusterId = Objects.requireNonNull(clusterId);
this.names = List.copyOf(Objects.requireNonNull(names));
}
- public ClusterId clusterId() {
+ public String clusterId() {
return clusterId;
}
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 514ca2a00f5..b5db9f5eddd 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
@@ -50,6 +50,7 @@ public interface ModelContext {
boolean hostedVespa();
Zone zone();
Set<Rotation> rotations();
+ Set<ContainerEndpoint> endpoints();
boolean isBootstrap();
boolean isFirstTimeDeployment();
boolean useDedicatedNodeForLogserver();
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 c19865fafc9..21a8297910f 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
@@ -11,6 +11,7 @@ import com.yahoo.config.application.api.FileRegistry;
import com.yahoo.config.application.api.UnparsedConfigDefinition;
import com.yahoo.config.application.api.ValidationOverrides;
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.Model;
import com.yahoo.config.model.api.ModelContext;
@@ -67,6 +68,7 @@ public class DeployState implements ConfigDefinitionStore {
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;
private final SemanticRules semanticRules;
@@ -96,6 +98,7 @@ public class DeployState implements ConfigDefinitionStore {
Optional<ConfigDefinitionRepo> configDefinitionRepo,
java.util.Optional<Model> previousModel,
Set<Rotation> rotations,
+ Set<ContainerEndpoint> endpoints,
Collection<MlModelImporter> modelImporters,
Zone zone,
QueryProfiles queryProfiles,
@@ -115,6 +118,7 @@ public class DeployState implements ConfigDefinitionStore {
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
this.semanticRules = semanticRules; // TODO: Remove this by seeing how pagetemplates are propagated
@@ -234,6 +238,10 @@ public class DeployState implements ConfigDefinitionStore {
return this.rotations; // todo: consider returning a copy or immutable view
}
+ public Set<ContainerEndpoint> getEndpoints() {
+ return endpoints;
+ }
+
/** Returns the zone in which this is currently running */
public Zone zone() { return zone; }
@@ -260,6 +268,7 @@ public class DeployState implements ConfigDefinitionStore {
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();
private Instant now = Instant.now();
@@ -315,6 +324,11 @@ public class DeployState implements ConfigDefinitionStore {
return this;
}
+ public Builder endpoints(Set<ContainerEndpoint> endpoints) {
+ this.endpoints = endpoints;
+ return this;
+ }
+
public Builder modelImporters(Collection<MlModelImporter> modelImporters) {
this.modelImporters = modelImporters;
return this;
@@ -356,6 +370,7 @@ public class DeployState implements ConfigDefinitionStore {
configDefinitionRepo,
previousModel,
rotations,
+ endpoints,
modelImporters,
zone,
queryProfiles,
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 0a54dd6790d..87ff9d1bb2a 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
@@ -3,6 +3,7 @@ package com.yahoo.config.model.deploy;
import com.google.common.collect.ImmutableList;
import com.yahoo.config.model.api.ConfigServerSpec;
+import com.yahoo.config.model.api.ContainerEndpoint;
import com.yahoo.config.model.api.ModelContext;
import com.yahoo.config.provision.ApplicationId;
import com.yahoo.config.provision.HostName;
@@ -31,6 +32,7 @@ public class TestProperties implements ModelContext.Properties {
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;
private boolean useDedicatedNodeForLogserver = false;
@@ -48,6 +50,8 @@ public class TestProperties implements ModelContext.Properties {
@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; }
@Override public boolean isFirstTimeDeployment() { return isFirstTimeDeployment; }
@Override public boolean useAdaptiveDispatch() { return useAdaptiveDispatch; }
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 af6400023cc..f69330eb196 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
@@ -139,6 +139,7 @@ public class VespaModelFactory implements ModelFactory {
.vespaVersion(version())
.modelHostProvisioner(createHostProvisioner(modelContext))
.rotations(modelContext.properties().rotations())
+ .endpoints(modelContext.properties().endpoints())
.modelImporters(modelImporters)
.zone(zone)
.now(clock.instant())
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 642f882f3ed..f68ddecad9d 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
@@ -9,6 +9,7 @@ import com.yahoo.config.application.api.DeployLogger;
import com.yahoo.config.application.api.DeploymentSpec;
import com.yahoo.config.model.ConfigModelContext;
import com.yahoo.config.model.api.ConfigServerSpec;
+import com.yahoo.config.model.api.ContainerEndpoint;
import com.yahoo.config.model.application.provider.IncludeDirs;
import com.yahoo.config.model.builder.xml.ConfigModelBuilder;
import com.yahoo.config.model.builder.xml.ConfigModelId;
@@ -72,6 +73,7 @@ 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;
@@ -212,13 +214,13 @@ public class ContainerModelBuilder extends ConfigModelBuilder<ContainerModel> {
context.getDeployState().getProperties().athenzDnsSuffix(),
context.getDeployState().zone(),
deploymentSpec);
- addRotationProperties(cluster, context.getDeployState().zone(), context.getDeployState().getRotations(), deploymentSpec);
+ addRotationProperties(cluster, context.getDeployState().zone(), context.getDeployState().getRotations(), context.getDeployState().getEndpoints(), deploymentSpec);
});
}
- private void addRotationProperties(ApplicationContainerCluster cluster, Zone zone, Set<Rotation> rotations, DeploymentSpec spec) {
+ private void addRotationProperties(ApplicationContainerCluster cluster, Zone zone, Set<Rotation> rotations, Set<ContainerEndpoint> endpoints, DeploymentSpec spec) {
cluster.getContainers().forEach(container -> {
- setRotations(container, rotations, spec.globalServiceId(), cluster.getName());
+ setRotations(container, rotations, endpoints, spec.globalServiceId(), cluster.getName());
container.setProp("activeRotation", Boolean.toString(zoneHasActiveRotation(zone, spec)));
});
}
@@ -229,13 +231,30 @@ public class ContainerModelBuilder extends ConfigModelBuilder<ContainerModel> {
declaredZone.active());
}
- private void setRotations(Container container, Set<Rotation> rotations, Optional<String> globalServiceId, String containerClusterName) {
+ 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())) {
- container.setProp("rotations", rotations.stream().map(Rotation::getId).collect(Collectors.joining(",")));
+ 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);
+
+ // Build the comma delimited list of endpoints this container should be known as.
+ // Confusingly called 'rotations' for legacy reasons.
+ container.setProp("rotations", String.join(",", rotationsProperty));
}
private void addRoutingAliases(ApplicationContainerCluster cluster, Element spec, Environment environment) {
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilderTest.java b/config-model/src/test/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilderTest.java
index c7816c23119..f787453dfb6 100644
--- a/config-model/src/test/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilderTest.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilderTest.java
@@ -6,6 +6,7 @@ import com.yahoo.component.ComponentId;
import com.yahoo.config.application.api.ApplicationPackage;
import com.yahoo.config.application.api.DeployLogger;
import com.yahoo.config.model.NullConfigModelRegistry;
+import com.yahoo.config.model.api.ContainerEndpoint;
import com.yahoo.config.model.builder.xml.test.DomBuilderTest;
import com.yahoo.config.model.deploy.DeployState;
import com.yahoo.config.model.deploy.TestProperties;
@@ -33,6 +34,7 @@ import com.yahoo.vespa.model.AbstractService;
import com.yahoo.vespa.model.VespaModel;
import com.yahoo.vespa.model.container.Container;
import com.yahoo.vespa.model.container.ContainerCluster;
+import com.yahoo.vespa.model.container.ContainerModel;
import com.yahoo.vespa.model.container.SecretStore;
import com.yahoo.vespa.model.container.component.Component;
import com.yahoo.vespa.model.content.utils.ContentClusterUtils;
@@ -45,8 +47,11 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import java.util.logging.Level;
+import java.util.stream.Collectors;
+import static com.yahoo.config.model.test.TestUtil.joinLines;
import static com.yahoo.test.LinePatternMatcher.containsLineWithPattern;
import static com.yahoo.vespa.defaults.Defaults.getDefaults;
import static org.hamcrest.CoreMatchers.is;
@@ -611,6 +616,48 @@ public class ContainerModelBuilderTest extends ContainerModelBuilderTestBase {
}
@Test
+ public void endpoints_are_added_to_containers() throws IOException, SAXException {
+ final var servicesXml = joinLines("",
+ "<container id='comics-search' version='1.0'>",
+ " <nodes>",
+ " <node hostalias='host1' />",
+ " </nodes>",
+ "</container>"
+ );
+
+ final var deploymentXml = joinLines("",
+ "<deployment version='1.0'>",
+ " <prod />",
+ "</deployment>"
+ );
+
+ final var applicationPackage = new MockApplicationPackage.Builder()
+ .withServices(servicesXml)
+ .withDeploymentSpec(deploymentXml)
+ .build();
+
+ final var deployState = new DeployState.Builder()
+ .applicationPackage(applicationPackage)
+ .zone(new Zone(Environment.prod, RegionName.from("us-east-1")))
+ .endpoints(Set.of(new ContainerEndpoint("comics-search", List.of("nalle", "balle"))))
+ .properties(new TestProperties().setHostedVespa(true))
+ .build();
+
+ final var model = new VespaModel(new NullConfigModelRegistry(), deployState);
+ final var containers = model.getContainerClusters().values().stream()
+ .flatMap(cluster -> cluster.getContainers().stream())
+ .collect(Collectors.toList());
+
+ assertFalse("Missing container objects based on configuration", containers.isEmpty());
+
+ containers.forEach(container -> {
+ final var rotations = container.getServicePropertyString("rotations").split(",");
+ final var rotationsSet = Set.of(rotations);
+ assertEquals(Set.of("balle", "nalle"), rotationsSet);
+ });
+ }
+
+ @Test
public void singlenode_servicespec_is_used_with_hosted_vespa() throws IOException, SAXException {
String servicesXml = "<container id='default' version='1.0' />";
ApplicationPackage applicationPackage = new MockApplicationPackage.Builder().withServices(servicesXml).build();
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 fc6667087c6..4627d350eb2 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
@@ -7,6 +7,7 @@ import com.yahoo.config.application.api.DeployLogger;
import com.yahoo.config.application.api.FileRegistry;
import com.yahoo.config.model.api.ConfigDefinitionRepo;
import com.yahoo.config.model.api.ConfigServerSpec;
+import com.yahoo.config.model.api.ContainerEndpoint;
import com.yahoo.config.model.api.HostProvisioner;
import com.yahoo.config.model.api.Model;
import com.yahoo.config.model.api.ModelContext;
@@ -126,6 +127,7 @@ public class ModelContextImpl implements ModelContext {
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;
private final boolean useDedicatedNodeForLogserver;
@@ -142,6 +144,7 @@ public class ModelContextImpl implements ModelContext {
boolean hostedVespa,
Zone zone,
Set<Rotation> rotations,
+ Set<ContainerEndpoint> endpoints,
boolean isBootstrap,
boolean isFirstTimeDeployment,
FlagSource flagSource) {
@@ -154,6 +157,7 @@ public class ModelContextImpl implements ModelContext {
this.hostedVespa = hostedVespa;
this.zone = zone;
this.rotations = rotations;
+ this.endpoints = endpoints;
this.isBootstrap = isBootstrap;
this.isFirstTimeDeployment = isFirstTimeDeployment;
this.useDedicatedNodeForLogserver = Flags.USE_DEDICATED_NODE_FOR_LOGSERVER.bindTo(flagSource)
@@ -198,6 +202,9 @@ public class ModelContextImpl implements ModelContext {
public Set<Rotation> rotations() { return rotations; }
@Override
+ public Set<ContainerEndpoint> endpoints() { return endpoints; }
+
+ @Override
public boolean isBootstrap() { return isBootstrap; }
@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 6351a93e6e6..117a9e0cac5 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
@@ -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.modelfactory;
+import com.google.common.collect.ImmutableSet;
import com.yahoo.component.Version;
import com.yahoo.config.application.api.ApplicationPackage;
import com.yahoo.config.application.api.DeployLogger;
@@ -24,6 +25,7 @@ import com.yahoo.vespa.config.server.monitoring.Metrics;
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.curator.Curator;
@@ -127,6 +129,7 @@ public class ActivatedModelsBuilder extends ModelsBuilder<Application> {
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
flagSource);
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 4cabf39edcc..00a7625ee87 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
@@ -10,7 +10,7 @@ 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.vespa.config.server.tenant.ContainerEndpoint;
+import com.yahoo.config.model.api.ContainerEndpoint;
import com.yahoo.vespa.config.server.tenant.ContainerEndpointSerializer;
import java.time.Clock;
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 7af61a6efc1..30ba9989343 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
@@ -2,6 +2,7 @@
package com.yahoo.vespa.config.server.session;
import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
import com.google.inject.Inject;
import com.yahoo.cloud.config.ConfigserverConfig;
import com.yahoo.component.Version;
@@ -20,7 +21,6 @@ import com.yahoo.config.provision.Zone;
import com.yahoo.lang.SettableOptional;
import com.yahoo.log.LogLevel;
import com.yahoo.path.Path;
-import com.yahoo.vespa.applicationmodel.ClusterId;
import com.yahoo.vespa.config.server.ConfigServerSpec;
import com.yahoo.vespa.config.server.application.ApplicationSet;
import com.yahoo.vespa.config.server.application.PermanentApplicationPackage;
@@ -31,7 +31,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.vespa.config.server.tenant.ContainerEndpoint;
+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.curator.Curator;
@@ -43,6 +43,7 @@ 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;
@@ -142,6 +143,7 @@ public class SessionPreparer {
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 ApplicationPackage applicationPackage;
@@ -163,6 +165,7 @@ public class SessionPreparer {
this.rotations = new Rotations(curator, tenantPath);
this.containerEndpoints = new ContainerEndpointsCache(tenantPath, curator);
this.rotationsSet = getRotations(params.rotations());
+ this.endpointsSet = getEndpoints(params.containerEndpoints());
this.properties = new ModelContextImpl.Properties(params.getApplicationId(),
configserverConfig.multitenant(),
ConfigServerSpec.fromConfig(configserverConfig),
@@ -172,6 +175,7 @@ public class SessionPreparer {
configserverConfig.hostedVespa(),
zone,
rotationsSet,
+ endpointsSet,
params.isBootstrap(),
! currentActiveApplicationSet.isPresent(),
context.getFlagSource());
@@ -266,10 +270,17 @@ public class SessionPreparer {
return rotations;
}
+ private Set<ContainerEndpoint> getEndpoints(List<ContainerEndpoint> endpoints) {
+ if (endpoints == null || endpoints.isEmpty()) {
+ endpoints = this.containerEndpoints.read(applicationId);
+ }
+ return ImmutableSet.copyOf(endpoints);
+ }
+
}
private static List<ContainerEndpoint> toContainerEndpoints(String globalServceId, Set<Rotation> rotations) {
- return List.of(new ContainerEndpoint(new ClusterId(globalServceId),
+ return List.of(new ContainerEndpoint(globalServceId,
rotations.stream()
.map(Rotation::getId)
.collect(Collectors.toUnmodifiableList())));
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/tenant/ContainerEndpointSerializer.java b/configserver/src/main/java/com/yahoo/vespa/config/server/tenant/ContainerEndpointSerializer.java
index 91f9e3c8eed..4ffce8a697e 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/tenant/ContainerEndpointSerializer.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/tenant/ContainerEndpointSerializer.java
@@ -1,11 +1,11 @@
// Copyright 2019 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.yahoo.config.model.api.ContainerEndpoint;
import com.yahoo.slime.ArrayTraverser;
import com.yahoo.slime.Cursor;
import com.yahoo.slime.Inspector;
import com.yahoo.slime.Slime;
-import com.yahoo.vespa.applicationmodel.ClusterId;
import java.util.ArrayList;
import java.util.List;
@@ -49,7 +49,7 @@ public class ContainerEndpointSerializer {
names.add(containerName);
});
- return new ContainerEndpoint(new ClusterId(clusterId), names);
+ return new ContainerEndpoint(clusterId, names);
}
public static List<ContainerEndpoint> endpointListFromSlime(Slime slime) {
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 7e29f9abc1d..9bce1224d96 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
@@ -1,6 +1,7 @@
// Copyright 2019 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.yahoo.config.model.api.ContainerEndpoint;
import com.yahoo.config.provision.ApplicationId;
import com.yahoo.path.Path;
import com.yahoo.vespa.config.SlimeUtils;
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 23326474371..b483705e3f5 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
@@ -2,6 +2,7 @@
package com.yahoo.vespa.config.server;
import com.yahoo.component.Version;
+import com.yahoo.config.model.api.ContainerEndpoint;
import com.yahoo.config.model.api.ModelContext;
import com.yahoo.config.model.application.provider.BaseDeployLogger;
import com.yahoo.config.model.application.provider.MockFileRegistry;
@@ -14,6 +15,7 @@ import com.yahoo.vespa.flags.InMemoryFlagSource;
import org.junit.Test;
import java.util.Collections;
+import java.util.List;
import java.util.Optional;
import java.util.Set;
@@ -33,6 +35,10 @@ public class ModelContextImplTest {
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();
ModelContext context = new ModelContextImpl(
@@ -53,6 +59,7 @@ public class ModelContextImplTest {
false,
Zone.defaultZone(),
rotations,
+ endpoints,
false,
false,
flagSource),
@@ -71,6 +78,7 @@ public class ModelContextImplTest {
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));
assertThat(context.properties().useDedicatedNodeForLogserver(), equalTo(true));
}
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 395c1ecb80b..1f99f59eb8e 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
@@ -5,6 +5,7 @@ import com.yahoo.cloud.config.LbServicesConfig;
import com.yahoo.config.application.api.ApplicationPackage;
import com.yahoo.config.model.NullConfigModelRegistry;
import com.yahoo.config.model.api.ApplicationInfo;
+import com.yahoo.config.model.api.ContainerEndpoint;
import com.yahoo.config.model.api.Model;
import com.yahoo.config.model.deploy.DeployState;
import com.yahoo.config.model.deploy.TestProperties;
@@ -20,11 +21,14 @@ import com.yahoo.vespa.flags.Flags;
import com.yahoo.vespa.flags.InMemoryFlagSource;
import com.yahoo.vespa.model.VespaModel;
import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
import org.xml.sax.SAXException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.Comparator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
@@ -33,20 +37,34 @@ import java.util.Random;
import java.util.Set;
import static com.yahoo.config.model.api.container.ContainerServiceType.QRSERVER;
-import static org.hamcrest.Matchers.is;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.assertTrue;
+import static org.hamcrest.Matchers.*;
+import static org.junit.Assert.*;
+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"))
+ );
private final InMemoryFlagSource flagSource = new InMemoryFlagSource();
+ private final boolean useGlobalServiceId;
+
+ @Parameterized.Parameters
+ public static Object[] useGlobalServiceId() {
+ return new Object[] { true, false };
+ }
+
+ public LbServicesProducerTest(boolean useGlobalServiceId) {
+ this.useGlobalServiceId = useGlobalServiceId;
+ }
@Test
public void testDeterministicGetConfig() throws IOException, SAXException {
@@ -123,20 +141,40 @@ 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");
- LbServicesConfig conf = getLbServicesConfig(new Zone(Environment.prod, regionName), testModel);
- final LbServicesConfig.Tenants.Applications.Hosts.Services services = conf.tenants("foo").applications("foo:prod:" + regionName.value() + ":default").hosts("foo.foo.yahoo.com").services(QRSERVER.serviceName);
- assertThat(services.servicealiases().size(), is(1));
- assertThat(services.endpointaliases().size(), is(4));
- assertThat(services.servicealiases(0), is("service1"));
- assertThat(services.endpointaliases(0), is("foo1.bar1.com"));
- assertThat(services.endpointaliases(1), is("foo2.bar2.com"));
- assertThat(services.endpointaliases(2), is(rotation1));
- assertThat(services.endpointaliases(3), is(rotation2));
+ 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);
+
+ Map<TenantName, Set<ApplicationInfo>> testModel = createTestModel(new DeployState.Builder()
+ .endpoints(endpoints)
+ .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 endpoints in list: " + services.endpointaliases(), services.endpointaliases(), containsInAnyOrder("foo1.bar1.com", "foo2.bar2.com", rotation1, rotation2));
}
private Map<TenantName, Set<ApplicationInfo>> randomizeApplications(Map<TenantName, Set<ApplicationInfo>> testModel, int seed) {
@@ -195,14 +233,32 @@ public class LbServicesProducerTest {
" <search/>" +
"</jdisc>" +
"</services>";
- String deploymentInfo ="<?xml version='1.0' encoding='UTF-8'?>" +
- "<deployment version='1.0'>" +
- " <test />" +
- " <prod global-service-id='mydisc'>" +
- " <region active='true'>us-east-1</region>" +
- " <region active='false'>us-east-2</region>" +
- " </prod>" +
- "</deployment>";
+
+ String deploymentInfo;
+
+ if (useGlobalServiceId) {
+ deploymentInfo ="<?xml version='1.0' encoding='UTF-8'?>" +
+ "<deployment version='1.0'>" +
+ " <test />" +
+ " <prod global-service-id='mydisc'>" +
+ " <region active='true'>us-east-1</region>" +
+ " <region active='false'>us-east-2</region>" +
+ " </prod>" +
+ "</deployment>";
+ } else {
+ deploymentInfo ="<?xml version='1.0' encoding='UTF-8'?>" +
+ "<deployment version='1.0'>" +
+ " <test />" +
+ " <prod>" +
+ " <region active='true'>us-east-1</region>" +
+ " <region active='false'>us-east-2</region>" +
+ " </prod>" +
+ " <endpoints>" +
+ " <endpoint container-id='mydisc' />" +
+ " </endpoints>" +
+ "</deployment>";
+ }
+
return new MockApplicationPackage.Builder().withHosts(hosts).withServices(services).withDeploymentSpec(deploymentInfo).build();
}
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 6eba85af37e..f5fd6053b07 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
@@ -6,8 +6,7 @@ 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.vespa.applicationmodel.ClusterId;
-import com.yahoo.vespa.config.server.tenant.ContainerEndpoint;
+import com.yahoo.config.model.api.ContainerEndpoint;
import org.junit.Test;
import java.net.URLEncoder;
@@ -84,10 +83,10 @@ public class PrepareParamsTest {
@Test
public void testCorrectParsingWithContainerEndpoints() {
- var endpoints = List.of(new ContainerEndpoint(new ClusterId("qrs1"),
+ var endpoints = List.of(new ContainerEndpoint("qrs1",
List.of("c1.example.com",
"c2.example.com")),
- new ContainerEndpoint(new ClusterId("qrs2"),
+ new ContainerEndpoint("qrs2",
List.of("c3.example.com",
"c4.example.com")));
var param = "[\n" +
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 6b2810af66c..74415993c52 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
@@ -15,7 +15,6 @@ import com.yahoo.io.IOUtils;
import com.yahoo.log.LogLevel;
import com.yahoo.path.Path;
import com.yahoo.slime.Slime;
-import com.yahoo.vespa.applicationmodel.ClusterId;
import com.yahoo.vespa.config.server.MockReloadHandler;
import com.yahoo.vespa.config.server.TestComponentRegistry;
import com.yahoo.vespa.config.server.TimeoutBudgetTest;
@@ -27,7 +26,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.vespa.config.server.tenant.ContainerEndpoint;
+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.zookeeper.ConfigCurator;
@@ -218,7 +217,7 @@ public class SessionPreparerTest {
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(new ClusterId("qrs"),
+ var expected = List.of(new ContainerEndpoint("qrs",
List.of("app1.tenant1.global.vespa.example.com",
"rotation-042.vespa.global.routing")));
assertEquals(expected, readContainerEndpoints(applicationId));
@@ -248,10 +247,10 @@ public class SessionPreparerTest {
.build();
prepare(new File("src/test/resources/deploy/hosted-app"), params);
- var expected = List.of(new ContainerEndpoint(new ClusterId("foo"),
+ var expected = List.of(new ContainerEndpoint("foo",
List.of("foo.app1.tenant1.global.vespa.example.com",
"rotation-042.vespa.global.routing")),
- new ContainerEndpoint(new ClusterId("bar"),
+ new ContainerEndpoint("bar",
List.of("bar.app1.tenant1.global.vespa.example.com",
"rotation-043.vespa.global.routing")));
assertEquals(expected, readContainerEndpoints(applicationId));
diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/tenant/ContainerEndpointSerializerTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/tenant/ContainerEndpointSerializerTest.java
index aac0b6d1a16..053a3f7a15d 100644
--- a/configserver/src/test/java/com/yahoo/vespa/config/server/tenant/ContainerEndpointSerializerTest.java
+++ b/configserver/src/test/java/com/yahoo/vespa/config/server/tenant/ContainerEndpointSerializerTest.java
@@ -1,7 +1,7 @@
package com.yahoo.vespa.config.server.tenant;
+import com.yahoo.config.model.api.ContainerEndpoint;
import com.yahoo.slime.Slime;
-import com.yahoo.vespa.applicationmodel.ClusterId;
import org.junit.Test;
import java.util.List;
@@ -30,7 +30,7 @@ public class ContainerEndpointSerializerTest {
@Test
public void writeReadSingleEndpoint() {
- final var endpoint = new ContainerEndpoint(new ClusterId("foo"), List.of("a", "b"));
+ final var endpoint = new ContainerEndpoint("foo", List.of("a", "b"));
final var serialized = new Slime();
ContainerEndpointSerializer.endpointToSlime(serialized.setObject(), endpoint);
final var deserialized = ContainerEndpointSerializer.endpointFromSlime(serialized.get());
@@ -40,7 +40,7 @@ public class ContainerEndpointSerializerTest {
@Test
public void writeReadEndpoints() {
- final var endpoints = List.of(new ContainerEndpoint(new ClusterId("foo"), List.of("a", "b")));
+ final var endpoints = List.of(new ContainerEndpoint("foo", List.of("a", "b")));
final var serialized = ContainerEndpointSerializer.endpointListToSlime(endpoints);
final var deserialized = ContainerEndpointSerializer.endpointListFromSlime(serialized);
diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/tenant/ContainerEndpointsCacheTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/tenant/ContainerEndpointsCacheTest.java
index 3598b6e63c3..4400b424d1b 100644
--- a/configserver/src/test/java/com/yahoo/vespa/config/server/tenant/ContainerEndpointsCacheTest.java
+++ b/configserver/src/test/java/com/yahoo/vespa/config/server/tenant/ContainerEndpointsCacheTest.java
@@ -1,9 +1,9 @@
// Copyright 2019 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.yahoo.config.model.api.ContainerEndpoint;
import com.yahoo.config.provision.ApplicationId;
import com.yahoo.path.Path;
-import com.yahoo.vespa.applicationmodel.ClusterId;
import com.yahoo.vespa.curator.mock.MockCurator;
import org.junit.Test;
@@ -17,7 +17,7 @@ public class ContainerEndpointsCacheTest {
public void readWriteFromCache() {
final var cache = new ContainerEndpointsCache(Path.createRoot(), new MockCurator());
final var endpoints = List.of(
- new ContainerEndpoint(new ClusterId("the-cluster-1"), List.of("a", "b", "c"))
+ new ContainerEndpoint("the-cluster-1", List.of("a", "b", "c"))
);
cache.write(ApplicationId.defaultId(), endpoints);