aboutsummaryrefslogtreecommitdiffstats
path: root/configserver
diff options
context:
space:
mode:
authorHarald Musum <musum@verizonmedia.com>2020-05-12 07:18:29 +0200
committerHarald Musum <musum@verizonmedia.com>2020-05-12 07:18:29 +0200
commit26fa530aedff254dc8871f7395b54c8d3487f336 (patch)
tree15554afef8d9f5884b5998a19147ffe927017f8c /configserver
parent3da1c0480f2f12e63abee601ba630f42e966e6de (diff)
Distribute application package to other config servers
Diffstat (limited to 'configserver')
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/modelfactory/PreparedModelsBuilder.java27
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/session/SessionPreparer.java26
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/TestComponentRegistry.java14
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/session/MockFileDistributionFactory.java3
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/session/SessionPreparerTest.java8
5 files changed, 43 insertions, 35 deletions
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/modelfactory/PreparedModelsBuilder.java b/configserver/src/main/java/com/yahoo/vespa/config/server/modelfactory/PreparedModelsBuilder.java
index b8e7d68ea5e..fb2ba9324e8 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/modelfactory/PreparedModelsBuilder.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/modelfactory/PreparedModelsBuilder.java
@@ -6,6 +6,7 @@ import com.yahoo.config.application.api.ApplicationPackage;
import com.yahoo.config.application.api.DeployLogger;
import com.yahoo.config.model.api.ConfigChangeAction;
import com.yahoo.config.model.api.ConfigDefinitionRepo;
+import com.yahoo.config.model.api.HostInfo;
import com.yahoo.config.model.api.HostProvisioner;
import com.yahoo.config.model.api.Model;
import com.yahoo.config.model.api.ModelContext;
@@ -22,13 +23,12 @@ import com.yahoo.config.provision.DockerImage;
import java.util.logging.Level;
import com.yahoo.vespa.config.server.application.Application;
import com.yahoo.vespa.config.server.application.ApplicationSet;
+import com.yahoo.vespa.config.server.filedistribution.FileDistributionProvider;
import com.yahoo.vespa.config.server.host.HostValidator;
import com.yahoo.vespa.config.server.application.PermanentApplicationPackage;
import com.yahoo.vespa.config.server.deploy.ModelContextImpl;
-import com.yahoo.vespa.config.server.filedistribution.FileDistributionProvider;
import com.yahoo.vespa.config.server.provision.HostProvisionerProvider;
import com.yahoo.vespa.config.server.provision.StaticProvisioner;
-import com.yahoo.vespa.config.server.session.FileDistributionFactory;
import com.yahoo.vespa.config.server.session.PrepareParams;
import com.yahoo.vespa.config.server.session.SessionContext;
@@ -52,14 +52,14 @@ public class PreparedModelsBuilder extends ModelsBuilder<PreparedModelsBuilder.P
private final SessionContext context;
private final DeployLogger logger;
private final PrepareParams params;
- private final FileDistributionFactory fileDistributionFactory;
+ private final FileDistributionProvider fileDistributionProvider;
private final Optional<ApplicationSet> currentActiveApplicationSet;
private final ModelContext.Properties properties;
public PreparedModelsBuilder(ModelFactoryRegistry modelFactoryRegistry,
PermanentApplicationPackage permanentApplicationPackage,
ConfigDefinitionRepo configDefinitionRepo,
- FileDistributionFactory fileDistributionFactory,
+ FileDistributionProvider fileDistributionProvider,
HostProvisionerProvider hostProvisionerProvider,
SessionContext context,
DeployLogger logger,
@@ -70,14 +70,11 @@ public class PreparedModelsBuilder extends ModelsBuilder<PreparedModelsBuilder.P
super(modelFactoryRegistry, configserverConfig, properties.zone(), hostProvisionerProvider);
this.permanentApplicationPackage = permanentApplicationPackage;
this.configDefinitionRepo = configDefinitionRepo;
-
- this.fileDistributionFactory = fileDistributionFactory;
-
+ this.fileDistributionProvider = fileDistributionProvider;
this.context = context;
this.logger = logger;
this.params = params;
this.currentActiveApplicationSet = currentActiveApplicationSet;
-
this.properties = properties;
}
@@ -91,7 +88,6 @@ public class PreparedModelsBuilder extends ModelsBuilder<PreparedModelsBuilder.P
Instant now) {
Version modelVersion = modelFactory.version();
log.log(Level.FINE, "Building model " + modelVersion + " for " + applicationId);
- FileDistributionProvider fileDistributionProvider = fileDistributionFactory.createProvider(context.getServerDBSessionDir());
// Use empty on non-hosted systems, use already allocated hosts if available, create connection to a host provisioner otherwise
Provisioned provisioned = new Provisioned();
@@ -120,7 +116,7 @@ public class PreparedModelsBuilder extends ModelsBuilder<PreparedModelsBuilder.P
}
private Optional<Model> modelOf(Version version) {
- if ( ! currentActiveApplicationSet.isPresent()) return Optional.empty();
+ if (currentActiveApplicationSet.isEmpty()) return Optional.empty();
return currentActiveApplicationSet.get().get(version).map(Application::getModel);
}
@@ -130,12 +126,12 @@ public class PreparedModelsBuilder extends ModelsBuilder<PreparedModelsBuilder.P
Provisioned provisioned) {
Optional<HostProvisioner> nodeRepositoryProvisioner = createNodeRepositoryProvisioner(properties.applicationId(),
provisioned);
- if ( ! allocatedHosts.isPresent()) return nodeRepositoryProvisioner;
+ if (allocatedHosts.isEmpty()) return nodeRepositoryProvisioner;
Optional<HostProvisioner> staticProvisioner = createStaticProvisioner(allocatedHosts,
properties.applicationId(),
provisioned);
- if ( ! staticProvisioner.isPresent()) return Optional.empty(); // Since we have hosts allocated this means we are on non-hosted
+ if (staticProvisioner.isEmpty()) return Optional.empty(); // Since we have hosts allocated this means we are on non-hosted
// Nodes are already allocated by a model and we should use them unless this model requests hosts from a
// previously unallocated cluster. This allows future models to stop allocate certain clusters.
@@ -153,7 +149,8 @@ public class PreparedModelsBuilder extends ModelsBuilder<PreparedModelsBuilder.P
}
private void validateModelHosts(HostValidator<ApplicationId> hostValidator, ApplicationId applicationId, Model model) {
- hostValidator.verifyHosts(applicationId, model.getHosts().stream().map(hostInfo -> hostInfo.getHostname())
+ hostValidator.verifyHosts(applicationId, model.getHosts().stream()
+ .map(HostInfo::getHostname)
.collect(Collectors.toList()));
}
@@ -162,11 +159,11 @@ public class PreparedModelsBuilder extends ModelsBuilder<PreparedModelsBuilder.P
public final Version version;
public final Model model;
- public final FileDistributionProvider fileDistributionProvider;
+ public final com.yahoo.vespa.config.server.filedistribution.FileDistributionProvider fileDistributionProvider;
public final List<ConfigChangeAction> actions;
public PreparedModelResult(Version version, Model model,
- FileDistributionProvider fileDistributionProvider, List<ConfigChangeAction> actions) {
+ com.yahoo.vespa.config.server.filedistribution.FileDistributionProvider fileDistributionProvider, List<ConfigChangeAction> actions) {
this.version = version;
this.model = model;
this.fileDistributionProvider = fileDistributionProvider;
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 00cafb77f6d..c882f10ab68 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
@@ -7,12 +7,14 @@ import com.google.inject.Inject;
import com.yahoo.cloud.config.ConfigserverConfig;
import com.yahoo.component.Version;
import com.yahoo.component.Vtag;
+import com.yahoo.config.FileReference;
import com.yahoo.config.application.api.ApplicationPackage;
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.ContainerEndpoint;
import com.yahoo.config.model.api.EndpointCertificateMetadata;
+import com.yahoo.config.model.api.FileDistribution;
import com.yahoo.config.model.api.ModelContext;
import com.yahoo.config.model.api.EndpointCertificateSecrets;
import com.yahoo.config.provision.AllocatedHosts;
@@ -23,6 +25,7 @@ import com.yahoo.config.provision.HostName;
import com.yahoo.config.provision.Zone;
import com.yahoo.container.jdisc.secretstore.SecretStore;
import com.yahoo.lang.SettableOptional;
+
import java.util.logging.Level;
import com.yahoo.path.Path;
import com.yahoo.vespa.config.server.ConfigServerSpec;
@@ -31,6 +34,7 @@ import com.yahoo.vespa.config.server.application.PermanentApplicationPackage;
import com.yahoo.vespa.config.server.configchange.ConfigChangeActions;
import com.yahoo.vespa.config.server.deploy.ModelContextImpl;
import com.yahoo.vespa.config.server.deploy.ZooKeeperDeployer;
+import com.yahoo.vespa.config.server.filedistribution.FileDistributionProvider;
import com.yahoo.vespa.config.server.http.InvalidApplicationException;
import com.yahoo.vespa.config.server.modelfactory.ModelFactoryRegistry;
import com.yahoo.vespa.config.server.modelfactory.PreparedModelsBuilder;
@@ -112,6 +116,7 @@ public class SessionPreparer {
Optional<ApplicationSet> currentActiveApplicationSet, Path tenantPath,
Instant now) {
Preparation preparation = new Preparation(context, logger, params, currentActiveApplicationSet, tenantPath);
+ preparation.distributeApplicationPackage();
preparation.preprocess();
try {
AllocatedHosts allocatedHosts = preparation.buildModels(now);
@@ -161,6 +166,7 @@ public class SessionPreparer {
private PrepareResult prepareResult;
private final PreparedModelsBuilder preparedModelsBuilder;
+ private final FileDistributionProvider fileDistributionProvider;
Preparation(SessionContext context, DeployLogger logger, PrepareParams params,
Optional<ApplicationSet> currentActiveApplicationSet, Path tenantPath) {
@@ -169,24 +175,19 @@ public class SessionPreparer {
this.params = params;
this.currentActiveApplicationSet = currentActiveApplicationSet;
this.tenantPath = tenantPath;
-
this.applicationId = params.getApplicationId();
this.dockerImageRepository = params.dockerImageRepository();
this.vespaVersion = params.vespaVersion().orElse(Vtag.currentVersion);
this.containerEndpoints = new ContainerEndpointsCache(tenantPath, curator);
this.endpointCertificateMetadataStore = new EndpointCertificateMetadataStore(curator, tenantPath);
this.endpointCertificateRetriever = new EndpointCertificateRetriever(secretStore);
-
this.endpointCertificateMetadata = params.endpointCertificateMetadata()
.or(() -> params.tlsSecretsKeyName().map(EndpointCertificateMetadataSerializer::fromString));
-
endpointCertificateSecrets = endpointCertificateMetadata
.or(() -> endpointCertificateMetadataStore.readEndpointCertificateMetadata(applicationId))
.flatMap(endpointCertificateRetriever::readEndpointCertificateSecrets);
-
this.endpointsSet = getEndpoints(params.containerEndpoints());
this.athenzDomain = params.athenzDomain();
-
this.properties = new ModelContextImpl.Properties(params.getApplicationId(),
configserverConfig.multitenant(),
ConfigServerSpec.fromConfig(configserverConfig),
@@ -197,14 +198,15 @@ public class SessionPreparer {
zone,
endpointsSet,
params.isBootstrap(),
- ! currentActiveApplicationSet.isPresent(),
+ currentActiveApplicationSet.isEmpty(),
context.getFlagSource(),
endpointCertificateSecrets,
athenzDomain);
+ this.fileDistributionProvider = fileDistributionFactory.createProvider(context.getServerDBSessionDir());
this.preparedModelsBuilder = new PreparedModelsBuilder(modelFactoryRegistry,
permanentApplicationPackage,
configDefinitionRepo,
- fileDistributionFactory,
+ fileDistributionProvider,
hostProvisionerProvider,
context,
logger,
@@ -221,6 +223,16 @@ public class SessionPreparer {
}
}
+ void distributeApplicationPackage() {
+ FileRegistry fileRegistry = fileDistributionProvider.getFileRegistry();
+ FileReference fileReference = fileRegistry.addFile("");
+ FileDistribution fileDistribution = fileDistributionProvider.getFileDistribution();
+ log.log(Level.INFO, "Distribute application package for " + applicationId + " (" + fileReference + ") to other config servers");
+ properties.configServerSpecs().stream()
+ .filter(spec -> ! spec.getHostName().equals(fileRegistry.fileSourceHost()))
+ .forEach(spec -> fileDistribution.startDownload(spec.getHostName(), spec.getConfigServerPort(), Set.of(fileReference)));
+ }
+
void preprocess() {
try {
this.applicationPackage = context.getApplicationPackage().preprocess(properties.zone(), logger);
diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/TestComponentRegistry.java b/configserver/src/test/java/com/yahoo/vespa/config/server/TestComponentRegistry.java
index a304f74858b..d73dc7c8a35 100644
--- a/configserver/src/test/java/com/yahoo/vespa/config/server/TestComponentRegistry.java
+++ b/configserver/src/test/java/com/yahoo/vespa/config/server/TestComponentRegistry.java
@@ -50,7 +50,7 @@ public class TestComponentRegistry implements GlobalComponentRegistry {
private final TenantListener tenantListener;
private final PermanentApplicationPackage permanentApplicationPackage;
private final HostRegistries hostRegistries;
- private final FileDistributionFactory fileDistributionFactory;
+ private final FileDistributionFactory fileDistributionProvider;
private final ModelFactoryRegistry modelFactoryRegistry;
private final Optional<Provisioner> hostProvisioner;
private final Zone zone;
@@ -63,7 +63,7 @@ public class TestComponentRegistry implements GlobalComponentRegistry {
private TestComponentRegistry(Curator curator, ConfigCurator configCurator, Metrics metrics,
ModelFactoryRegistry modelFactoryRegistry,
PermanentApplicationPackage permanentApplicationPackage,
- FileDistributionFactory fileDistributionFactory,
+ FileDistributionFactory fileDistributionProvider,
HostRegistries hostRegistries,
ConfigserverConfig configserverConfig,
SessionPreparer sessionPreparer,
@@ -83,7 +83,7 @@ public class TestComponentRegistry implements GlobalComponentRegistry {
this.defRepo = defRepo;
this.permanentApplicationPackage = permanentApplicationPackage;
this.hostRegistries = hostRegistries;
- this.fileDistributionFactory = fileDistributionFactory;
+ this.fileDistributionProvider = fileDistributionProvider;
this.modelFactoryRegistry = modelFactoryRegistry;
this.hostProvisioner = hostProvisioner;
this.sessionPreparer = sessionPreparer;
@@ -158,17 +158,17 @@ public class TestComponentRegistry implements GlobalComponentRegistry {
public TestComponentRegistry build() {
final PermanentApplicationPackage permApp = this.permanentApplicationPackage
.orElse(new PermanentApplicationPackage(configserverConfig));
- FileDistributionFactory fileDistributionFactory = this.fileDistributionFactory
+ FileDistributionFactory fileDistributionProvider = this.fileDistributionFactory
.orElse(new MockFileDistributionFactory(configserverConfig));
HostProvisionerProvider hostProvisionerProvider = hostProvisioner.
map(HostProvisionerProvider::withProvisioner).orElseGet(HostProvisionerProvider::empty);
SecretStore secretStore = new MockSecretStore();
- SessionPreparer sessionPreparer = new SessionPreparer(modelFactoryRegistry, fileDistributionFactory,
+ SessionPreparer sessionPreparer = new SessionPreparer(modelFactoryRegistry, fileDistributionProvider,
hostProvisionerProvider, permApp,
configserverConfig, defRepo, curator,
zone, new InMemoryFlagSource(), secretStore);
return new TestComponentRegistry(curator, ConfigCurator.create(curator), metrics, modelFactoryRegistry,
- permApp, fileDistributionFactory, hostRegistries, configserverConfig,
+ permApp, fileDistributionProvider, hostRegistries, configserverConfig,
sessionPreparer, hostProvisioner, defRepo, reloadListener, tenantListener,
zone, clock, secretStore);
}
@@ -227,6 +227,6 @@ public class TestComponentRegistry implements GlobalComponentRegistry {
return secretStore;
}
- public FileDistributionFactory getFileDistributionFactory() { return fileDistributionFactory; }
+ public FileDistributionFactory getFileDistributionProvider() { return fileDistributionProvider; }
}
diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/session/MockFileDistributionFactory.java b/configserver/src/test/java/com/yahoo/vespa/config/server/session/MockFileDistributionFactory.java
index e1874c622c2..ae626499d30 100644
--- a/configserver/src/test/java/com/yahoo/vespa/config/server/session/MockFileDistributionFactory.java
+++ b/configserver/src/test/java/com/yahoo/vespa/config/server/session/MockFileDistributionFactory.java
@@ -2,7 +2,6 @@
package com.yahoo.vespa.config.server.session;
import com.yahoo.cloud.config.ConfigserverConfig;
-import com.yahoo.vespa.config.server.filedistribution.FileDistributionProvider;
import com.yahoo.vespa.config.server.filedistribution.MockFileDistributionProvider;
import java.io.File;
@@ -20,7 +19,7 @@ public class MockFileDistributionFactory extends FileDistributionFactory {
}
@Override
- public FileDistributionProvider createProvider(File applicationFile) {
+ public com.yahoo.vespa.config.server.filedistribution.FileDistributionProvider createProvider(File applicationFile) {
return mockFileDistributionProvider;
}
}
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 cdf57b68814..2657f4b46e3 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
@@ -104,7 +104,7 @@ public class SessionPreparerTest {
curator = new MockCurator();
configCurator = ConfigCurator.create(curator);
componentRegistry = new TestComponentRegistry.Builder().curator(curator).build();
- fileDistributionFactory = (MockFileDistributionFactory)componentRegistry.getFileDistributionFactory();
+ fileDistributionFactory = (MockFileDistributionFactory)componentRegistry.getFileDistributionProvider();
preparer = createPreparer();
}
@@ -122,7 +122,7 @@ public class SessionPreparerTest {
HostProvisionerProvider hostProvisionerProvider) {
return new SessionPreparer(
modelFactoryRegistry,
- componentRegistry.getFileDistributionFactory(),
+ componentRegistry.getFileDistributionProvider(),
hostProvisionerProvider,
new PermanentApplicationPackage(componentRegistry.getConfigserverConfig()),
componentRegistry.getConfigserverConfig(),
@@ -152,13 +152,13 @@ public class SessionPreparerTest {
@Test
public void require_that_filedistribution_is_ignored_on_dryrun() throws IOException {
prepare(testApp, new PrepareParams.Builder().dryRun(true).timeoutBudget(TimeoutBudgetTest.day()).build());
- assertThat(fileDistributionFactory.mockFileDistributionProvider.timesCalled, is(0));
+ assertThat(fileDistributionFactory.mockFileDistributionProvider.timesCalled, is(0 + 1)); // App is distributed to other config servers
}
@Test
public void require_that_application_is_prepared() throws Exception {
prepare(testApp);
- assertThat(fileDistributionFactory.mockFileDistributionProvider.timesCalled, is(1)); // Only builds the newest version
+ assertThat(fileDistributionFactory.mockFileDistributionProvider.timesCalled, is(1 + 1)); // Only builds the newest version, + 1 because app is distributed to other config servers
assertTrue(configCurator.exists(sessionsPath.append(ConfigCurator.USERAPP_ZK_SUBPATH).append("services.xml").getAbsolute()));
}