diff options
author | Morten Tokle <mortent@verizonmedia.com> | 2021-11-10 13:52:23 +0100 |
---|---|---|
committer | Morten Tokle <mortent@verizonmedia.com> | 2021-11-10 15:30:05 +0100 |
commit | ffb034aa6605c46fd52a00acdc74a7140269e3f5 (patch) | |
tree | a11317585b55070584b26cdedec3f353ee7af1e8 /config-model | |
parent | 58607cf37f94f150c42d68854c19d1a8ad50a92d (diff) |
Let config model generate endpoints
Diffstat (limited to 'config-model')
4 files changed, 128 insertions, 1 deletions
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 5183a3ca587..49c968a1d91 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 @@ -72,6 +72,7 @@ public class TestProperties implements ModelContext.Properties, ModelContext.Fea private double diskBloatFactor = 0.2; private boolean distributorEnhancedMaintenanceScheduling = false; private boolean asyncApplyBucketDiff = false; + private List<String> zoneDnsSuffixes = List.of(); @Override public ModelContext.FeatureFlags featureFlags() { return this; } @Override public boolean multitenant() { return multitenant; } @@ -124,6 +125,7 @@ public class TestProperties implements ModelContext.Properties, ModelContext.Fea @Override public boolean distributorEnhancedMaintenanceScheduling() { return distributorEnhancedMaintenanceScheduling; } @Override public int maxUnCommittedMemory() { return maxUnCommittedMemory; } @Override public boolean asyncApplyBucketDiff() { return asyncApplyBucketDiff; } + @Override public List<String> zoneDnsSuffixes() { return zoneDnsSuffixes; } public TestProperties maxUnCommittedMemory(int maxUnCommittedMemory) { this.maxUnCommittedMemory = maxUnCommittedMemory; @@ -320,6 +322,11 @@ public class TestProperties implements ModelContext.Properties, ModelContext.Fea return this; } + public TestProperties setZoneDnsSuffixes(List<String> zoneDnsSuffixes) { + this.zoneDnsSuffixes = List.copyOf(zoneDnsSuffixes); + return this; + } + public static class Spec implements ConfigServerSpec { private final String hostName; diff --git a/config-model/src/main/java/com/yahoo/vespa/model/VespaModel.java b/config-model/src/main/java/com/yahoo/vespa/model/VespaModel.java index d6c66a635d4..f584b4cd207 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/VespaModel.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/VespaModel.java @@ -18,6 +18,7 @@ import com.yahoo.config.model.ApplicationConfigProducerRoot; import com.yahoo.config.model.ConfigModelRegistry; import com.yahoo.config.model.ConfigModelRepo; import com.yahoo.config.model.NullConfigModelRegistry; +import com.yahoo.config.model.api.ApplicationClusterInfo; import com.yahoo.config.model.api.HostInfo; import com.yahoo.config.model.api.Model; import com.yahoo.config.model.api.Provisioned; @@ -696,4 +697,8 @@ public final class VespaModel extends AbstractConfigProducerRoot implements Seri .collect(Collectors.toSet()); } + @Override + public Set<ApplicationClusterInfo> applicationClusterInfo() { + return Set.copyOf(getContainerClusters().values()); + } } diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/ApplicationContainerCluster.java b/config-model/src/main/java/com/yahoo/vespa/model/container/ApplicationContainerCluster.java index c3897f49c44..4231cc7ffe3 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/container/ApplicationContainerCluster.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/container/ApplicationContainerCluster.java @@ -7,10 +7,14 @@ import com.yahoo.component.ComponentId; import com.yahoo.component.ComponentSpecification; import com.yahoo.config.FileReference; import com.yahoo.config.application.api.ComponentInfo; +import com.yahoo.config.model.api.ApplicationClusterEndpoint; +import com.yahoo.config.model.api.ApplicationClusterInfo; +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.producer.AbstractConfigProducer; import com.yahoo.config.provision.AllocatedHosts; +import com.yahoo.config.provision.ClusterSpec; import com.yahoo.config.provision.HostSpec; import com.yahoo.container.bundle.BundleInstantiationSpecification; import com.yahoo.container.di.config.ApplicationBundlesConfig; @@ -26,6 +30,7 @@ import com.yahoo.vespa.config.search.RankProfilesConfig; import com.yahoo.vespa.config.search.core.OnnxModelsConfig; import com.yahoo.vespa.config.search.core.RankingConstantsConfig; import com.yahoo.vespa.config.search.core.RankingExpressionsConfig; +import com.yahoo.vespa.model.AbstractService; import com.yahoo.vespa.model.admin.metricsproxy.MetricsProxyContainer; import com.yahoo.vespa.model.container.component.BindingPattern; import com.yahoo.vespa.model.container.component.Component; @@ -39,6 +44,7 @@ import com.yahoo.vespa.model.utils.FileSender; import java.util.ArrayList; import java.util.Collection; import java.util.LinkedHashSet; +import java.util.List; import java.util.Map; import java.util.Optional; import java.util.Set; @@ -60,7 +66,8 @@ public final class ApplicationContainerCluster extends ContainerCluster<Applicat ServletPathsConfig.Producer, ContainerMbusConfig.Producer, MetricsProxyApiConfig.Producer, - ZookeeperServerConfig.Producer { + ZookeeperServerConfig.Producer, + ApplicationClusterInfo { public static final String METRICS_V2_HANDLER_CLASS = MetricsV2Handler.class.getName(); public static final BindingPattern METRICS_V2_HANDLER_BINDING_1 = SystemBindingPattern.fromHttpPath(MetricsV2Handler.V2_PATH); @@ -88,6 +95,8 @@ public final class ApplicationContainerCluster extends ContainerCluster<Applicat private Integer memoryPercentage = null; + private List<ApplicationClusterEndpoint> endpointList = List.of(); + public ApplicationContainerCluster(AbstractConfigProducer<?> parent, String configSubId, String clusterId, DeployState deployState) { super(parent, configSubId, clusterId, deployState, true); this.tlsClientAuthority = deployState.tlsClientAuthority(); @@ -115,6 +124,7 @@ public final class ApplicationContainerCluster extends ContainerCluster<Applicat protected void doPrepare(DeployState deployState) { addAndSendApplicationBundles(deployState); sendUserConfiguredFiles(deployState); + createEndpointList(deployState); } private void addAndSendApplicationBundles(DeployState deployState) { @@ -184,6 +194,60 @@ public final class ApplicationContainerCluster extends ContainerCluster<Applicat */ public Optional<Integer> getMemoryPercentage() { return Optional.ofNullable(memoryPercentage); } + /* + Create list of endpoints, these will be consumed later by the LBservicesProducer + */ + private void createEndpointList(DeployState deployState) { + + if( deployState.getProperties().applicationId().instance().isTester()) return; + List<ApplicationClusterEndpoint> endpoints = new ArrayList<>(); + // Add zone local endpoints using zone dns suffixes, tenant, application and cluster id. + // For now support both L7 and L4 routing + + List<String> hosts = getContainers().stream() + .map(AbstractService::getHostName) + .collect(Collectors.toList()); + for(String suffix : deployState.getProperties().zoneDnsSuffixes()) { + // L4 + ApplicationClusterEndpoint.DnsName l4Name = ApplicationClusterEndpoint.DnsName.sharedL4NameFrom( + ClusterSpec.Id.from(getName()), + deployState.getProperties().applicationId(), + suffix); + endpoints.add(ApplicationClusterEndpoint.builder() + .zoneScope() + .sharedL4Routing() + .dnsName(l4Name) + .hosts(hosts) + .build()); + + // L7 + ApplicationClusterEndpoint.DnsName l7Name = ApplicationClusterEndpoint.DnsName.sharedNameFrom( + ClusterSpec.Id.from(getName()), + deployState.getProperties().applicationId(), + suffix); + endpoints.add(ApplicationClusterEndpoint.builder() + .zoneScope() + .sharedRouting() + .dnsName(l7Name) + .hosts(hosts) + .build()); + } + + // Then get all endpoints provided by controller. Can be created with L4 routing only + Set<ContainerEndpoint> endpointsFromController = deployState.getEndpoints(); + endpointsFromController.stream() + .filter(ce -> ce.clusterId().equals(getName())) + .forEach(ce -> ce.names().forEach( + name -> endpoints.add(ApplicationClusterEndpoint.builder() + .globalScope() + .sharedL4Routing() + .dnsName(ApplicationClusterEndpoint.DnsName.from(name)) + .hosts(hosts) + .build()) + )); + endpointList = List.copyOf(endpoints); + } + @Override public void getConfig(ApplicationBundlesConfig.Builder builder) { applicationBundles.stream().map(FileReference::value) @@ -293,6 +357,11 @@ public final class ApplicationContainerCluster extends ContainerCluster<Applicat null)))); } + @Override + public List<ApplicationClusterEndpoint> endpoints() { + return endpointList; + } + public static class MbusParams { // the amount of the maxpendingbytes to process concurrently, typically 0.2 (20%) final Double maxConcurrentFactor; diff --git a/config-model/src/test/java/com/yahoo/vespa/model/container/ContainerClusterTest.java b/config-model/src/test/java/com/yahoo/vespa/model/container/ContainerClusterTest.java index 7190a7d4db1..900aee40720 100755 --- a/config-model/src/test/java/com/yahoo/vespa/model/container/ContainerClusterTest.java +++ b/config-model/src/test/java/com/yahoo/vespa/model/container/ContainerClusterTest.java @@ -7,6 +7,8 @@ import com.yahoo.cloud.config.CuratorConfig; import com.yahoo.cloud.config.ZookeeperServerConfig; import com.yahoo.component.ComponentId; import com.yahoo.config.application.api.DeployLogger; +import com.yahoo.config.model.api.ApplicationClusterEndpoint; +import com.yahoo.config.model.api.ContainerEndpoint; import com.yahoo.config.model.deploy.DeployState; import com.yahoo.config.model.deploy.TestProperties; import com.yahoo.config.model.test.MockApplicationPackage; @@ -36,8 +38,11 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.List; +import java.util.Objects; +import java.util.Set; import java.util.stream.Collectors; +import static org.hamcrest.Matchers.containsInAnyOrder; import static org.hamcrest.Matchers.hasItem; import static org.hamcrest.Matchers.hasKey; import static org.junit.Assert.assertEquals; @@ -351,6 +356,47 @@ public class ContainerClusterTest { } + @Test + public void generatesCorrectRoutingInfo() { + + assertNames(ApplicationId.from("t1", "a1", "i1"), + Set.of(), + List.of("search-cluster.i1.a1.t1.endpoint.suffix", "search-cluster--i1--a1--t1.endpoint.suffix")); + + assertNames(ApplicationId.from("t1", "a1", "default"), + Set.of(), + List.of("search-cluster.a1.t1.endpoint.suffix", "search-cluster--a1--t1.endpoint.suffix")); + + assertNames(ApplicationId.from("t1", "default", "default"), + Set.of(), + List.of("search-cluster.default.t1.endpoint.suffix", "search-cluster--default--t1.endpoint.suffix")); + + assertNames(ApplicationId.from("t1", "a1", "default"), + Set.of(new ContainerEndpoint("not-in-this-cluster", List.of("foo", "bar"))), + List.of("search-cluster.a1.t1.endpoint.suffix", "search-cluster--a1--t1.endpoint.suffix")); + + assertNames(ApplicationId.from("t1", "a1", "default"), + Set.of(new ContainerEndpoint("search-cluster", List.of("rotation-1.x.y.z", "rotation-2.x.y.z"))), + List.of("search-cluster.a1.t1.endpoint.suffix", "search-cluster--a1--t1.endpoint.suffix", "rotation-1.x.y.z", "rotation-2.x.y.z")); + } + + private void assertNames(ApplicationId appId, Set<ContainerEndpoint> globalEndpoints, List<String> expectedNames) { + DeployState state = new DeployState.Builder() + .zone(Zone.defaultZone()) + .endpoints(globalEndpoints) + .properties(new TestProperties() + .setApplicationId(appId) + .setZoneDnsSuffixes(List.of(".endpoint.suffix"))) + .build(); + MockRoot root = new MockRoot("foo", state); + ApplicationContainerCluster cluster = new ApplicationContainerCluster(root, "container", "search-cluster", state); + addContainer(root, cluster, "c1", "host-c1"); + cluster.doPrepare(state); + List<ApplicationClusterEndpoint> endpoints = cluster.endpoints(); + assertEquals(expectedNames.size(), endpoints.size()); + expectedNames.forEach(expected -> assertTrue("Endpoint not matched " + expected, endpoints.stream().anyMatch(e -> Objects.equals(e.dnsName().value(), expected)))); + } + private void verifyTesterApplicationInstalledBundles(Zone zone, List<String> expectedBundleNames) { ApplicationId appId = ApplicationId.from("tenant", "application", "instance-t"); DeployState state = new DeployState.Builder().properties( |