summaryrefslogtreecommitdiffstats
path: root/configserver
diff options
context:
space:
mode:
authorArne H Juul <arnej@yahooinc.com>2022-02-17 18:42:02 +0000
committerArne H Juul <arnej@yahooinc.com>2022-02-17 18:42:02 +0000
commit419ca82c28e7ea97ae7f7f1265eca158fae0844c (patch)
tree55ee9be894ad4f862ffeb12f733048451ff8c063 /configserver
parentc1e701cd70e2531302a6e72d0900772f4296ab2c (diff)
parent70e50ea1b7d974ffb2e1db805e8e273eeffd6d0e (diff)
Merge branch 'master' into arnej/rename-summaryfeatures-back-to-original
Diffstat (limited to 'configserver')
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/ApplicationRepository.java27
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/ConfigServerBootstrap.java24
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/TimeoutBudget.java2
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/application/ConfigConvergenceChecker.java90
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/application/ConfigNotConvergedException.java6
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/application/TenantApplications.java2
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/deploy/DeployHandlerLogger.java2
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/deploy/Deployment.java33
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/deploy/ModelContextImpl.java45
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/deploy/ZooKeeperClient.java10
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/filedistribution/FileServer.java1
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/http/HttpErrorResponse.java9
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/http/HttpHandler.java7
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/http/v1/RoutingStatusApiHandler.java19
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/http/v2/ApplicationHandler.java11
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/maintenance/ApplicationPackageMaintainer.java1
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/model/LbServicesProducer.java49
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/session/SessionPreparer.java2
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/session/SessionRepository.java2
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/tenant/TenantRepository.java4
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/serviceview/StateRequestHandler.java4
-rw-r--r--configserver/src/main/resources/configserver-app/services.xml2
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/ApplicationRepositoryTest.java184
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/ConfigServerBootstrapTest.java12
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/MockConfigConvergenceChecker.java38
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/SuperModelControllerTest.java27
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/application/ConfigConvergenceCheckerTest.java8
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/deploy/DeployHandlerLoggerTest.java1
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/deploy/DeployTester.java21
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/deploy/HostedDeployTest.java14
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/http/HttpGetConfigHandlerTest.java2
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/http/HttpHandlerTest.java2
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/http/HttpListConfigsHandlerTest.java2
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/http/status/StatusHandlerTest.java2
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/http/v1/RoutingStatusApiHandlerTest.java16
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/ApplicationContentHandlerTest.java2
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/ApplicationHandlerTest.java16
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/HostHandlerTest.java2
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/HttpGetConfigHandlerTest.java2
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/HttpListConfigsHandlerTest.java4
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/ListApplicationsHandlerTest.java2
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/SessionActiveHandlerTest.java2
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/SessionContentHandlerTest.java2
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/SessionCreateHandlerTest.java2
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/SessionPrepareHandlerTest.java10
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/model/LbServicesProducerTest.java51
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/rpc/security/MultiTenantRpcAuthorizerTest.java2
47 files changed, 451 insertions, 327 deletions
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 80194337daa..ccd9f0e7044 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
@@ -88,7 +88,6 @@ import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.UncheckedIOException;
-import java.net.URI;
import java.nio.file.Files;
import java.nio.file.attribute.BasicFileAttributes;
import java.time.Clock;
@@ -111,8 +110,8 @@ import java.util.stream.Collectors;
import static com.yahoo.config.model.api.container.ContainerServiceType.CONTAINER;
import static com.yahoo.config.model.api.container.ContainerServiceType.LOGSERVER_CONTAINER;
-import static com.yahoo.vespa.config.server.application.ConfigConvergenceChecker.ServiceResponse;
import static com.yahoo.vespa.config.server.application.ConfigConvergenceChecker.ServiceListResponse;
+import static com.yahoo.vespa.config.server.application.ConfigConvergenceChecker.ServiceResponse;
import static com.yahoo.vespa.config.server.filedistribution.FileDistributionUtil.fileReferenceExistsOnDisk;
import static com.yahoo.vespa.config.server.filedistribution.FileDistributionUtil.getFileReferencesOnDisk;
import static com.yahoo.vespa.config.server.tenant.TenantRepository.HOSTED_VESPA_TENANT;
@@ -147,6 +146,7 @@ public class ApplicationRepository implements com.yahoo.config.provision.Deploye
private final Metric metric;
private final SecretStoreValidator secretStoreValidator;
private final ClusterReindexingStatusClient clusterReindexingStatusClient;
+ private final FlagSource flagSource;
@Inject
public ApplicationRepository(TenantRepository tenantRepository,
@@ -203,8 +203,10 @@ public class ApplicationRepository implements com.yahoo.config.provision.Deploye
this.metric = Objects.requireNonNull(metric);
this.secretStoreValidator = Objects.requireNonNull(secretStoreValidator);
this.clusterReindexingStatusClient = clusterReindexingStatusClient;
+ this.flagSource = flagSource;
}
+ // Should be used by tests only (first constructor in this class makes sure we use injectable components where possible)
public static class Builder {
private TenantRepository tenantRepository;
private Optional<Provisioner> hostProvisioner;
@@ -217,6 +219,7 @@ public class ApplicationRepository implements com.yahoo.config.provision.Deploye
private Metric metric = new NullMetric();
private SecretStoreValidator secretStoreValidator = new SecretStoreValidator(new SecretStoreProvider().get());
private FlagSource flagSource = new InMemoryFlagSource();
+ private ConfigConvergenceChecker configConvergenceChecker = new ConfigConvergenceChecker();
public Builder withTenantRepository(TenantRepository tenantRepository) {
this.tenantRepository = tenantRepository;
@@ -280,11 +283,16 @@ public class ApplicationRepository implements com.yahoo.config.provision.Deploye
return this;
}
+ public Builder withConfigConvergenceChecker(ConfigConvergenceChecker configConvergenceChecker) {
+ this.configConvergenceChecker = configConvergenceChecker;
+ return this;
+ }
+
public ApplicationRepository build() {
return new ApplicationRepository(tenantRepository,
hostProvisioner,
InfraDeployerProvider.empty().getInfraDeployer(),
- new ConfigConvergenceChecker(),
+ configConvergenceChecker,
httpProxy,
configserverConfig,
orchestrator,
@@ -631,7 +639,7 @@ public class ApplicationRepository implements com.yahoo.config.provision.Deploye
private List<String> sortedUnusedFileReferences(File fileReferencesPath, Set<String> fileReferencesInUse, Duration keepFileReferences) {
Set<String> fileReferencesOnDisk = getFileReferencesOnDisk(fileReferencesPath);
log.log(Level.FINE, () -> "File references on disk (in " + fileReferencesPath + "): " + fileReferencesOnDisk);
- Instant instant = Instant.now().minus(keepFileReferences);
+ Instant instant = clock.instant().minus(keepFileReferences);
return fileReferencesOnDisk
.stream()
.filter(fileReference -> ! fileReferencesInUse.contains(fileReference))
@@ -747,10 +755,9 @@ public class ApplicationRepository implements com.yahoo.config.provision.Deploye
}
public ServiceListResponse servicesToCheckForConfigConvergence(ApplicationId applicationId,
- URI uri,
Duration timeoutPerService,
Optional<Version> vespaVersion) {
- return convergeChecker.getServiceConfigGenerations(getApplication(applicationId, vespaVersion), uri, timeoutPerService);
+ return convergeChecker.checkConvergenceForAllServices(getApplication(applicationId, vespaVersion), timeoutPerService);
}
public ConfigConvergenceChecker configConvergenceChecker() { return convergeChecker; }
@@ -1016,6 +1023,8 @@ public class ApplicationRepository implements com.yahoo.config.provision.Deploye
return applicationId.orElse(null);
}
+ public FlagSource flagSource() { return flagSource; }
+
private Session validateThatLocalSessionIsNotActive(Tenant tenant, long sessionId) {
Session session = getLocalSession(tenant, sessionId);
if (Session.Status.ACTIVATE.equals(session.getStatus())) {
@@ -1042,6 +1051,12 @@ public class ApplicationRepository implements com.yahoo.config.provision.Deploye
return getTenant(appId).getSessionRepository().getActiveApplicationSet(appId);
}
+ public Application getActiveApplication(ApplicationId applicationId) {
+ return getActiveApplicationSet(applicationId)
+ .map(a -> a.getForVersionOrLatest(Optional.empty(), clock.instant()))
+ .orElseThrow(() -> new RuntimeException("Found no active application for " + applicationId));
+ }
+
private File decompressApplication(InputStream in, String contentType, File tempDir) {
try (CompressedApplicationInputStream application =
CompressedApplicationInputStream.createFromCompressedStream(in, contentType)) {
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/ConfigServerBootstrap.java b/configserver/src/main/java/com/yahoo/vespa/config/server/ConfigServerBootstrap.java
index 57e49ef3e8d..8d51a91bc3a 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/ConfigServerBootstrap.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/ConfigServerBootstrap.java
@@ -17,6 +17,7 @@ import com.yahoo.vespa.config.server.version.VersionState;
import com.yahoo.vespa.flags.FlagSource;
import com.yahoo.yolean.Exceptions;
+import java.time.Clock;
import java.time.Duration;
import java.time.Instant;
import java.util.ArrayList;
@@ -73,6 +74,7 @@ public class ConfigServerBootstrap extends AbstractComponent implements Runnable
private final RedeployingApplicationsFails exitIfRedeployingApplicationsFails;
private final ExecutorService rpcServerExecutor;
private final ConfigServerMaintenance configServerMaintenance;
+ private final Clock clock;
@SuppressWarnings("unused") // Injected component
@Inject
@@ -83,21 +85,22 @@ public class ConfigServerBootstrap extends AbstractComponent implements Runnable
applicationRepository.configserverConfig().hostedVespa()
? VipStatusMode.VIP_STATUS_FILE
: VipStatusMode.VIP_STATUS_PROGRAMMATICALLY,
- flagSource, convergence);
+ flagSource, convergence, Clock.systemUTC());
}
// For testing only
ConfigServerBootstrap(ApplicationRepository applicationRepository, RpcServer server, VersionState versionState,
StateMonitor stateMonitor, VipStatus vipStatus, VipStatusMode vipStatusMode,
- FlagSource flagSource, ConfigConvergenceChecker convergence) {
+ FlagSource flagSource, ConfigConvergenceChecker convergence, Clock clock) {
this(applicationRepository, server, versionState, stateMonitor, vipStatus,
- FOR_TESTING_NO_BOOTSTRAP_OF_APPS, CONTINUE, vipStatusMode, flagSource, convergence);
+ FOR_TESTING_NO_BOOTSTRAP_OF_APPS, CONTINUE, vipStatusMode, flagSource, convergence, clock);
}
private ConfigServerBootstrap(ApplicationRepository applicationRepository, RpcServer server,
VersionState versionState, StateMonitor stateMonitor, VipStatus vipStatus,
Mode mode, RedeployingApplicationsFails exitIfRedeployingApplicationsFails,
- VipStatusMode vipStatusMode, FlagSource flagSource, ConfigConvergenceChecker convergence) {
+ VipStatusMode vipStatusMode, FlagSource flagSource, ConfigConvergenceChecker convergence,
+ Clock clock) {
this.applicationRepository = applicationRepository;
this.server = server;
this.versionState = versionState;
@@ -107,6 +110,7 @@ public class ConfigServerBootstrap extends AbstractComponent implements Runnable
this.maxDurationOfRedeployment = Duration.ofSeconds(configserverConfig.maxDurationOfBootstrap());
this.sleepTimeWhenRedeployingFails = Duration.ofSeconds(configserverConfig.sleepTimeWhenRedeployingFails());
this.exitIfRedeployingApplicationsFails = exitIfRedeployingApplicationsFails;
+ this.clock = clock;
rpcServerExecutor = Executors.newSingleThreadExecutor(new DaemonThreadFactory("config server RPC server"));
configServerMaintenance = new ConfigServerMaintenance(configserverConfig,
@@ -197,8 +201,8 @@ public class ConfigServerBootstrap extends AbstractComponent implements Runnable
private void startRpcServerWithFileDistribution() {
rpcServerExecutor.execute(server);
- Instant end = Instant.now().plus(Duration.ofSeconds(10));
- while (!server.isRunning() && Instant.now().isBefore(end)) {
+ Instant end = clock.instant().plus(Duration.ofSeconds(10));
+ while (!server.isRunning() && clock.instant().isBefore(end)) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
@@ -220,7 +224,7 @@ public class ConfigServerBootstrap extends AbstractComponent implements Runnable
}
private void redeployAllApplications() throws InterruptedException {
- Instant end = Instant.now().plus(maxDurationOfRedeployment);
+ Instant end = clock.instant().plus(maxDurationOfRedeployment);
List<ApplicationId> applicationsToRedeploy = applicationRepository.listApplications();
Collections.shuffle(applicationsToRedeploy);
long failCount = 0;
@@ -233,7 +237,7 @@ public class ConfigServerBootstrap extends AbstractComponent implements Runnable
log.log(Level.INFO, "Redeployment of " + applicationsToRedeploy + " not finished, will retry in " + sleepTime);
Thread.sleep(sleepTime.toMillis());
}
- } while ( ! applicationsToRedeploy.isEmpty() && Instant.now().isBefore(end));
+ } while ( ! applicationsToRedeploy.isEmpty() && clock.instant().isBefore(end));
if ( ! applicationsToRedeploy.isEmpty())
throw new RuntimeException("Redeploying applications not finished after " + maxDurationOfRedeployment +
@@ -296,11 +300,11 @@ public class ConfigServerBootstrap extends AbstractComponent implements Runnable
}
private void logProgress(LogState logState, int failedDeployments, int finishedDeployments) {
- if ( ! Duration.between(logState.lastLogged, Instant.now()).minus(Duration.ofSeconds(10)).isNegative()
+ if ( ! Duration.between(logState.lastLogged, clock.instant()).minus(Duration.ofSeconds(10)).isNegative()
&& (logState.failedDeployments != failedDeployments || logState.finishedDeployments != finishedDeployments)) {
log.log(Level.INFO, () -> finishedDeployments + " of " + logState.applicationCount + " apps redeployed " +
"(" + failedDeployments + " failed)");
- logState.update(Instant.now(), failedDeployments, finishedDeployments);
+ logState.update(clock.instant(), failedDeployments, finishedDeployments);
}
}
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/TimeoutBudget.java b/configserver/src/main/java/com/yahoo/vespa/config/server/TimeoutBudget.java
index d3295c023b0..a96f9db855c 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/TimeoutBudget.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/TimeoutBudget.java
@@ -1,7 +1,7 @@
// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.config.server;
-import com.google.common.util.concurrent.UncheckedTimeoutException;
+import com.yahoo.concurrent.UncheckedTimeoutException;
import java.time.Clock;
import java.time.Duration;
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/application/ConfigConvergenceChecker.java b/configserver/src/main/java/com/yahoo/vespa/config/server/application/ConfigConvergenceChecker.java
index ad14cf4aab6..a49af0a0e51 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/application/ConfigConvergenceChecker.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/application/ConfigConvergenceChecker.java
@@ -7,6 +7,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.inject.Inject;
import com.yahoo.component.AbstractComponent;
import com.yahoo.concurrent.DaemonThreadFactory;
+import com.yahoo.config.model.api.ApplicationClusterInfo;
import com.yahoo.config.model.api.HostInfo;
import com.yahoo.config.model.api.PortInfo;
import com.yahoo.config.model.api.ServiceInfo;
@@ -39,14 +40,17 @@ import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ExecutionException;
-import java.util.concurrent.Executor;
+import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
+import java.util.stream.Collectors;
import static com.yahoo.config.model.api.container.ContainerServiceType.CLUSTERCONTROLLER_CONTAINER;
import static com.yahoo.config.model.api.container.ContainerServiceType.CONTAINER;
import static com.yahoo.config.model.api.container.ContainerServiceType.LOGSERVER_CONTAINER;
+import static com.yahoo.config.model.api.container.ContainerServiceType.METRICS_PROXY_CONTAINER;
import static com.yahoo.config.model.api.container.ContainerServiceType.QRSERVER;
/**
@@ -65,13 +69,14 @@ public class ConfigConvergenceChecker extends AbstractComponent {
QRSERVER.serviceName,
LOGSERVER_CONTAINER.serviceName,
CLUSTERCONTROLLER_CONTAINER.serviceName,
+ METRICS_PROXY_CONTAINER.serviceName,
"searchnode",
"storagenode",
"distributor"
);
- private final Executor responseHandlerExecutor =
+ private final ExecutorService responseHandlerExecutor =
Executors.newSingleThreadExecutor(new DaemonThreadFactory("config-convergence-checker-response-handler-"));
private final ObjectMapper jsonMapper = new ObjectMapper();
@@ -80,20 +85,43 @@ public class ConfigConvergenceChecker extends AbstractComponent {
/** Fetches the active config generation for all services in the given application. */
public Map<ServiceInfo, Long> getServiceConfigGenerations(Application application, Duration timeoutPerService) {
+ return getServiceConfigGenerations(application, timeoutPerService, true);
+ }
+
+ /**
+ * Fetches the active config generation for all services in the given application. Will not check services
+ * which defer config changes until restart if checkAll is false.
+ */
+ private Map<ServiceInfo, Long> getServiceConfigGenerations(Application application, Duration timeoutPerService, boolean checkAll) {
List<ServiceInfo> servicesToCheck = new ArrayList<>();
application.getModel().getHosts()
.forEach(host -> host.getServices().stream()
.filter(service -> serviceTypesToCheck.contains(service.getServiceType()))
+ .filter(serviceInfo -> shouldCheckService(checkAll, application, serviceInfo))
.forEach(service -> getStatePort(service).ifPresent(port -> servicesToCheck.add(service))));
+ log.log(Level.FINE, "Services to check for config convergence: " + servicesToCheck);
return getServiceGenerations(servicesToCheck, timeoutPerService);
}
- /** Check all services in given application. Returns the minimum current generation of all services */
- public ServiceListResponse getServiceConfigGenerations(Application application, URI uri, Duration timeoutPerService) {
- Map<ServiceInfo, Long> currentGenerations = getServiceConfigGenerations(application, timeoutPerService);
+ /** Checks all services in given application. Returns the minimum current generation of all services */
+ public ServiceListResponse checkConvergenceForAllServices(Application application, Duration timeoutPerService) {
+ return checkConvergence(application, timeoutPerService, true);
+ }
+
+ /**
+ * Checks services except those which defer config changes until restart in the given application.
+ * Returns the minimum current generation of those services.
+ */
+ public ServiceListResponse checkConvergenceUnlessDeferringChangesUntilRestart(Application application) {
+ Duration timeoutPerService = Duration.ofSeconds(10);
+ return checkConvergence(application, timeoutPerService, false);
+ }
+
+ private ServiceListResponse checkConvergence(Application application, Duration timeoutPerService, boolean checkAll) {
+ Map<ServiceInfo, Long> currentGenerations = getServiceConfigGenerations(application, timeoutPerService, checkAll);
long currentGeneration = currentGenerations.values().stream().mapToLong(Long::longValue).min().orElse(-1);
- return new ServiceListResponse(currentGenerations, uri, application.getApplicationGeneration(), currentGeneration);
+ return new ServiceListResponse(currentGenerations, application.getApplicationGeneration(), currentGeneration);
}
/** Check service identified by host and port in given application */
@@ -113,6 +141,26 @@ public class ConfigConvergenceChecker extends AbstractComponent {
}
}
+ private boolean shouldCheckService(boolean checkServicesWithDeferChangesUntilRestart, Application application, ServiceInfo serviceInfo) {
+ if (checkServicesWithDeferChangesUntilRestart) return true;
+ if (isNotContainer(serviceInfo)) return true;
+ return serviceIsInClusterWhichShouldBeChecked(application, serviceInfo);
+ }
+
+ private boolean isNotContainer(ServiceInfo serviceInfo) {
+ return ! List.of(CONTAINER.serviceName, QRSERVER.serviceName, METRICS_PROXY_CONTAINER).contains(serviceInfo.getServiceType());
+ }
+
+ // Don't check service in a cluster which uses restartOnDeploy (new config will not be used until service is restarted)
+ private boolean serviceIsInClusterWhichShouldBeChecked(Application application, ServiceInfo serviceInfo) {
+ Set<ApplicationClusterInfo> excludeFromChecking = application.getModel().applicationClusterInfo()
+ .stream()
+ .filter(ApplicationClusterInfo::getDeferChangesUntilRestart)
+ .collect(Collectors.toSet());
+
+ return excludeFromChecking.stream().noneMatch(info -> info.name().equals(serviceInfo.getProperty("clustername").orElse("")));
+ }
+
/** Gets service generation for a list of services (in parallel). */
private Map<ServiceInfo, Long> getServiceGenerations(List<ServiceInfo> services, Duration timeout) {
try (CloseableHttpAsyncClient client = createHttpClient()) {
@@ -196,6 +244,16 @@ public class ConfigConvergenceChecker extends AbstractComponent {
.findFirst();
}
+ @Override
+ public void deconstruct() {
+ responseHandlerExecutor.shutdown();
+ try {
+ responseHandlerExecutor.awaitTermination(10, TimeUnit.SECONDS);
+ } catch (InterruptedException e) {
+ log.log(Level.WARNING, "Unable to shutdown executor", e);
+ }
+ }
+
private static long generationFromContainerState(JsonNode state) {
return state.get("config").get("generation").asLong(-1);
}
@@ -256,23 +314,23 @@ public class ConfigConvergenceChecker extends AbstractComponent {
public final boolean converged;
public final Optional<String> errorMessage;
- public ServiceResponse(Status status, Long wantedGeneration) {
- this(status, wantedGeneration, 0L);
+ public ServiceResponse(Status status, long wantedGeneration) {
+ this(status, wantedGeneration, 0);
}
- public ServiceResponse(Status status, Long wantedGeneration, Long currentGeneration) {
+ public ServiceResponse(Status status, long wantedGeneration, long currentGeneration) {
this(status, wantedGeneration, currentGeneration, false);
}
- public ServiceResponse(Status status, Long wantedGeneration, Long currentGeneration, boolean converged) {
+ public ServiceResponse(Status status, long wantedGeneration, long currentGeneration, boolean converged) {
this(status, wantedGeneration, currentGeneration, converged, Optional.empty());
}
- public ServiceResponse(Status status, Long wantedGeneration, String errorMessage) {
- this(status, wantedGeneration, 0L, false, Optional.ofNullable(errorMessage));
+ public ServiceResponse(Status status, long wantedGeneration, String errorMessage) {
+ this(status, wantedGeneration, 0, false, Optional.ofNullable(errorMessage));
}
- private ServiceResponse(Status status, Long wantedGeneration, Long currentGeneration, boolean converged, Optional<String> errorMessage) {
+ private ServiceResponse(Status status, long wantedGeneration, long currentGeneration, boolean converged, Optional<String> errorMessage) {
this.status = status;
this.wantedGeneration = wantedGeneration;
this.currentGeneration = currentGeneration;
@@ -285,15 +343,15 @@ public class ConfigConvergenceChecker extends AbstractComponent {
public static class ServiceListResponse {
public final List<Service> services = new ArrayList<>();
- public final URI uri;
public final long wantedGeneration;
public final long currentGeneration;
+ public final boolean converged;
- public ServiceListResponse(Map<ServiceInfo, Long> services, URI uri, long wantedGeneration, long currentGeneration) {
+ public ServiceListResponse(Map<ServiceInfo, Long> services, long wantedGeneration, long currentGeneration) {
services.forEach((key, value) -> this.services.add(new Service(key, value)));
- this.uri = uri;
this.wantedGeneration = wantedGeneration;
this.currentGeneration = currentGeneration;
+ this.converged = currentGeneration >= wantedGeneration;
}
public List<Service> services() { return services; }
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/application/ConfigNotConvergedException.java b/configserver/src/main/java/com/yahoo/vespa/config/server/application/ConfigNotConvergedException.java
index f0711e5c238..88cddb93d9d 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/application/ConfigNotConvergedException.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/application/ConfigNotConvergedException.java
@@ -5,7 +5,13 @@ package com.yahoo.vespa.config.server.application;
* @author Ulf Lilleengen
*/
public class ConfigNotConvergedException extends RuntimeException {
+
+ public ConfigNotConvergedException(Throwable t) {
+ super(t);
+ }
+
public ConfigNotConvergedException(String message) {
super(message);
}
+
}
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/application/TenantApplications.java b/configserver/src/main/java/com/yahoo/vespa/config/server/application/TenantApplications.java
index 98ddf702a7f..937ec2bb0e7 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/application/TenantApplications.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/application/TenantApplications.java
@@ -472,7 +472,7 @@ public class TenantApplications implements RequestHandler, HostValidator<Applica
// If some are missing, quorum is enough, but wait for all up to 5 seconds before returning
if (respondents.size() >= barrierMemberCount()) {
if (gotQuorumTime.isBefore(startTime))
- gotQuorumTime = Instant.now();
+ gotQuorumTime = clock.instant();
// Give up if more than some time has passed since we got quorum, otherwise continue
if (Duration.between(Instant.now(), gotQuorumTime.plus(waitForAll)).isNegative()) {
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/deploy/DeployHandlerLogger.java b/configserver/src/main/java/com/yahoo/vespa/config/server/deploy/DeployHandlerLogger.java
index 71e5489fb2e..d7977477f30 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/deploy/DeployHandlerLogger.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/deploy/DeployHandlerLogger.java
@@ -36,6 +36,7 @@ public class DeployHandlerLogger implements DeployLogger {
}
@Override
+ @SuppressWarnings("deprecation")
public void log(Level level, String message) {
if (level.intValue() <= LogLevel.DEBUG.intValue() && !verbose)
return;
@@ -46,6 +47,7 @@ public class DeployHandlerLogger implements DeployLogger {
}
@Override
+ @SuppressWarnings("deprecation")
public void logApplicationPackage(Level level, String message) {
if (level.intValue() <= LogLevel.DEBUG.intValue() && !verbose)
return;
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/deploy/Deployment.java b/configserver/src/main/java/com/yahoo/vespa/config/server/deploy/Deployment.java
index 4b7e39f48a4..e6159cbfa33 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/deploy/Deployment.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/deploy/Deployment.java
@@ -3,6 +3,7 @@ package com.yahoo.vespa.config.server.deploy;
import com.google.common.base.Supplier;
import com.google.common.base.Suppliers;
+import com.yahoo.concurrent.UncheckedTimeoutException;
import com.yahoo.config.FileReference;
import com.yahoo.config.application.api.DeployLogger;
import com.yahoo.config.model.api.ServiceInfo;
@@ -19,6 +20,9 @@ import com.yahoo.vespa.config.server.ApplicationRepository;
import com.yahoo.vespa.config.server.ApplicationRepository.ActionTimer;
import com.yahoo.vespa.config.server.ApplicationRepository.Activation;
import com.yahoo.vespa.config.server.TimeoutBudget;
+import com.yahoo.vespa.config.server.application.Application;
+import com.yahoo.vespa.config.server.application.ConfigConvergenceChecker;
+import com.yahoo.vespa.config.server.application.ConfigNotConvergedException;
import com.yahoo.vespa.config.server.configchange.ConfigChangeActions;
import com.yahoo.vespa.config.server.configchange.ReindexActions;
import com.yahoo.vespa.config.server.configchange.RestartActions;
@@ -35,6 +39,8 @@ import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Collectors;
+import static com.yahoo.vespa.config.server.application.ConfigConvergenceChecker.ServiceListResponse;
+
/**
* The process of deploying an application.
* Deployments are created by an {@link ApplicationRepository}.
@@ -149,6 +155,9 @@ public class Deployment implements com.yahoo.config.provision.Deployment {
RestartActions restartActions = configChangeActions.getRestartActions().useForInternalRestart(internalRedeploy);
if ( ! restartActions.isEmpty()) {
+
+ waitForConfigToConverge(applicationId);
+
Set<String> hostnames = restartActions.getEntries().stream()
.flatMap(entry -> entry.getServices().stream())
.map(ServiceInfo::getHostName)
@@ -165,6 +174,30 @@ public class Deployment implements com.yahoo.config.provision.Deployment {
}
}
+ private void waitForConfigToConverge(ApplicationId applicationId) {
+ deployLogger.log(Level.INFO, "Wait for all services to use new config generation before restarting");
+ while (true) {
+ try {
+ params.get().getTimeoutBudget().assertNotTimedOut(
+ () -> "Timeout exceeded while waiting for config convergence for " + applicationId);
+ } catch (UncheckedTimeoutException e) {
+ throw new ConfigNotConvergedException(e);
+ }
+
+ ConfigConvergenceChecker convergenceChecker = applicationRepository.configConvergenceChecker();
+ Application app = applicationRepository.getActiveApplication(applicationId);
+ ServiceListResponse response = convergenceChecker.checkConvergenceUnlessDeferringChangesUntilRestart(app);
+ if (response.converged) {
+ deployLogger.log(Level.INFO, "Services converged on new config generation " + response.currentGeneration);
+ return;
+ } else {
+ deployLogger.log(Level.INFO, "Services did not converge on new config generation " +
+ response.wantedGeneration + ", current generation: " + response.currentGeneration + ", will retry");
+ try { Thread.sleep(10_000); } catch (InterruptedException e) { /* ignore */ }
+ }
+ }
+ }
+
private void storeReindexing(ApplicationId applicationId, long requiredSession) {
applicationRepository.modifyReindexing(applicationId, reindexing -> {
if (configChangeActions != null)
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 8c1fcf9d9f2..38245f26a18 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
@@ -177,24 +177,20 @@ public class ModelContextImpl implements ModelContext {
private final boolean skipMbusReplyThread;
private final boolean useAsyncMessageHandlingOnSchedule;
private final double feedConcurrency;
- private final boolean enableFeedBlockInDistributor;
private final List<String> allowedAthenzProxyIdentities;
private final int maxActivationInhibitedOutOfSyncGroups;
private final ToIntFunction<ClusterSpec.Type> jvmOmitStackTraceInFastThrow;
private final int maxConcurrentMergesPerContentNode;
private final int maxMergeQueueSize;
- private final boolean ignoreMergeQueueLimit;
private final double resourceLimitDisk;
private final double resourceLimitMemory;
private final double minNodeRatioPerGroup;
private final int metricsproxyNumThreads;
+ private final int availableProcessors;
private final boolean containerDumpHeapOnShutdownTimeout;
private final double containerShutdownTimeout;
- private final int distributorMergeBusyWait;
- private final boolean distributorEnhancedMaintenanceScheduling;
private final int maxUnCommittedMemory;
private final boolean forwardIssuesAsErrors;
- private final boolean asyncApplyBucketDiff;
private final boolean ignoreThreadStackSizes;
private final boolean unorderedMergeChaining;
private final boolean useV8GeoPositions;
@@ -204,6 +200,11 @@ public class ModelContextImpl implements ModelContext {
private final List<String> ignoredHttpUserAgents;
private final boolean enableServerOcspStapling;
private final String persistenceAsyncThrottling;
+ private final String mergeThrottlingPolicy;
+ private final double persistenceThrottlingWsDecrementFactor;
+ private final double persistenceThrottlingWsBackoff;
+ private final boolean inhibitDefaultMergesWhenGlobalMergesPending;
+ private final boolean useQrserverServiceName;
private final boolean avoidRenamingSummaryFeatures;
public FeatureFlags(FlagSource source, ApplicationId appId) {
@@ -220,24 +221,20 @@ public class ModelContextImpl implements ModelContext {
this.skipMbusReplyThread = flagValue(source, appId, Flags.SKIP_MBUS_REPLY_THREAD);
this.useAsyncMessageHandlingOnSchedule = flagValue(source, appId, Flags.USE_ASYNC_MESSAGE_HANDLING_ON_SCHEDULE);
this.feedConcurrency = flagValue(source, appId, Flags.FEED_CONCURRENCY);
- this.enableFeedBlockInDistributor = flagValue(source, appId, Flags.ENABLE_FEED_BLOCK_IN_DISTRIBUTOR);
this.allowedAthenzProxyIdentities = flagValue(source, appId, Flags.ALLOWED_ATHENZ_PROXY_IDENTITIES);
this.maxActivationInhibitedOutOfSyncGroups = flagValue(source, appId, Flags.MAX_ACTIVATION_INHIBITED_OUT_OF_SYNC_GROUPS);
this.jvmOmitStackTraceInFastThrow = type -> flagValueAsInt(source, appId, type, PermanentFlags.JVM_OMIT_STACK_TRACE_IN_FAST_THROW);
this.maxConcurrentMergesPerContentNode = flagValue(source, appId, Flags.MAX_CONCURRENT_MERGES_PER_NODE);
this.maxMergeQueueSize = flagValue(source, appId, Flags.MAX_MERGE_QUEUE_SIZE);
- this.ignoreMergeQueueLimit = flagValue(source, appId, Flags.IGNORE_MERGE_QUEUE_LIMIT);
this.resourceLimitDisk = flagValue(source, appId, PermanentFlags.RESOURCE_LIMIT_DISK);
this.resourceLimitMemory = flagValue(source, appId, PermanentFlags.RESOURCE_LIMIT_MEMORY);
this.minNodeRatioPerGroup = flagValue(source, appId, Flags.MIN_NODE_RATIO_PER_GROUP);
this.metricsproxyNumThreads = flagValue(source, appId, Flags.METRICSPROXY_NUM_THREADS);
+ this.availableProcessors = flagValue(source, appId, Flags.AVAILABLE_PROCESSORS);
this.containerDumpHeapOnShutdownTimeout = flagValue(source, appId, Flags.CONTAINER_DUMP_HEAP_ON_SHUTDOWN_TIMEOUT);
this.containerShutdownTimeout = flagValue(source, appId,Flags.CONTAINER_SHUTDOWN_TIMEOUT);
- this.distributorMergeBusyWait = flagValue(source, appId, Flags.DISTRIBUTOR_MERGE_BUSY_WAIT);
- this.distributorEnhancedMaintenanceScheduling = flagValue(source, appId, Flags.DISTRIBUTOR_ENHANCED_MAINTENANCE_SCHEDULING);
- this.maxUnCommittedMemory = flagValue(source, appId, Flags.MAX_UNCOMMITTED_MEMORY);;
+ this.maxUnCommittedMemory = flagValue(source, appId, Flags.MAX_UNCOMMITTED_MEMORY);
this.forwardIssuesAsErrors = flagValue(source, appId, PermanentFlags.FORWARD_ISSUES_AS_ERRORS);
- this.asyncApplyBucketDiff = flagValue(source, appId, Flags.ASYNC_APPLY_BUCKET_DIFF);
this.ignoreThreadStackSizes = flagValue(source, appId, Flags.IGNORE_THREAD_STACK_SIZES);
this.unorderedMergeChaining = flagValue(source, appId, Flags.UNORDERED_MERGE_CHAINING);
this.useV8GeoPositions = flagValue(source, appId, Flags.USE_V8_GEO_POSITIONS);
@@ -247,6 +244,11 @@ public class ModelContextImpl implements ModelContext {
this.ignoredHttpUserAgents = flagValue(source, appId, PermanentFlags.IGNORED_HTTP_USER_AGENTS);
this.enableServerOcspStapling = flagValue(source, appId, Flags.ENABLE_SERVER_OCSP_STAPLING);
this.persistenceAsyncThrottling = flagValue(source, appId, Flags.PERSISTENCE_ASYNC_THROTTLING);
+ this.mergeThrottlingPolicy = flagValue(source, appId, Flags.MERGE_THROTTLING_POLICY);
+ this.persistenceThrottlingWsDecrementFactor = flagValue(source, appId, Flags.PERSISTENCE_THROTTLING_WS_DECREMENT_FACTOR);
+ this.persistenceThrottlingWsBackoff = flagValue(source, appId, Flags.PERSISTENCE_THROTTLING_WS_BACKOFF);
+ this.inhibitDefaultMergesWhenGlobalMergesPending = flagValue(source, appId, Flags.INHIBIT_DEFAULT_MERGES_WHEN_GLOBAL_MERGES_PENDING);
+ this.useQrserverServiceName = flagValue(source, appId, Flags.USE_QRSERVER_SERVICE_NAME);
this.avoidRenamingSummaryFeatures = flagValue(source, appId, Flags.AVOID_RENAMING_SUMMARY_FEATURES);
}
@@ -263,7 +265,6 @@ public class ModelContextImpl implements ModelContext {
@Override public boolean skipMbusReplyThread() { return skipMbusReplyThread; }
@Override public boolean useAsyncMessageHandlingOnSchedule() { return useAsyncMessageHandlingOnSchedule; }
@Override public double feedConcurrency() { return feedConcurrency; }
- @Override public boolean enableFeedBlockInDistributor() { return enableFeedBlockInDistributor; }
@Override public List<String> allowedAthenzProxyIdentities() { return allowedAthenzProxyIdentities; }
@Override public int maxActivationInhibitedOutOfSyncGroups() { return maxActivationInhibitedOutOfSyncGroups; }
@Override public String jvmOmitStackTraceInFastThrowOption(ClusterSpec.Type type) {
@@ -271,18 +272,15 @@ public class ModelContextImpl implements ModelContext {
}
@Override public int maxConcurrentMergesPerNode() { return maxConcurrentMergesPerContentNode; }
@Override public int maxMergeQueueSize() { return maxMergeQueueSize; }
- @Override public boolean ignoreMergeQueueLimit() { return ignoreMergeQueueLimit; }
@Override public double resourceLimitDisk() { return resourceLimitDisk; }
@Override public double resourceLimitMemory() { return resourceLimitMemory; }
@Override public double minNodeRatioPerGroup() { return minNodeRatioPerGroup; }
- @Override public int metricsproxyNumThreads() { return metricsproxyNumThreads; }
+ @Override public int defaultPoolNumThreads() { return metricsproxyNumThreads; }
+ @Override public int availableProcessors() { return availableProcessors; }
@Override public double containerShutdownTimeout() { return containerShutdownTimeout; }
@Override public boolean containerDumpHeapOnShutdownTimeout() { return containerDumpHeapOnShutdownTimeout; }
- @Override public int distributorMergeBusyWait() { return distributorMergeBusyWait; }
- @Override public boolean distributorEnhancedMaintenanceScheduling() { return distributorEnhancedMaintenanceScheduling; }
@Override public int maxUnCommittedMemory() { return maxUnCommittedMemory; }
@Override public boolean forwardIssuesAsErrors() { return forwardIssuesAsErrors; }
- @Override public boolean asyncApplyBucketDiff() { return asyncApplyBucketDiff; }
@Override public boolean ignoreThreadStackSizes() { return ignoreThreadStackSizes; }
@Override public boolean unorderedMergeChaining() { return unorderedMergeChaining; }
@Override public boolean useV8GeoPositions() { return useV8GeoPositions; }
@@ -292,6 +290,11 @@ public class ModelContextImpl implements ModelContext {
@Override public List<String> ignoredHttpUserAgents() { return ignoredHttpUserAgents; }
@Override public boolean enableServerOcspStapling() { return enableServerOcspStapling; }
@Override public String persistenceAsyncThrottling() { return persistenceAsyncThrottling; }
+ @Override public String mergeThrottlingPolicy() { return mergeThrottlingPolicy; }
+ @Override public double persistenceThrottlingWsDecrementFactor() { return persistenceThrottlingWsDecrementFactor; }
+ @Override public double persistenceThrottlingWsBackoff() { return persistenceThrottlingWsBackoff; }
+ @Override public boolean inhibitDefaultMergesWhenGlobalMergesPending() { return inhibitDefaultMergesWhenGlobalMergesPending; }
+ @Override public boolean useQrserverServiceName() { return useQrserverServiceName; }
@Override public boolean avoidRenamingSummaryFeatures() { return avoidRenamingSummaryFeatures; }
private static <V> V flagValue(FlagSource source, ApplicationId appId, UnboundFlag<? extends V, ?, ?> flag) {
@@ -354,6 +357,7 @@ public class ModelContextImpl implements ModelContext {
private final List<X509Certificate> operatorCertificates;
private final List<String> tlsCiphersOverride;
private final List<String> zoneDnsSuffixes;
+ private final List<String> environmentVariables;
public Properties(ApplicationId applicationId,
ConfigserverConfig configserverConfig,
@@ -386,13 +390,15 @@ public class ModelContextImpl implements ModelContext {
this.tenantSecretStores = tenantSecretStores;
this.secretStore = secretStore;
this.jvmGCOptionsFlag = PermanentFlags.JVM_GC_OPTIONS.bindTo(flagSource)
- .with(FetchVector.Dimension.APPLICATION_ID, applicationId.serializedForm());
+ .with(FetchVector.Dimension.APPLICATION_ID, applicationId.serializedForm());
this.allowDisableMtls = PermanentFlags.ALLOW_DISABLE_MTLS.bindTo(flagSource)
.with(FetchVector.Dimension.APPLICATION_ID, applicationId.serializedForm()).value();
this.operatorCertificates = operatorCertificates;
this.tlsCiphersOverride = PermanentFlags.TLS_CIPHERS_OVERRIDE.bindTo(flagSource)
.with(FetchVector.Dimension.APPLICATION_ID, applicationId.serializedForm()).value();
this.zoneDnsSuffixes = configserverConfig.zoneDnsSuffixes();
+ this.environmentVariables = PermanentFlags.ENVIRONMENT_VARIABLES.bindTo(flagSource)
+ .with(FetchVector.Dimension.APPLICATION_ID, applicationId.serializedForm()).value();
}
@Override public ModelContext.FeatureFlags featureFlags() { return featureFlags; }
@@ -474,6 +480,9 @@ public class ModelContextImpl implements ModelContext {
.value();
}
+ @Override
+ public List<String> environmentVariables() { return environmentVariables; }
+
}
}
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/deploy/ZooKeeperClient.java b/configserver/src/main/java/com/yahoo/vespa/config/server/deploy/ZooKeeperClient.java
index ca822b7a99d..0acf32d79a7 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/deploy/ZooKeeperClient.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/deploy/ZooKeeperClient.java
@@ -90,15 +90,15 @@ public class ZooKeeperClient {
}
private void writeSchemas(ApplicationPackage app) throws IOException {
- Collection<NamedReader> sds = app.getSchemas();
- if (sds.isEmpty()) return;
+ Collection<NamedReader> schemas = app.getSchemas();
+ if (schemas.isEmpty()) return;
Path zkPath = getZooKeeperAppPath(USERAPP_ZK_SUBPATH).append(SCHEMAS_DIR);
curator.create(zkPath);
// Ensures that ranking expressions and other files are also written
- writeDir(app.getFile(ApplicationPackage.SEARCH_DEFINITIONS_DIR), zkPath, false);
- writeDir(app.getFile(ApplicationPackage.SCHEMAS_DIR), zkPath, false);
- for (NamedReader sd : sds) {
+ writeDir(app.getFile(ApplicationPackage.SEARCH_DEFINITIONS_DIR), zkPath, true);
+ writeDir(app.getFile(ApplicationPackage.SCHEMAS_DIR), zkPath, true);
+ for (NamedReader sd : schemas) {
curator.set(zkPath.append(sd.getName()), Utf8.toBytes(com.yahoo.io.IOUtils.readAll(sd.getReader())));
sd.getReader().close();
}
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/filedistribution/FileServer.java b/configserver/src/main/java/com/yahoo/vespa/config/server/filedistribution/FileServer.java
index 8e5eee2104c..a3f9dbfad11 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/filedistribution/FileServer.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/filedistribution/FileServer.java
@@ -223,6 +223,7 @@ public class FileServer {
}
private static ConnectionPool createConnectionPool(List<String> configServers, Supervisor supervisor) {
+ @SuppressWarnings("removal") // TODO Vespa 8: remove
ConfigSourceSet configSourceSet = new ConfigSourceSet(configServers);
if (configServers.size() == 0) return FileDownloader.emptyConnectionPool();
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/http/HttpErrorResponse.java b/configserver/src/main/java/com/yahoo/vespa/config/server/http/HttpErrorResponse.java
index 96e1767b462..c414d8dfa9a 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/http/HttpErrorResponse.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/http/HttpErrorResponse.java
@@ -2,13 +2,13 @@
package com.yahoo.vespa.config.server.http;
import com.yahoo.container.jdisc.HttpResponse;
-import java.util.logging.Level;
import com.yahoo.slime.Cursor;
import com.yahoo.slime.JsonFormat;
import com.yahoo.slime.Slime;
import java.io.IOException;
import java.io.OutputStream;
+import java.util.logging.Level;
import java.util.logging.Logger;
import static com.yahoo.jdisc.Response.Status.BAD_REQUEST;
@@ -50,7 +50,8 @@ public class HttpErrorResponse extends HttpResponse {
UNKNOWN_VESPA_VERSION,
PARENT_HOST_NOT_READY,
CERTIFICATE_NOT_READY,
- LOAD_BALANCER_NOT_READY
+ LOAD_BALANCER_NOT_READY,
+ CONFIG_NOT_CONVERGED
}
public static HttpErrorResponse notFoundError(String msg) {
@@ -101,6 +102,10 @@ public class HttpErrorResponse extends HttpResponse {
return new HttpErrorResponse(CONFLICT, ErrorCode.CERTIFICATE_NOT_READY.name(), msg);
}
+ public static HttpErrorResponse configNotConverged(String msg) {
+ return new HttpErrorResponse(CONFLICT, ErrorCode.CONFIG_NOT_CONVERGED.name(), msg);
+ }
+
public static HttpErrorResponse loadBalancerNotReady(String msg) {
return new HttpErrorResponse(CONFLICT, ErrorCode.LOAD_BALANCER_NOT_READY.name(), msg);
}
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/http/HttpHandler.java b/configserver/src/main/java/com/yahoo/vespa/config/server/http/HttpHandler.java
index 2dad2c060cc..190005771c7 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/http/HttpHandler.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/http/HttpHandler.java
@@ -9,7 +9,8 @@ import com.yahoo.config.provision.exception.ActivationConflictException;
import com.yahoo.config.provision.exception.LoadBalancerServiceException;
import com.yahoo.container.jdisc.HttpRequest;
import com.yahoo.container.jdisc.HttpResponse;
-import com.yahoo.container.jdisc.LoggingRequestHandler;
+import com.yahoo.vespa.config.server.application.ConfigNotConvergedException;
+import com.yahoo.container.jdisc.ThreadedHttpRequestHandler;
import com.yahoo.yolean.Exceptions;
import java.io.PrintWriter;
@@ -24,7 +25,7 @@ import java.util.logging.Level;
*
* @author hmusum
*/
-public class HttpHandler extends LoggingRequestHandler {
+public class HttpHandler extends ThreadedHttpRequestHandler {
public HttpHandler(HttpHandler.Context ctx) {
super(ctx);
@@ -68,6 +69,8 @@ public class HttpHandler extends LoggingRequestHandler {
return HttpErrorResponse.parentHostNotReady(getMessage(e, request));
} catch (CertificateNotReadyException e) {
return HttpErrorResponse.certificateNotReady(getMessage(e, request));
+ } catch (ConfigNotConvergedException e) {
+ return HttpErrorResponse.configNotConverged(getMessage(e, request));
} catch (LoadBalancerServiceException e) {
return HttpErrorResponse.loadBalancerNotReady(getMessage(e, request));
} catch (Exception e) {
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/http/v1/RoutingStatusApiHandler.java b/configserver/src/main/java/com/yahoo/vespa/config/server/http/v1/RoutingStatusApiHandler.java
index d9cbc7bc533..569ed1525b2 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/http/v1/RoutingStatusApiHandler.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/http/v1/RoutingStatusApiHandler.java
@@ -63,6 +63,7 @@ public class RoutingStatusApiHandler extends RestApiRequestHandler<RoutingStatus
private static RestApi createRestApiDefinition(RoutingStatusApiHandler self) {
return RestApi.builder()
+ // TODO(mpolden): Remove this route when clients have migrated to v2
.addRoute(RestApi.route("/routing/v1/status")
.get(self::listInactiveDeployments))
.addRoute(RestApi.route("/routing/v1/status/zone")
@@ -72,9 +73,27 @@ public class RoutingStatusApiHandler extends RestApiRequestHandler<RoutingStatus
.addRoute(RestApi.route("/routing/v1/status/{upstreamName}")
.get(self::getDeploymentStatus)
.put(self::changeDeploymentStatus))
+ .addRoute(RestApi.route("/routing/v2/status")
+ .get(self::getDeploymentStatusV2))
.build();
}
+ /* Get inactive deployments and zone status */
+ private SlimeJsonResponse getDeploymentStatusV2(RestApi.RequestContext context) {
+ Slime slime = new Slime();
+ Cursor root = slime.setObject();
+ Cursor inactiveDeploymentsArray = root.setArray("inactiveDeployments");
+ curator.getChildren(DEPLOYMENT_STATUS_ROOT).stream()
+ .filter(upstreamName -> deploymentStatus(upstreamName).status() == RoutingStatus.out)
+ .sorted()
+ .forEach(upstreamName -> {
+ Cursor deploymentObject = inactiveDeploymentsArray.addObject();
+ deploymentObject.setString("upstreamName", upstreamName);
+ });
+ root.setBool("zoneActive", zoneStatus() == RoutingStatus.in);
+ return new SlimeJsonResponse(slime);
+ }
+
/** Get upstream of all deployments with status OUT */
private SlimeJsonResponse listInactiveDeployments(RestApi.RequestContext context) {
List<String> inactiveDeployments = curator.getChildren(DEPLOYMENT_STATUS_ROOT).stream()
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/http/v2/ApplicationHandler.java b/configserver/src/main/java/com/yahoo/vespa/config/server/http/v2/ApplicationHandler.java
index 0131517818d..df4df234ed0 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/http/v2/ApplicationHandler.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/http/v2/ApplicationHandler.java
@@ -117,10 +117,9 @@ public class ApplicationHandler extends HttpHandler {
private HttpResponse listServiceConverge(ApplicationId applicationId, HttpRequest request) {
ServiceListResponse response =
applicationRepository.servicesToCheckForConfigConvergence(applicationId,
- request.getUri(),
getTimeoutFromRequest(request),
getVespaVersionFromRequest(request));
- return new HttpServiceListResponse(response);
+ return new HttpServiceListResponse(response, request.getUri());
}
private HttpResponse checkServiceConverge(ApplicationId applicationId, String hostAndPort, HttpRequest request) {
@@ -370,7 +369,7 @@ public class ApplicationHandler extends HttpHandler {
static class HttpServiceListResponse extends JSONResponse {
// Pre-condition: servicesToCheck has a state port
- public HttpServiceListResponse(ConfigConvergenceChecker.ServiceListResponse response) {
+ public HttpServiceListResponse(ConfigConvergenceChecker.ServiceListResponse response, URI uri) {
super(200);
Cursor serviceArray = object.setArray("services");
response.services().forEach((service) -> {
@@ -381,13 +380,13 @@ public class ApplicationHandler extends HttpHandler {
serviceObject.setString("host", hostName);
serviceObject.setLong("port", statePort);
serviceObject.setString("type", serviceInfo.getServiceType());
- serviceObject.setString("url", response.uri.toString() + "/" + hostName + ":" + statePort);
+ serviceObject.setString("url", uri.toString() + "/" + hostName + ":" + statePort);
serviceObject.setLong("currentGeneration", service.currentGeneration);
});
- object.setString("url", response.uri.toString());
+ object.setString("url", uri.toString());
object.setLong("currentGeneration", response.currentGeneration);
object.setLong("wantedGeneration", response.wantedGeneration);
- object.setBool("converged", response.currentGeneration >= response.wantedGeneration);
+ object.setBool("converged", response.converged);
}
}
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/maintenance/ApplicationPackageMaintainer.java b/configserver/src/main/java/com/yahoo/vespa/config/server/maintenance/ApplicationPackageMaintainer.java
index a0e8d83fba1..9d8a3d87811 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/maintenance/ApplicationPackageMaintainer.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/maintenance/ApplicationPackageMaintainer.java
@@ -96,6 +96,7 @@ public class ApplicationPackageMaintainer extends ConfigServerMaintainer {
File downloadDirectory,
Supervisor supervisor) {
List<String> otherConfigServersInCluster = getOtherConfigServersInCluster(configserverConfig);
+ @SuppressWarnings("removal") // TODO Vespa 8: remove
ConfigSourceSet configSourceSet = new ConfigSourceSet(otherConfigServersInCluster);
ConnectionPool connectionPool = (otherConfigServersInCluster.isEmpty())
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/model/LbServicesProducer.java b/configserver/src/main/java/com/yahoo/vespa/config/server/model/LbServicesProducer.java
index dccabca2858..7677417f1a9 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/model/LbServicesProducer.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/model/LbServicesProducer.java
@@ -1,7 +1,6 @@
// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.config.server.model;
-import com.google.common.base.Joiner;
import com.yahoo.cloud.config.LbServicesConfig;
import com.yahoo.config.model.api.ApplicationClusterEndpoint;
import com.yahoo.config.model.api.ApplicationClusterInfo;
@@ -11,19 +10,14 @@ import com.yahoo.config.model.api.ServiceInfo;
import com.yahoo.config.provision.ApplicationId;
import com.yahoo.config.provision.TenantName;
import com.yahoo.config.provision.Zone;
-import com.yahoo.vespa.flags.BooleanFlag;
-import com.yahoo.vespa.flags.FetchVector;
import com.yahoo.vespa.flags.FlagSource;
-import com.yahoo.vespa.flags.Flags;
-import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
-import java.util.stream.Stream;
import static com.yahoo.config.model.api.container.ContainerServiceType.CONTAINER;
import static com.yahoo.config.model.api.container.ContainerServiceType.QRSERVER;
@@ -37,12 +31,10 @@ public class LbServicesProducer implements LbServicesConfig.Producer {
private final Map<TenantName, Set<ApplicationInfo>> models;
private final Zone zone;
- private final BooleanFlag generateNonMtlsEndpoint;
public LbServicesProducer(Map<TenantName, Set<ApplicationInfo>> models, Zone zone, FlagSource flagSource) {
this.models = models;
this.zone = zone;
- generateNonMtlsEndpoint = Flags.GENERATE_NON_MTLS_ENDPOINT.bindTo(flagSource);
}
@Override
@@ -76,13 +68,6 @@ public class LbServicesProducer implements LbServicesConfig.Producer {
// TODO: read active rotation from ApplicationClusterInfo
ab.activeRotation(getActiveRotation(app));
- ab.usePowerOfTwoChoicesLb(true);
- ab.generateNonMtlsEndpoint(generateNonMtlsEndpoint(app));
-
- // TODO: Remove when endpoints-config is read by all load balancers
- app.getModel().getHosts().stream()
- .sorted((a, b) -> a.getHostname().compareTo(b.getHostname()))
- .forEach(hostInfo -> ab.hosts(hostInfo.getHostname(), getHostsConfig(hostInfo)));
Set<ApplicationClusterInfo> applicationClusterInfos = app.getModel().applicationClusterInfo();
List<LbServicesConfig.Tenants.Applications.Endpoints.Builder> endpointBuilder = applicationClusterInfos.stream()
@@ -123,38 +108,4 @@ public class LbServicesProducer implements LbServicesConfig.Producer {
return activeRotation;
}
- private boolean generateNonMtlsEndpoint(ApplicationInfo app) {
- return generateNonMtlsEndpoint.with(FetchVector.Dimension.APPLICATION_ID, app.getApplicationId().serializedForm()).value();
- }
-
- private LbServicesConfig.Tenants.Applications.Hosts.Builder getHostsConfig(HostInfo hostInfo) {
- LbServicesConfig.Tenants.Applications.Hosts.Builder hb = new LbServicesConfig.Tenants.Applications.Hosts.Builder();
- hb.hostname(hostInfo.getHostname());
- hostInfo.getServices().forEach(serviceInfo -> hb.services(serviceInfo.getServiceName(), getServiceConfig(serviceInfo)));
- return hb;
- }
-
- private LbServicesConfig.Tenants.Applications.Hosts.Services.Builder getServiceConfig(ServiceInfo serviceInfo) {
- List<String> endpointAliases = Stream.of(serviceInfo.getProperty("endpointaliases").orElse("").split(",")).
- filter(prop -> !"".equals(prop)).collect(Collectors.toList());
- endpointAliases.addAll(Stream.of(serviceInfo.getProperty("rotations").orElse("").split(",")).filter(prop -> !"".equals(prop)).collect(Collectors.toList()));
- Collections.sort(endpointAliases);
-
- LbServicesConfig.Tenants.Applications.Hosts.Services.Builder sb = new LbServicesConfig.Tenants.Applications.Hosts.Services.Builder()
- .type(serviceInfo.getServiceType())
- .clustertype(serviceInfo.getProperty("clustertype").orElse(""))
- .clustername(serviceInfo.getProperty("clustername").orElse(""))
- .configId(serviceInfo.getConfigId())
- .servicealiases(Stream.of(serviceInfo.getProperty("servicealiases").orElse("").split(",")).
- filter(prop -> !"".equals(prop)).sorted((a, b) -> a.compareTo(b)).collect(Collectors.toList()))
- .endpointaliases(endpointAliases)
- .index(Integer.parseInt(serviceInfo.getProperty("index").orElse("999999")));
- serviceInfo.getPorts().forEach(portInfo -> {
- LbServicesConfig.Tenants.Applications.Hosts.Services.Ports.Builder pb = new LbServicesConfig.Tenants.Applications.Hosts.Services.Ports.Builder()
- .number(portInfo.getPort())
- .tags(Joiner.on(" ").join(portInfo.getTags()));
- sb.ports(pb);
- });
- return sb;
- }
}
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 e4a0fa81f94..f8ee3e5e0c9 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
@@ -1,10 +1,10 @@
// Copyright Yahoo. 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.google.common.util.concurrent.UncheckedTimeoutException;
import com.yahoo.cloud.config.ConfigserverConfig;
import com.yahoo.component.Version;
import com.yahoo.component.Vtag;
+import com.yahoo.concurrent.UncheckedTimeoutException;
import com.yahoo.config.FileReference;
import com.yahoo.config.application.api.ApplicationPackage;
import com.yahoo.config.application.api.DeployLogger;
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/session/SessionRepository.java b/configserver/src/main/java/com/yahoo/vespa/config/server/session/SessionRepository.java
index 42ccdffb2af..ab02594d164 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/session/SessionRepository.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/session/SessionRepository.java
@@ -578,7 +578,7 @@ public class SessionRepository {
// Skip sessions newly added (we might have a session in the file system, but not in ZooKeeper,
// we don't want to touch any of them)
if (newSessions.contains(candidate.getSessionId())) {
- log.log(Level.INFO, () -> "Skipping session " + candidate.getSessionId() + ", newly created: ");
+ log.log(Level.FINE, () -> "Skipping expiring newly created session " + candidate.getSessionId());
continue;
}
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/tenant/TenantRepository.java b/configserver/src/main/java/com/yahoo/vespa/config/server/tenant/TenantRepository.java
index b3c2fa2e300..7d53c383cf5 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/tenant/TenantRepository.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/tenant/TenantRepository.java
@@ -330,7 +330,7 @@ public class TenantRepository {
private Tenant createTenant(TenantName tenantName, Instant created) {
if (tenants.containsKey(tenantName)) return getTenant(tenantName);
- Instant start = Instant.now();
+ Instant start = clock.instant();
log.log(Level.FINE, () -> "Adding tenant '" + tenantName);
TenantApplications applicationRepo =
new TenantApplications(tenantName,
@@ -375,7 +375,7 @@ public class TenantRepository {
configDefinitionRepo,
zookeeperServerConfig.juteMaxBuffer());
log.log(Level.INFO, "Adding tenant '" + tenantName + "'" + ", created " + created +
- ". Bootstrapping in " + Duration.between(start, Instant.now()));
+ ". Bootstrapping in " + Duration.between(start, clock.instant()));
Tenant tenant = new Tenant(tenantName, sessionRepository, applicationRepo, created);
createAndWriteTenantMetaData(tenant);
tenants.putIfAbsent(tenantName, tenant);
diff --git a/configserver/src/main/java/com/yahoo/vespa/serviceview/StateRequestHandler.java b/configserver/src/main/java/com/yahoo/vespa/serviceview/StateRequestHandler.java
index d81297a87e9..d3c19bb0ba5 100644
--- a/configserver/src/main/java/com/yahoo/vespa/serviceview/StateRequestHandler.java
+++ b/configserver/src/main/java/com/yahoo/vespa/serviceview/StateRequestHandler.java
@@ -3,7 +3,7 @@ package com.yahoo.vespa.serviceview;
import com.google.inject.Inject;
import com.yahoo.cloud.config.ConfigserverConfig;
-import com.yahoo.container.jdisc.LoggingRequestHandler;
+import com.yahoo.container.jdisc.ThreadedHttpRequestHandler;
import com.yahoo.restapi.RestApi;
import com.yahoo.restapi.RestApiRequestHandler;
import com.yahoo.restapi.UriBuilder;
@@ -57,7 +57,7 @@ public class StateRequestHandler extends RestApiRequestHandler<StateRequestHandl
}
@Inject
- public StateRequestHandler(LoggingRequestHandler.Context context,
+ public StateRequestHandler(ThreadedHttpRequestHandler.Context context,
ConfigserverConfig configserverConfig) {
super(context, StateRequestHandler::createRestApiDefinition);
this.restApiPort = configserverConfig.httpport();
diff --git a/configserver/src/main/resources/configserver-app/services.xml b/configserver/src/main/resources/configserver-app/services.xml
index 729b50419d7..b3a37c6f669 100644
--- a/configserver/src/main/resources/configserver-app/services.xml
+++ b/configserver/src/main/resources/configserver-app/services.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8" ?>
<!-- Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -->
<services version="1.0" xmlns:preprocess="properties">
- <container id="configserver" jetty="true" version="1.0">
+ <container id="configserver" version="1.0">
<config name="container.jdisc.config.health-monitor">
<initialStatus>initializing</initialStatus>
</config>
diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/ApplicationRepositoryTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/ApplicationRepositoryTest.java
index 7baad75ebc5..284a0aa0a62 100644
--- a/configserver/src/test/java/com/yahoo/vespa/config/server/ApplicationRepositoryTest.java
+++ b/configserver/src/test/java/com/yahoo/vespa/config/server/ApplicationRepositoryTest.java
@@ -42,6 +42,7 @@ import com.yahoo.vespa.config.server.session.Session;
import com.yahoo.vespa.config.server.session.SessionRepository;
import com.yahoo.vespa.config.server.session.SessionZooKeeperClient;
import com.yahoo.vespa.config.server.tenant.Tenant;
+import com.yahoo.vespa.config.server.tenant.TenantMetaData;
import com.yahoo.vespa.config.server.tenant.TenantRepository;
import com.yahoo.vespa.config.server.tenant.TestTenantRepository;
import com.yahoo.vespa.config.util.ConfigUtils;
@@ -94,7 +95,6 @@ public class ApplicationRepositoryTest {
private final static TenantName tenant1 = TenantName.from("test1");
private final static TenantName tenant2 = TenantName.from("test2");
- private final static TenantName tenant3 = TenantName.from("test3");
private final static ManualClock clock = new ManualClock(Instant.now());
private ApplicationRepository applicationRepository;
@@ -103,6 +103,7 @@ public class ApplicationRepositoryTest {
private OrchestratorMock orchestrator;
private TimeoutBudget timeoutBudget;
private Curator curator;
+ private ConfigserverConfig configserverConfig;
@Rule
public TemporaryFolder temporaryFolder = new TemporaryFolder();
@@ -114,24 +115,22 @@ public class ApplicationRepositoryTest {
@Before
public void setup() throws IOException {
curator = new MockCurator();
- ConfigserverConfig configserverConfig = new ConfigserverConfig.Builder()
+ configserverConfig = new ConfigserverConfig.Builder()
.payloadCompressionType(ConfigserverConfig.PayloadCompressionType.Enum.UNCOMPRESSED)
.configServerDBDir(temporaryFolder.newFolder().getAbsolutePath())
.configDefinitionsDir(temporaryFolder.newFolder().getAbsolutePath())
.fileReferencesDir(temporaryFolder.newFolder().getAbsolutePath())
.build();
- InMemoryFlagSource flagSource = new InMemoryFlagSource();
tenantRepository = new TestTenantRepository.Builder()
.withClock(clock)
.withConfigserverConfig(configserverConfig)
.withCurator(curator)
.withFileDistributionFactory(new MockFileDistributionFactory(configserverConfig))
- .withFlagSource(flagSource)
+ .withFlagSource(new InMemoryFlagSource())
.build();
tenantRepository.addTenant(TenantRepository.HOSTED_VESPA_TENANT);
tenantRepository.addTenant(tenant1);
tenantRepository.addTenant(tenant2);
- tenantRepository.addTenant(tenant3);
orchestrator = new OrchestratorMock();
provisioner = new MockProvisioner();
applicationRepository = new ApplicationRepository.Builder()
@@ -146,47 +145,42 @@ public class ApplicationRepositoryTest {
}
@Test
- public void prepareAndActivate() {
- PrepareResult result = prepareAndActivate(testApp);
- assertTrue(result.configChangeActions().getRefeedActions().isEmpty());
- assertTrue(result.configChangeActions().getReindexActions().isEmpty());
- assertTrue(result.configChangeActions().getRestartActions().isEmpty());
-
- Tenant tenant = applicationRepository.getTenant(applicationId());
- Session session = applicationRepository.getActiveLocalSession(tenant, applicationId());
- session.getAllocatedHosts();
- }
-
- @Test
public void prepareAndActivateWithTenantMetaData() {
- Instant startTime = clock.instant();
+ long startTime = clock.instant().toEpochMilli();
Duration duration = Duration.ofHours(1);
clock.advance(duration);
- Instant deployTime = clock.instant();
+ long deployTime = clock.instant().toEpochMilli();
PrepareResult result = prepareAndActivate(testApp);
assertTrue(result.configChangeActions().getRefeedActions().isEmpty());
assertTrue(result.configChangeActions().getReindexActions().isEmpty());
assertTrue(result.configChangeActions().getRestartActions().isEmpty());
- Tenant tenant = applicationRepository.getTenant(applicationId());
+ Session session = applicationRepository.getActiveLocalSession(tenant(), applicationId());
+ session.getAllocatedHosts();
- assertEquals(startTime.toEpochMilli(),
- applicationRepository.getTenantMetaData(tenant).createdTimestamp().toEpochMilli());
- assertEquals(deployTime.toEpochMilli(),
- applicationRepository.getTenantMetaData(tenant).lastDeployTimestamp().toEpochMilli());
+ assertEquals(startTime, tenantMetaData(tenant()).createdTimestamp().toEpochMilli());
+ assertEquals(deployTime, tenantMetaData(tenant()).lastDeployTimestamp().toEpochMilli());
// Creating a new tenant will have metadata with timestamp equal to current time
clock.advance(duration);
- Instant createTenantTime = clock.instant();
+ long createTenantTime = clock.instant().toEpochMilli();
Tenant fooTenant = tenantRepository.addTenant(TenantName.from("foo"));
- assertEquals(createTenantTime.toEpochMilli(),
- applicationRepository.getTenantMetaData(fooTenant).createdTimestamp().toEpochMilli());
- assertEquals(createTenantTime.toEpochMilli(),
- applicationRepository.getTenantMetaData(fooTenant).lastDeployTimestamp().toEpochMilli());
+ assertEquals(createTenantTime, tenantMetaData(fooTenant).createdTimestamp().toEpochMilli());
+ assertEquals(createTenantTime, tenantMetaData(fooTenant).lastDeployTimestamp().toEpochMilli());
}
@Test
public void prepareAndActivateWithRestart() {
+ applicationRepository = new ApplicationRepository.Builder()
+ .withTenantRepository(tenantRepository)
+ .withProvisioner(provisioner)
+ .withConfigserverConfig(configserverConfig)
+ .withOrchestrator(orchestrator)
+ .withLogRetriever(new MockLogRetriever())
+ .withClock(clock)
+ .withConfigConvergenceChecker(new MockConfigConvergenceChecker(2))
+ .build();
+
prepareAndActivate(testAppJdiscOnly);
PrepareResult result = prepareAndActivate(testAppJdiscOnlyRestart);
assertTrue(result.configChangeActions().getRefeedActions().isEmpty());
@@ -217,24 +211,20 @@ public class ApplicationRepositoryTest {
@Test
public void redeploy() {
- PrepareResult result = deployApp(testApp);
+ long firstSessionId = deployApp(testApp).sessionId();
- long firstSessionId = result.sessionId();
-
- PrepareResult result2 = deployApp(testApp);
- long secondSessionId = result2.sessionId();
+ long secondSessionId = deployApp(testApp).sessionId();
assertNotEquals(firstSessionId, secondSessionId);
- Tenant tenant = applicationRepository.getTenant(applicationId());
- Session session = applicationRepository.getActiveLocalSession(tenant, applicationId());
+ Session session = applicationRepository.getActiveLocalSession(tenant(), applicationId());
assertEquals(firstSessionId, session.getMetaData().getPreviousActiveGeneration());
}
@Test
public void createFromActiveSession() {
- PrepareResult result = deployApp(testApp);
- long sessionId = applicationRepository.createSessionFromExisting(applicationId(), false, timeoutBudget);
- long originalSessionId = result.sessionId();
+ long originalSessionId = deployApp(testApp).sessionId();
+
+ long sessionId = createSessionFromExisting(applicationId(), timeoutBudget);
ApplicationMetaData originalApplicationMetaData = getApplicationMetaData(applicationId(), originalSessionId);
ApplicationMetaData applicationMetaData = getApplicationMetaData(applicationId(), sessionId);
@@ -269,20 +259,24 @@ public class ApplicationRepositoryTest {
}
@Test
- public void deleteUnusedFileReferences() throws IOException, InterruptedException {
+ public void deleteUnusedFileReferences() throws IOException {
File fileReferencesDir = temporaryFolder.newFolder();
Duration keepFileReferencesDuration = Duration.ofSeconds(4);
// Add file reference that is not in use and should be deleted (older than 'keepFileReferencesDuration')
File filereferenceDirOldest = createFilereferenceOnDisk(new File(fileReferencesDir, "foo"));
- //Thread.sleep(Duration.ofSeconds(1).toMillis());
+ clock.advance(Duration.ofSeconds(1));
// Add file references that are not in use and could be deleted
IntStream.range(0, 3).forEach(i -> {
- createFilereferenceOnDisk(new File(fileReferencesDir, "bar" + i));
- try { Thread.sleep(Duration.ofSeconds(1).toMillis()); } catch (InterruptedException e) { /* ignore */ }
+ try {
+ createFilereferenceOnDisk(new File(fileReferencesDir, "bar" + i));
+ } catch (IOException e) {
+ fail(e.getMessage());
+ }
+ clock.advance(Duration.ofSeconds(1));
});
- Thread.sleep(keepFileReferencesDuration.toMillis());
+ clock.advance(keepFileReferencesDuration);
// Add file reference that is not in use, but should not be deleted (newer than 'keepFileReferencesDuration')
File filereferenceDirNewest = createFilereferenceOnDisk(new File(fileReferencesDir, "baz"));
@@ -309,17 +303,17 @@ public class ApplicationRepositoryTest {
assertTrue(filereferenceDirNewest.exists());
}
- private File createFilereferenceOnDisk(File filereferenceDir) {
+ private File createFilereferenceOnDisk(File filereferenceDir) throws IOException {
assertTrue(filereferenceDir.mkdir());
- File bar = new File(filereferenceDir, "file");
- IOUtils.writeFile(bar, Utf8.toBytes("test"));
+ File file = new File(filereferenceDir, "bar");
+ IOUtils.writeFile(file, Utf8.toBytes("test"));
+ Files.setAttribute(filereferenceDir.toPath(), "lastAccessTime", FileTime.from(clock.instant()));
return filereferenceDir;
}
@Test
public void delete() {
- Tenant tenant = applicationRepository.getTenant(applicationId());
- SessionRepository sessionRepository = tenant.getSessionRepository();
+ SessionRepository sessionRepository = tenant().getSessionRepository();
{
PrepareResult result = deployApp(testApp);
long sessionId = result.sessionId();
@@ -330,7 +324,7 @@ public class ApplicationRepositoryTest {
assertNotNull(applicationRepository.getActiveSession(applicationId()));
Path sessionNode = sessionRepository.getSessionPath(sessionId);
assertTrue(curator.exists(sessionNode));
- TenantFileSystemDirs tenantFileSystemDirs = tenant.getApplicationRepo().getTenantFileSystemDirs();
+ TenantFileSystemDirs tenantFileSystemDirs = tenant().getApplicationRepo().getTenantFileSystemDirs();
File sessionFile = new File(tenantFileSystemDirs.sessionsPath(), String.valueOf(sessionId));
assertTrue(sessionFile.exists());
@@ -339,7 +333,7 @@ public class ApplicationRepositoryTest {
assertNull(applicationRepository.getActiveSession(applicationId()));
assertEquals(Optional.empty(), sessionRepository.getRemoteSession(sessionId).applicationSet());
assertTrue(provisioner.removed());
- assertEquals(tenant.getName(), provisioner.lastApplicationId().tenant());
+ assertEquals(tenant().getName(), provisioner.lastApplicationId().tenant());
assertEquals(applicationId(), provisioner.lastApplicationId());
assertTrue(curator.exists(sessionNode));
assertEquals(Session.Status.DELETE.name(), Utf8.toString(curator.getData(sessionNode.append("sessionState")).get()));
@@ -367,10 +361,9 @@ public class ApplicationRepositoryTest {
assertTrue(applicationRepository.delete(applicationId()));
}
- // If delete fails, a retry should work if the failure is transient and zookeeper state should be constistent
+ // If delete fails, a retry should work if the failure is transient and zookeeper state should be consistent
{
- PrepareResult result = deployApp(testApp);
- long sessionId = result.sessionId();
+ long sessionId = deployApp(testApp).sessionId();
assertNotNull(sessionRepository.getRemoteSession(sessionId));
assertNotNull(applicationRepository.getActiveSession(applicationId()));
assertEquals(sessionId, applicationRepository.getActiveSession(applicationId()).getSessionId());
@@ -488,8 +481,7 @@ public class ApplicationRepositoryTest {
// ... but it should be deleted if some time has passed
clock.advance(Duration.ofSeconds(60));
- tester.applicationRepository().deleteExpiredLocalSessions();
- assertEquals(1, sessionRepository.getLocalSessions().size());
+ deleteExpiredLocalSessionsAndAssertNumberOfSessions(1, tester, sessionRepository);
// Set older created timestamp for session dir for local session without any data in zookeeper, should be deleted
setCreatedTime(dir, Instant.now().minus(Duration.ofDays(31)));
@@ -564,10 +556,10 @@ public class ApplicationRepositoryTest {
long firstSession = result.sessionId();
TimeoutBudget timeoutBudget = new TimeoutBudget(clock, Duration.ofSeconds(10));
- long sessionId = applicationRepository.createSession(applicationId(), timeoutBudget, testAppJdiscOnly);
+ long sessionId = createSession(applicationId(), timeoutBudget, testAppJdiscOnly);
exceptionRule.expect(IllegalArgumentException.class);
exceptionRule.expectMessage("tenant:test1 Session 3 is not prepared");
- applicationRepository.activate(applicationRepository.getTenant(applicationId()), sessionId, timeoutBudget, false);
+ activate(applicationId(), sessionId, timeoutBudget);
Session activeSession = applicationRepository.getActiveSession(applicationId());
assertEquals(firstSession, activeSession.getSessionId());
@@ -577,14 +569,13 @@ public class ApplicationRepositoryTest {
@Test
public void testActivationTimesOut() {
// Needed so we can test that the original active session is still active after a failed activation
- PrepareResult result = deployApp(testAppJdiscOnly);
- long firstSession = result.sessionId();
+ long firstSession = deployApp(testAppJdiscOnly).sessionId();
- long sessionId = applicationRepository.createSession(applicationId(), timeoutBudget, testAppJdiscOnly);
+ long sessionId = createSession(applicationId(), timeoutBudget, testAppJdiscOnly);
applicationRepository.prepare(sessionId, prepareParams());
exceptionRule.expect(RuntimeException.class);
exceptionRule.expectMessage("Timeout exceeded when trying to activate 'test1.testapp'");
- applicationRepository.activate(applicationRepository.getTenant(applicationId()), sessionId, new TimeoutBudget(clock, Duration.ofSeconds(0)), false);
+ activate(applicationId(), sessionId, new TimeoutBudget(clock, Duration.ofSeconds(0)));
Session activeSession = applicationRepository.getActiveSession(applicationId());
assertEquals(firstSession, activeSession.getSessionId());
@@ -595,18 +586,16 @@ public class ApplicationRepositoryTest {
public void testActivationOfSessionCreatedFromNoLongerActiveSessionFails() {
TimeoutBudget timeoutBudget = new TimeoutBudget(clock, Duration.ofSeconds(10));
- PrepareResult result1 = deployApp(testAppJdiscOnly);
- result1.sessionId();
+ deployApp(testAppJdiscOnly);
- long sessionId2 = applicationRepository.createSessionFromExisting(applicationId(), false, timeoutBudget);
+ long sessionId2 = createSessionFromExisting(applicationId(), timeoutBudget);
// Deploy and activate another session
- PrepareResult result2 = deployApp(testAppJdiscOnly);
- result2.sessionId();
+ deployApp(testAppJdiscOnly);
applicationRepository.prepare(sessionId2, prepareParams());
exceptionRule.expect(ActivationConflictException.class);
exceptionRule.expectMessage("app:test1.testapp.default Cannot activate session 3 because the currently active session (4) has changed since session 3 was created (was 2 at creation time)");
- applicationRepository.activate(applicationRepository.getTenant(applicationId()), sessionId2, timeoutBudget, false);
+ activate(applicationId(), sessionId2, timeoutBudget);
}
@Test
@@ -620,7 +609,7 @@ public class ApplicationRepositoryTest {
exceptionRule.expect(IllegalArgumentException.class);
exceptionRule.expectMessage("app:test1.testapp.default Session 2 is already active");
- applicationRepository.activate(applicationRepository.getTenant(applicationId()), sessionId, timeoutBudget, false);
+ activate(applicationId(), sessionId, timeoutBudget);
}
@Test
@@ -641,9 +630,8 @@ public class ApplicationRepositoryTest {
.vespaVersion(vespaVersion)
.build());
- RequestHandler requestHandler = getRequestHandler(applicationId());
- SimpletypesConfig config = resolve(SimpletypesConfig.class, requestHandler, applicationId(), vespaVersion);
- assertEquals(1337 , config.intval());
+ SimpletypesConfig config = resolve(applicationId(), vespaVersion);
+ assertEquals(1337, config.intval());
}
@Test
@@ -664,18 +652,17 @@ public class ApplicationRepositoryTest {
.vespaVersion(vespaVersion)
.build());
- RequestHandler requestHandler = getRequestHandler(applicationId());
- SimpletypesConfig config = resolve(SimpletypesConfig.class, requestHandler, applicationId(), vespaVersion);
+ SimpletypesConfig config = resolve(applicationId(), vespaVersion);
assertEquals(1337, config.intval());
- RequestHandler requestHandler2 = getRequestHandler(appId2);
- SimpletypesConfig config2 = resolve(SimpletypesConfig.class, requestHandler2, appId2, vespaVersion);
+ SimpletypesConfig config2 = resolve(appId2, vespaVersion);
assertEquals(1330, config2.intval());
+ RequestHandler requestHandler = getRequestHandler(applicationId());
assertTrue(requestHandler.hasApplication(applicationId(), Optional.of(vespaVersion)));
assertNull(requestHandler.resolveApplicationId("doesnotexist"));
assertEquals(new ApplicationId.Builder().tenant(tenant1).applicationName("testapp").build(),
- requestHandler.resolveApplicationId("mytesthost")); // Host set in application package.
+ requestHandler.resolveApplicationId("mytesthost")); // Host set in application package.
}
@Test
@@ -686,12 +673,11 @@ public class ApplicationRepositoryTest {
.vespaVersion(vespaVersion)
.build());
- RequestHandler requestHandler = getRequestHandler(applicationId());
- SimpletypesConfig config = resolve(SimpletypesConfig.class, requestHandler, applicationId(), vespaVersion);
+ SimpletypesConfig config = resolve(applicationId(), vespaVersion);
assertEquals(1337, config.intval());
// TODO: Revisit this test, I cannot see that we create a model for version 3.2.1
- config = resolve(SimpletypesConfig.class, requestHandler, applicationId(), new Version(3, 2, 1));
+ config = resolve(applicationId(), new Version(3, 2, 1));
assertEquals(1337, config.intval());
}
@@ -703,15 +689,14 @@ public class ApplicationRepositoryTest {
.vespaVersion(vespaVersion)
.build());
- RequestHandler requestHandler = getRequestHandler(applicationId());
- SimpletypesConfig config = resolve(SimpletypesConfig.class, requestHandler, applicationId(), vespaVersion);
- assertEquals(1337 , config.intval());
+ SimpletypesConfig config = resolve(applicationId(), vespaVersion);
+ assertEquals(1337, config.intval());
applicationRepository.delete(applicationId());
exceptionRule.expect(com.yahoo.vespa.config.server.NotFoundException.class);
exceptionRule.expectMessage("No such application id: test1.testapp");
- resolve(SimpletypesConfig.class, requestHandler, applicationId(), vespaVersion);
+ resolve(applicationId(), vespaVersion);
}
private PrepareResult prepareAndActivate(File application) {
@@ -730,14 +715,14 @@ public class ApplicationRepositoryTest {
return new PrepareParams.Builder().applicationId(applicationId()).build();
}
- private ApplicationId applicationId() {
- return applicationId(tenant1);
- }
+ private ApplicationId applicationId() { return applicationId(tenant1); }
private ApplicationId applicationId(TenantName tenantName) {
return ApplicationId.from(tenantName, ApplicationName.from("testapp"), InstanceName.defaultName());
}
+ private Tenant tenant() { return applicationRepository.getTenant(applicationId()); }
+
private ApplicationMetaData getApplicationMetaData(ApplicationId applicationId, long sessionId) {
Tenant tenant = tenantRepository.getTenant(applicationId.tenant());
return applicationRepository.getMetadataFromLocalSession(tenant, sessionId);
@@ -786,12 +771,11 @@ public class ApplicationRepositoryTest {
}
- private <T extends ConfigInstance> T resolve(Class<T> clazz,
- RequestHandler applications,
- ApplicationId appId,
- Version vespaVersion) {
+ private SimpletypesConfig resolve(ApplicationId applicationId, Version vespaVersion) {
String configId = "";
- ConfigResponse response = getConfigResponse(clazz, applications, appId, vespaVersion, configId);
+ RequestHandler requestHandler = getRequestHandler(applicationId);
+ Class<SimpletypesConfig> clazz = SimpletypesConfig.class;
+ ConfigResponse response = getConfigResponse(clazz, requestHandler, applicationId, vespaVersion, configId);
return ConfigPayload.fromUtf8Array(response.getPayload()).toInstance(clazz, configId);
}
@@ -841,4 +825,20 @@ public class ApplicationRepositoryTest {
assertEquals(expectedNumberOfSessions, sessionRepository.getLocalSessions().size());
}
+ private void activate(ApplicationId applicationId, long sessionId, TimeoutBudget timeoutBudget) {
+ applicationRepository.activate(applicationRepository.getTenant(applicationId), sessionId, timeoutBudget, false);
+ }
+
+ private TenantMetaData tenantMetaData(Tenant tenant) {
+ return applicationRepository.getTenantMetaData(tenant);
+ }
+
+ private long createSession(ApplicationId applicationId, TimeoutBudget timeoutBudget, File app) {
+ return applicationRepository.createSession(applicationId, timeoutBudget, app);
+ }
+
+ private long createSessionFromExisting(ApplicationId applicationId, TimeoutBudget timeoutBudget) {
+ return applicationRepository.createSessionFromExisting(applicationId, false, timeoutBudget);
+ }
+
}
diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/ConfigServerBootstrapTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/ConfigServerBootstrapTest.java
index babc7b79b65..67613d5a806 100644
--- a/configserver/src/test/java/com/yahoo/vespa/config/server/ConfigServerBootstrapTest.java
+++ b/configserver/src/test/java/com/yahoo/vespa/config/server/ConfigServerBootstrapTest.java
@@ -18,6 +18,7 @@ import com.yahoo.container.handler.VipStatus;
import com.yahoo.container.jdisc.state.StateMonitor;
import com.yahoo.docproc.jdisc.metric.NullMetric;
import com.yahoo.path.Path;
+import com.yahoo.test.ManualClock;
import com.yahoo.text.Utf8;
import com.yahoo.vespa.config.server.application.ConfigConvergenceChecker;
import com.yahoo.vespa.config.server.deploy.DeployTester;
@@ -42,6 +43,7 @@ import java.util.Optional;
import java.util.function.BooleanSupplier;
import java.util.stream.Collectors;
+import static com.yahoo.vespa.config.server.ConfigServerBootstrap.VipStatusMode;
import static com.yahoo.vespa.config.server.ConfigServerBootstrap.VipStatusMode.VIP_STATUS_FILE;
import static com.yahoo.vespa.config.server.ConfigServerBootstrap.VipStatusMode.VIP_STATUS_PROGRAMMATICALLY;
import static com.yahoo.vespa.config.server.deploy.DeployTester.createHostedModelFactory;
@@ -56,6 +58,7 @@ import static org.junit.Assert.assertTrue;
public class ConfigServerBootstrapTest {
private final MockCurator curator = new MockCurator();
+ private final ManualClock clock = new ManualClock();
@Rule
public TemporaryFolder temporaryFolder = new TemporaryFolder();
@@ -177,7 +180,7 @@ public class ConfigServerBootstrapTest {
waitUntil(() -> bootstrap.vipStatus().isInRotation(), "failed waiting for server to be in rotation");
}
- private ConfigServerBootstrap createBootstrap(DeployTester tester, RpcServer rpcServer, ConfigServerBootstrap.VipStatusMode vipStatusProgrammatically) throws IOException {
+ private ConfigServerBootstrap createBootstrap(DeployTester tester, RpcServer rpcServer, VipStatusMode vipStatusMode) throws IOException {
VersionState versionState = createVersionState();
assertTrue(versionState.isUpgraded());
@@ -188,9 +191,10 @@ public class ConfigServerBootstrapTest {
versionState,
stateMonitor,
vipStatus,
- vipStatusProgrammatically,
+ vipStatusMode,
new InMemoryFlagSource(),
- new ConfigConvergenceChecker());
+ new ConfigConvergenceChecker(),
+ clock);
}
private void waitUntil(BooleanSupplier booleanSupplier, String messageIfWaitingFails) throws InterruptedException {
@@ -223,7 +227,7 @@ public class ConfigServerBootstrapTest {
.fileReferencesDir(temporaryFolder.newFolder("filedistribution").getAbsolutePath())
.hostedVespa(hosted)
.multitenant(hosted)
- .maxDurationOfBootstrap(2) /* seconds */
+ .maxDurationOfBootstrap(0) /* seconds, 0 => it will not retry deployment if bootstrap fails */
.sleepTimeWhenRedeployingFails(0)); /* seconds */
}
diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/MockConfigConvergenceChecker.java b/configserver/src/test/java/com/yahoo/vespa/config/server/MockConfigConvergenceChecker.java
new file mode 100644
index 00000000000..b4892caa05f
--- /dev/null
+++ b/configserver/src/test/java/com/yahoo/vespa/config/server/MockConfigConvergenceChecker.java
@@ -0,0 +1,38 @@
+package com.yahoo.vespa.config.server;
+
+import com.yahoo.config.model.api.ServiceInfo;
+import com.yahoo.vespa.config.server.application.Application;
+import com.yahoo.vespa.config.server.application.ConfigConvergenceChecker;
+
+import java.time.Duration;
+import java.util.Map;
+
+public class MockConfigConvergenceChecker extends ConfigConvergenceChecker {
+
+ private final long wantedGeneration;
+
+ public MockConfigConvergenceChecker(long wantedGeneration) {
+ this.wantedGeneration = wantedGeneration;
+ }
+
+ @Override
+ public Map<ServiceInfo, Long> getServiceConfigGenerations(Application application, Duration timeoutPerService) {
+ return Map.of();
+ }
+
+ @Override
+ public ServiceListResponse checkConvergenceForAllServices(Application application, Duration timeoutPerService) {
+ return new ServiceListResponse(Map.of(), wantedGeneration, wantedGeneration);
+ }
+
+ @Override
+ public ServiceResponse getServiceConfigGeneration(Application application, String hostAndPortToCheck, Duration timeout) {
+ return new ServiceResponse(ServiceResponse.Status.ok, wantedGeneration);
+ }
+
+ @Override
+ public ServiceListResponse checkConvergenceUnlessDeferringChangesUntilRestart(Application application) {
+ return new ServiceListResponse(Map.of(), wantedGeneration, wantedGeneration);
+ }
+
+}
diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/SuperModelControllerTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/SuperModelControllerTest.java
index 2c738e2d519..57060e10282 100644
--- a/configserver/src/test/java/com/yahoo/vespa/config/server/SuperModelControllerTest.java
+++ b/configserver/src/test/java/com/yahoo/vespa/config/server/SuperModelControllerTest.java
@@ -13,9 +13,9 @@ import com.yahoo.config.provision.ApplicationName;
import com.yahoo.config.provision.InstanceName;
import com.yahoo.config.provision.TenantName;
import com.yahoo.config.provision.Zone;
-import com.yahoo.vespa.config.PayloadChecksums;
import com.yahoo.jrt.Request;
import com.yahoo.vespa.config.ConfigKey;
+import com.yahoo.vespa.config.PayloadChecksums;
import com.yahoo.vespa.config.protocol.CompressionType;
import com.yahoo.vespa.config.protocol.DefContent;
import com.yahoo.vespa.config.protocol.JRTServerConfigRequestV3;
@@ -35,10 +35,9 @@ import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Optional;
-import static com.yahoo.config.model.api.container.ContainerServiceType.QRSERVER;
import static com.yahoo.vespa.config.protocol.JRTClientConfigRequestV3.createWithParams;
import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertNotNull;
/**
* @author Ulf Lilleengen
@@ -67,10 +66,9 @@ public class SuperModelControllerTest {
assertEquals(1, lbc.tenants().size());
assertEquals(1, lbc.tenants("a").applications().size());
Applications app = lbc.tenants("a").applications("foo:prod:default:default");
- assertTrue(app.hosts().size() > 0);
+ assertNotNull(app);
}
-
@Test(expected = UnknownConfigDefinitionException.class)
public void test_unknown_config_definition() {
PayloadChecksums payloadChecksums = PayloadChecksums.empty();
@@ -107,31 +105,12 @@ public class SuperModelControllerTest {
assertEquals(2, lbc.tenants().size());
assertEquals(2, lbc.tenants("t1").applications().size());
assertEquals(1, lbc.tenants("t2").applications().size());
- assertEquals(1, lbc.tenants("t2").applications("minetooadvancedapp:prod:default:default").hosts().size());
- assertQrServer(lbc.tenants("t2").applications("minetooadvancedapp:prod:default:default"));
}
private ApplicationId applicationId(String applicationName, TenantName tenantName) {
return ApplicationId.from(tenantName, ApplicationName.from(applicationName), InstanceName.defaultName());
}
- private void assertQrServer(Applications app) {
- String host = app.hosts().keySet().iterator().next();
- Applications.Hosts hosts = app.hosts(host);
- assertEquals(host, hosts.hostname());
- for (Map.Entry<String, Applications.Hosts.Services> e : app.hosts(host).services().entrySet()) {
- if (QRSERVER.serviceName.equals(e.getKey())) {
- Applications.Hosts.Services s = e.getValue();
- assertEquals("qrserver", s.type());
- assertEquals(4, s.ports().size());
- assertEquals(8000, s.ports().get(0).number());
- assertEquals(0, s.index());
- return;
- }
- }
- org.junit.Assert.fail("No container service in config");
- }
-
private DeployState createDeployState(File applicationPackage, ApplicationId applicationId) {
return new DeployState.Builder()
.applicationPackage(FilesApplicationPackage.fromFile(applicationPackage))
diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/application/ConfigConvergenceCheckerTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/application/ConfigConvergenceCheckerTest.java
index 6afb9ef086d..6016ce991d0 100644
--- a/configserver/src/test/java/com/yahoo/vespa/config/server/application/ConfigConvergenceCheckerTest.java
+++ b/configserver/src/test/java/com/yahoo/vespa/config/server/application/ConfigConvergenceCheckerTest.java
@@ -28,6 +28,7 @@ import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.options
import static com.yahoo.vespa.config.server.application.ConfigConvergenceChecker.ServiceListResponse;
import static com.yahoo.vespa.config.server.application.ConfigConvergenceChecker.ServiceResponse;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
/**
@@ -88,12 +89,12 @@ public class ConfigConvergenceCheckerTest {
@Test
public void service_list_convergence() {
{
- URI requestUrl = testServer().resolve("/serviceconverge");
wireMock.stubFor(get(urlEqualTo("/state/v1/config")).willReturn(okJson("{\"config\":{\"generation\":3}}")));
- ServiceListResponse response = checker.getServiceConfigGenerations(application, requestUrl, clientTimeout);
+ ServiceListResponse response = checker.checkConvergenceForAllServices(application, clientTimeout);
assertEquals(3, response.wantedGeneration);
assertEquals(3, response.currentGeneration);
+ assertTrue(response.converged);
List<ServiceListResponse.Service> services = response.services;
assertEquals(1, services.size());
assertService(this.service, services.get(0), 3);
@@ -113,9 +114,10 @@ public class ConfigConvergenceCheckerTest {
URI requestUrl = testServer().resolve("/serviceconverge");
- ServiceListResponse response = checker.getServiceConfigGenerations(application, requestUrl, clientTimeout);
+ ServiceListResponse response = checker.checkConvergenceForAllServices(application, clientTimeout);
assertEquals(4, response.wantedGeneration);
assertEquals(3, response.currentGeneration);
+ assertFalse(response.converged);
List<ServiceListResponse.Service> services = response.services;
assertEquals(2, services.size());
diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/deploy/DeployHandlerLoggerTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/deploy/DeployHandlerLoggerTest.java
index 582b7f2c071..ea1f6a845b0 100644
--- a/configserver/src/test/java/com/yahoo/vespa/config/server/deploy/DeployHandlerLoggerTest.java
+++ b/configserver/src/test/java/com/yahoo/vespa/config/server/deploy/DeployHandlerLoggerTest.java
@@ -39,6 +39,7 @@ public class DeployHandlerLoggerTest {
assertTrue(Pattern.matches(expectedPattern, baos.toString()));
}
+ @SuppressWarnings("deprecation")
private void logMessages(DeployLogger logger) {
logger.log(LogLevel.DEBUG, "foobar");
logger.log(LogLevel.SPAM, "foobar");
diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/deploy/DeployTester.java b/configserver/src/test/java/com/yahoo/vespa/config/server/deploy/DeployTester.java
index f16b1102f2a..7f223fbce6f 100644
--- a/configserver/src/test/java/com/yahoo/vespa/config/server/deploy/DeployTester.java
+++ b/configserver/src/test/java/com/yahoo/vespa/config/server/deploy/DeployTester.java
@@ -24,6 +24,7 @@ import com.yahoo.config.provision.Zone;
import com.yahoo.vespa.config.server.ApplicationRepository;
import com.yahoo.vespa.config.server.MockProvisioner;
import com.yahoo.vespa.config.server.TimeoutBudget;
+import com.yahoo.vespa.config.server.application.ConfigConvergenceChecker;
import com.yahoo.vespa.config.server.application.OrchestratorMock;
import com.yahoo.vespa.config.server.filedistribution.MockFileDistributionFactory;
import com.yahoo.vespa.config.server.http.v2.PrepareResult;
@@ -37,9 +38,10 @@ import com.yahoo.vespa.config.server.tenant.TenantRepository;
import com.yahoo.vespa.config.server.tenant.TestTenantRepository;
import com.yahoo.vespa.curator.Curator;
import com.yahoo.vespa.curator.mock.MockCurator;
+import com.yahoo.vespa.flags.FlagSource;
+import com.yahoo.vespa.flags.InMemoryFlagSource;
import com.yahoo.vespa.model.VespaModel;
import com.yahoo.vespa.model.VespaModelFactory;
-import com.yahoo.vespa.orchestrator.Orchestrator;
import java.io.File;
import java.nio.file.Files;
@@ -253,7 +255,8 @@ public class DeployTester {
private Curator curator = new MockCurator();
private Metrics metrics;
private List<ModelFactory> modelFactories;
- private Orchestrator orchestrator;
+ private ConfigConvergenceChecker configConvergenceChecker = new ConfigConvergenceChecker();
+ private FlagSource flagSource = new InMemoryFlagSource();
public DeployTester build() {
Clock clock = Optional.ofNullable(this.clock).orElseGet(Clock::systemUTC);
@@ -285,9 +288,11 @@ public class DeployTester {
ApplicationRepository applicationRepository = new ApplicationRepository.Builder()
.withTenantRepository(tenantRepository)
.withConfigserverConfig(configserverConfig)
- .withOrchestrator(Optional.ofNullable(orchestrator).orElseGet(OrchestratorMock::new))
+ .withOrchestrator(new OrchestratorMock())
.withClock(clock)
.withProvisioner(provisioner)
+ .withConfigConvergenceChecker(configConvergenceChecker)
+ .withFlagSource(flagSource)
.build();
return new DeployTester(clock, tenantRepository, applicationRepository);
@@ -336,10 +341,16 @@ public class DeployTester {
return this;
}
- public Builder orchestrator(Orchestrator orchestrator) {
- this.orchestrator = orchestrator;
+ public Builder configConvergenceChecker(ConfigConvergenceChecker configConvergenceChecker) {
+ this.configConvergenceChecker = configConvergenceChecker;
return this;
}
+
+ public Builder flagSource(FlagSource flagSource) {
+ this.flagSource = flagSource;
+ return this;
+ }
+
}
}
diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/deploy/HostedDeployTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/deploy/HostedDeployTest.java
index 33e18843738..a6d7cf02bc7 100644
--- a/configserver/src/test/java/com/yahoo/vespa/config/server/deploy/HostedDeployTest.java
+++ b/configserver/src/test/java/com/yahoo/vespa/config/server/deploy/HostedDeployTest.java
@@ -22,6 +22,7 @@ import com.yahoo.config.provision.Environment;
import com.yahoo.config.provision.RegionName;
import com.yahoo.config.provision.Zone;
import com.yahoo.test.ManualClock;
+import com.yahoo.vespa.config.server.MockConfigConvergenceChecker;
import com.yahoo.vespa.config.server.application.ApplicationReindexing;
import com.yahoo.vespa.config.server.http.InternalServerException;
import com.yahoo.vespa.config.server.http.InvalidApplicationException;
@@ -432,7 +433,14 @@ public class HostedDeployTest {
"reindex please", services, "music"),
new VespaRestartAction(ClusterSpec.Id.from("test"), "change", services)));
- DeployTester tester = createTester(hosts, modelFactories, prodZone, clock);
+ DeployTester tester = new DeployTester.Builder()
+ .modelFactories(modelFactories)
+ .configserverConfig(createConfigserverConfig(prodZone))
+ .clock(clock)
+ .zone(prodZone)
+ .hostProvisioner(new InMemoryProvisioner(new Hosts(hosts), true, false))
+ .configConvergenceChecker(new MockConfigConvergenceChecker(2))
+ .build();
PrepareResult prepareResult = tester.deployApp("src/test/apps/hosted/", "6.1.0");
assertEquals(7, tester.getAllocatedHostsOf(tester.applicationId()).getHosts().size());
@@ -480,7 +488,9 @@ public class HostedDeployTest {
.configserverConfig(createConfigserverConfig(prodZone))
.clock(clock)
.zone(prodZone)
- .hostProvisioner(new InMemoryProvisioner(new Hosts(hosts), true, false)).build();
+ .hostProvisioner(new InMemoryProvisioner(new Hosts(hosts), true, false))
+ .configConvergenceChecker(new MockConfigConvergenceChecker(2))
+ .build();
}
private static class ConfigChangeActionsModelFactory extends TestModelFactory {
diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/http/HttpGetConfigHandlerTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/http/HttpGetConfigHandlerTest.java
index 8816e695e64..279f3a237e8 100644
--- a/configserver/src/test/java/com/yahoo/vespa/config/server/http/HttpGetConfigHandlerTest.java
+++ b/configserver/src/test/java/com/yahoo/vespa/config/server/http/HttpGetConfigHandlerTest.java
@@ -63,7 +63,7 @@ public class HttpGetConfigHandlerTest {
.withOrchestrator(new OrchestratorMock())
.withConfigserverConfig(configserverConfig)
.build();
- handler = new HttpGetConfigHandler(HttpGetConfigHandler.testOnlyContext(), tenantRepository);
+ handler = new HttpGetConfigHandler(HttpGetConfigHandler.testContext(), tenantRepository);
applicationRepository.deploy(testApp, prepareParams());
}
diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/http/HttpHandlerTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/http/HttpHandlerTest.java
index 8f092ec9d54..40671294b4c 100644
--- a/configserver/src/test/java/com/yahoo/vespa/config/server/http/HttpHandlerTest.java
+++ b/configserver/src/test/java/com/yahoo/vespa/config/server/http/HttpHandlerTest.java
@@ -45,7 +45,7 @@ public class HttpHandlerTest {
private static class HttpTestHandler extends HttpHandler {
private final RuntimeException exception;
HttpTestHandler(RuntimeException exception) {
- super(HttpHandler.testOnlyContext());
+ super(HttpHandler.testContext());
this.exception = exception;
}
diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/http/HttpListConfigsHandlerTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/http/HttpListConfigsHandlerTest.java
index 45c74f0d49f..520b4d0edc5 100644
--- a/configserver/src/test/java/com/yahoo/vespa/config/server/http/HttpListConfigsHandlerTest.java
+++ b/configserver/src/test/java/com/yahoo/vespa/config/server/http/HttpListConfigsHandlerTest.java
@@ -70,7 +70,7 @@ public class HttpListConfigsHandlerTest {
.build();
applicationRepository.deploy(testApp, prepareParams());
- HttpListConfigsHandler.Context ctx = HttpListConfigsHandler.testOnlyContext();
+ HttpListConfigsHandler.Context ctx = HttpListConfigsHandler.testContext();
handler = new HttpListConfigsHandler(ctx, tenantRepository);
namedHandler = new HttpListNamedConfigsHandler(ctx, tenantRepository);
}
diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/http/status/StatusHandlerTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/http/status/StatusHandlerTest.java
index 18fa307a9d3..ed739d73860 100644
--- a/configserver/src/test/java/com/yahoo/vespa/config/server/http/status/StatusHandlerTest.java
+++ b/configserver/src/test/java/com/yahoo/vespa/config/server/http/status/StatusHandlerTest.java
@@ -29,7 +29,7 @@ public class StatusHandlerTest {
public void require_that_handler_works() throws IOException {
ModelFactoryRegistry modelFactoryRegistry = new ModelFactoryRegistry(List.of(new VespaModelFactory(new NullConfigModelRegistry())));
ConfigserverConfig configserverConfig = new ConfigserverConfig.Builder().build();
- StatusHandler handler = new StatusHandler(StatusHandler.testOnlyContext(), modelFactoryRegistry, configserverConfig);
+ StatusHandler handler = new StatusHandler(StatusHandler.testContext(), modelFactoryRegistry, configserverConfig);
HttpResponse response = handler.handle(HttpRequest.createTestRequest("/status", GET));
JsonNode jsonNode = mapper.readTree(SessionHandlerTest.getRenderedString(response));
diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/http/v1/RoutingStatusApiHandlerTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/http/v1/RoutingStatusApiHandlerTest.java
index e2b45d33cbc..f389829a160 100644
--- a/configserver/src/test/java/com/yahoo/vespa/config/server/http/v1/RoutingStatusApiHandlerTest.java
+++ b/configserver/src/test/java/com/yahoo/vespa/config/server/http/v1/RoutingStatusApiHandlerTest.java
@@ -62,6 +62,22 @@ public class RoutingStatusApiHandlerTest {
}
@Test
+ public void get_deployment_status_v2() {
+ String response = responseAsString(executeRequest(Method.GET, "/routing/v2/status/", null));
+ assertEquals("{\"inactiveDeployments\":[],\"zoneActive\":true}", response);
+
+ // Set deployment out
+ executeRequest(Method.PUT, "/routing/v1/status/" + upstreamName + "?application=" + instance.serializedForm(), statusOut());
+ response = responseAsString(executeRequest(Method.GET, "/routing/v2/status/", null));
+ assertEquals("{\"inactiveDeployments\":[{\"upstreamName\":\"test-upstream-name\"}],\"zoneActive\":true}", response);
+
+ // Set zone out
+ executeRequest(Method.PUT, "/routing/v1/status/zone", null);
+ response = responseAsString(executeRequest(Method.GET, "/routing/v2/status/", null));
+ assertEquals("{\"inactiveDeployments\":[{\"upstreamName\":\"test-upstream-name\"}],\"zoneActive\":false}", response);
+ }
+
+ @Test
public void set_deployment_status() {
String response = responseAsString(executeRequest(Method.PUT, "/routing/v1/status/" + upstreamName + "?application=" + instance.serializedForm(),
statusOut()));
diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/ApplicationContentHandlerTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/ApplicationContentHandlerTest.java
index 322a2b924bd..1d891c0547c 100644
--- a/configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/ApplicationContentHandlerTest.java
+++ b/configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/ApplicationContentHandlerTest.java
@@ -69,7 +69,7 @@ public class ApplicationContentHandlerTest extends ContentHandlerTestBase {
.build();
applicationRepository.deploy(testApp, prepareParams(appId1));
- handler = new ApplicationHandler(ApplicationHandler.testOnlyContext(),
+ handler = new ApplicationHandler(ApplicationHandler.testContext(),
Zone.defaultZone(),
applicationRepository);
pathPrefix = createPath(appId1, Zone.defaultZone());
diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/ApplicationHandlerTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/ApplicationHandlerTest.java
index 04483e0191d..005dd715dd4 100644
--- a/configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/ApplicationHandlerTest.java
+++ b/configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/ApplicationHandlerTest.java
@@ -556,8 +556,8 @@ public class ApplicationHandlerTest {
{ // Known service
HttpResponse response = createResponse(new ServiceResponse(ServiceResponse.Status.ok,
- 3L,
- 3L,
+ 3,
+ 3,
true),
hostAndPort,
uri);
@@ -601,9 +601,9 @@ public class ApplicationHandlerTest {
{
HttpServiceListResponse response =
new HttpServiceListResponse(new ServiceListResponse(Map.of(createServiceInfo(hostname, port), 3L),
- requestUrl,
3L,
- 3L));
+ 3L),
+ requestUrl);
assertResponse("{\n" +
" \"services\": [\n" +
" {\n" +
@@ -635,9 +635,9 @@ public class ApplicationHandlerTest {
HttpServiceListResponse response =
new HttpServiceListResponse(new ServiceListResponse(serviceInfos,
- requestUrl,
4L,
- 3L));
+ 3L),
+ requestUrl);
assertResponse("{\n" +
" \"services\": [\n" +
" {\n" +
@@ -756,7 +756,7 @@ public class ApplicationHandlerTest {
"/environment/" + zone.environment().value() +
"/region/" + zone.region().value() +
"/instance/" + applicationId.instance().value() + "\"]";
- ListApplicationsHandler listApplicationsHandler = new ListApplicationsHandler(ListApplicationsHandler.testOnlyContext(),
+ ListApplicationsHandler listApplicationsHandler = new ListApplicationsHandler(ListApplicationsHandler.testContext(),
tenantRepository,
Zone.defaultZone());
ListApplicationsHandlerTest.assertResponse(listApplicationsHandler,
@@ -808,7 +808,7 @@ public class ApplicationHandlerTest {
}
private ApplicationHandler createApplicationHandler(ApplicationRepository applicationRepository) {
- return new ApplicationHandler(ApplicationHandler.testOnlyContext(), Zone.defaultZone(), applicationRepository);
+ return new ApplicationHandler(ApplicationHandler.testContext(), Zone.defaultZone(), applicationRepository);
}
private PrepareParams prepareParams(ApplicationId applicationId) {
diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/HostHandlerTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/HostHandlerTest.java
index 6bbbc451094..fbc5e87c329 100644
--- a/configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/HostHandlerTest.java
+++ b/configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/HostHandlerTest.java
@@ -62,7 +62,7 @@ public class HostHandlerTest {
.withOrchestrator(new OrchestratorMock())
.withConfigserverConfig(configserverConfig)
.build();
- handler = new HostHandler(HostHandler.testOnlyContext(), applicationRepository);
+ handler = new HostHandler(HostHandler.testContext(), applicationRepository);
}
@Test
diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/HttpGetConfigHandlerTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/HttpGetConfigHandlerTest.java
index 3d207f9f64a..9aae64cb884 100644
--- a/configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/HttpGetConfigHandlerTest.java
+++ b/configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/HttpGetConfigHandlerTest.java
@@ -72,7 +72,7 @@ public class HttpGetConfigHandlerTest {
.withOrchestrator(new OrchestratorMock())
.withConfigserverConfig(configserverConfig)
.build();
- handler = new HttpGetConfigHandler(HttpGetConfigHandler.testOnlyContext(), tenantRepository);
+ handler = new HttpGetConfigHandler(HttpGetConfigHandler.testContext(), tenantRepository);
applicationRepository.deploy(testApp, prepareParams());
}
diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/HttpListConfigsHandlerTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/HttpListConfigsHandlerTest.java
index 141f8a52f13..2ee1064f614 100644
--- a/configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/HttpListConfigsHandlerTest.java
+++ b/configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/HttpListConfigsHandlerTest.java
@@ -76,10 +76,10 @@ public class HttpListConfigsHandlerTest {
.withConfigserverConfig(configserverConfig)
.build();
applicationRepository.deploy(testApp, prepareParams());
- handler = new HttpListConfigsHandler(HttpListConfigsHandler.testOnlyContext(),
+ handler = new HttpListConfigsHandler(HttpListConfigsHandler.testContext(),
tenantRepository,
Zone.defaultZone());
- namedHandler = new HttpListNamedConfigsHandler(HttpListConfigsHandler.testOnlyContext(),
+ namedHandler = new HttpListNamedConfigsHandler(HttpListConfigsHandler.testContext(),
tenantRepository,
Zone.defaultZone());
}
diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/ListApplicationsHandlerTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/ListApplicationsHandlerTest.java
index e2ad65786a4..76790e6264d 100644
--- a/configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/ListApplicationsHandlerTest.java
+++ b/configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/ListApplicationsHandlerTest.java
@@ -55,7 +55,7 @@ public class ListApplicationsHandlerTest {
tenantRepository.addTenant(foobar);
applicationRepo = tenantRepository.getTenant(mytenant).getApplicationRepo();
applicationRepo2 = tenantRepository.getTenant(foobar).getApplicationRepo();
- handler = new ListApplicationsHandler(ListApplicationsHandler.testOnlyContext(),
+ handler = new ListApplicationsHandler(ListApplicationsHandler.testContext(),
tenantRepository,
new Zone(Environment.dev, RegionName.from("us-east")));
}
diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/SessionActiveHandlerTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/SessionActiveHandlerTest.java
index c6f84c2d6ae..ecb8d7603f6 100644
--- a/configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/SessionActiveHandlerTest.java
+++ b/configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/SessionActiveHandlerTest.java
@@ -164,7 +164,7 @@ public class SessionActiveHandlerTest {
}
private SessionActiveHandler createHandler() {
- return new SessionActiveHandler(SessionActiveHandler.testOnlyContext(),
+ return new SessionActiveHandler(SessionActiveHandler.testContext(),
applicationRepository,
Zone.defaultZone());
}
diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/SessionContentHandlerTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/SessionContentHandlerTest.java
index f13ec6cd5c8..ec96be0d0c8 100644
--- a/configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/SessionContentHandlerTest.java
+++ b/configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/SessionContentHandlerTest.java
@@ -183,7 +183,7 @@ public class SessionContentHandlerTest extends ContentHandlerTestBase {
private SessionContentHandler createHandler() {
return new SessionContentHandler(
- SessionContentHandler.testOnlyContext(),
+ SessionContentHandler.testContext(),
new ApplicationRepository.Builder()
.withTenantRepository(tenantRepository)
.withProvisioner(new MockProvisioner())
diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/SessionCreateHandlerTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/SessionCreateHandlerTest.java
index 4cb69ce5d20..702dd2792da 100644
--- a/configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/SessionCreateHandlerTest.java
+++ b/configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/SessionCreateHandlerTest.java
@@ -195,7 +195,7 @@ public class SessionCreateHandlerTest extends SessionHandlerTest {
}
private SessionCreateHandler createHandler() {
- return new SessionCreateHandler(SessionCreateHandler.testOnlyContext(),
+ return new SessionCreateHandler(SessionCreateHandler.testContext(),
applicationRepository,
configserverConfig);
}
diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/SessionPrepareHandlerTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/SessionPrepareHandlerTest.java
index 3c762b7c2e5..3d2e108a75e 100644
--- a/configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/SessionPrepareHandlerTest.java
+++ b/configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/SessionPrepareHandlerTest.java
@@ -1,8 +1,8 @@
// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.config.server.http.v2;
-import com.google.common.util.concurrent.UncheckedTimeoutException;
import com.yahoo.cloud.config.ConfigserverConfig;
+import com.yahoo.concurrent.UncheckedTimeoutException;
import com.yahoo.config.provision.ApplicationId;
import com.yahoo.config.provision.ApplicationLockException;
import com.yahoo.config.provision.ApplicationName;
@@ -247,7 +247,7 @@ public class SessionPrepareHandlerTest extends SessionHandlerTest {
public void test_out_of_capacity_response() throws IOException {
long sessionId = applicationRepository.createSession(applicationId(), timeoutBudget, app);
String exceptionMessage = "Out of capacity";
- FailingSessionPrepareHandler handler = new FailingSessionPrepareHandler(SessionPrepareHandler.testOnlyContext(),
+ FailingSessionPrepareHandler handler = new FailingSessionPrepareHandler(SessionPrepareHandler.testContext(),
applicationRepository,
configserverConfig,
new OutOfCapacityException(exceptionMessage));
@@ -262,7 +262,7 @@ public class SessionPrepareHandlerTest extends SessionHandlerTest {
public void test_that_nullpointerexception_gives_internal_server_error() throws IOException {
long sessionId = applicationRepository.createSession(applicationId(), timeoutBudget, app);
String exceptionMessage = "nullpointer thrown in test handler";
- FailingSessionPrepareHandler handler = new FailingSessionPrepareHandler(SessionPrepareHandler.testOnlyContext(),
+ FailingSessionPrepareHandler handler = new FailingSessionPrepareHandler(SessionPrepareHandler.testContext(),
applicationRepository,
configserverConfig,
new NullPointerException(exceptionMessage));
@@ -277,7 +277,7 @@ public class SessionPrepareHandlerTest extends SessionHandlerTest {
public void test_application_lock_failure() throws IOException {
String exceptionMessage = "Timed out after waiting PT1M to acquire lock '/provision/v1/locks/foo/bar/default'";
long sessionId = applicationRepository.createSession(applicationId(), timeoutBudget, app);
- FailingSessionPrepareHandler handler = new FailingSessionPrepareHandler(SessionPrepareHandler.testOnlyContext(),
+ FailingSessionPrepareHandler handler = new FailingSessionPrepareHandler(SessionPrepareHandler.testContext(),
applicationRepository,
configserverConfig,
new ApplicationLockException(new UncheckedTimeoutException(exceptionMessage)));
@@ -314,7 +314,7 @@ public class SessionPrepareHandlerTest extends SessionHandlerTest {
}
private SessionHandler createHandler() {
- return new SessionPrepareHandler(SessionPrepareHandler.testOnlyContext(), applicationRepository, configserverConfig);
+ return new SessionPrepareHandler(SessionPrepareHandler.testContext(), applicationRepository, configserverConfig);
}
private HttpResponse request(HttpRequest.Method put, long l) {
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 402e2576591..ee35ca572e1 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
@@ -19,7 +19,6 @@ import com.yahoo.config.provision.RegionName;
import com.yahoo.config.provision.TenantName;
import com.yahoo.config.provision.Zone;
import com.yahoo.vespa.config.ConfigPayload;
-import com.yahoo.vespa.flags.Flags;
import com.yahoo.vespa.flags.InMemoryFlagSource;
import com.yahoo.vespa.model.VespaModel;
import org.junit.Test;
@@ -43,7 +42,6 @@ import static com.yahoo.cloud.config.LbServicesConfig.Tenants.Applications.Endpo
import static com.yahoo.cloud.config.LbServicesConfig.Tenants.Applications.Endpoints.Scope.Enum.application;
import static com.yahoo.cloud.config.LbServicesConfig.Tenants.Applications.Endpoints.Scope.Enum.global;
import static com.yahoo.cloud.config.LbServicesConfig.Tenants.Applications.Endpoints.Scope.Enum.zone;
-import static com.yahoo.config.model.api.container.ContainerServiceType.QRSERVER;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
@@ -56,8 +54,6 @@ import static org.junit.Assume.assumeFalse;
@RunWith(Parameterized.class)
public class LbServicesProducerTest {
- private static final String rotation1 = "rotation-1";
- private static final String rotation2 = "rotation-2";
private static final Set<ContainerEndpoint> endpoints = Set.of(
new ContainerEndpoint("mydisc", ApplicationClusterEndpoint.Scope.global, List.of("rotation-1", "rotation-2")),
new ContainerEndpoint("mydisc", ApplicationClusterEndpoint.Scope.application, List.of("app-endpoint"))
@@ -91,20 +87,6 @@ public class LbServicesProducerTest {
}
@Test
- public void testConfigAliases() {
- Map<TenantName, Set<ApplicationInfo>> testModel = createTestModel(new DeployState.Builder());
- LbServicesConfig conf = getLbServicesConfig(Zone.defaultZone(), testModel);
- LbServicesConfig.Tenants.Applications.Hosts.Services services =
- conf.tenants("foo").applications("foo:prod:default:default").hosts("foo.foo.yahoo.com").services(QRSERVER.serviceName);
- assertEquals(1, services.servicealiases().size());
- assertEquals(2, services.endpointaliases().size());
-
- assertEquals("service1", services.servicealiases(0));
- assertEquals("foo1.bar1.com", services.endpointaliases(0));
- assertEquals("foo2.bar2.com", services.endpointaliases(1));
- }
-
- @Test
public void testConfigActiveRotation() {
{
RegionName regionName = RegionName.from("us-east-1");
@@ -119,18 +101,6 @@ public class LbServicesProducerTest {
}
}
- @Test
- public void generate_non_mtls_endpoints_from_feature_flag() {
- RegionName regionName = RegionName.from("us-east-1");
-
- LbServicesConfig conf = createModelAndGetLbServicesConfig(regionName);
- assertTrue(conf.tenants("foo").applications("foo:prod:" + regionName.value() + ":default").generateNonMtlsEndpoint());
-
- flagSource.withBooleanFlag(Flags.GENERATE_NON_MTLS_ENDPOINT.id(), false);
- conf = createModelAndGetLbServicesConfig(regionName);
- assertFalse(conf.tenants("foo").applications("foo:prod:" + regionName.value() + ":default").generateNonMtlsEndpoint());
- }
-
private LbServicesConfig createModelAndGetLbServicesConfig(RegionName regionName) {
Zone zone = new Zone(Environment.prod, regionName);
Map<TenantName, Set<ApplicationInfo>> testModel = createTestModel(new DeployState.Builder().zone(zone));
@@ -153,20 +123,12 @@ public class LbServicesProducerTest {
.properties(new TestProperties().setHostedVespa(true)));
RegionName regionName = RegionName.from("us-east-1");
LbServicesConfig config = getLbServicesConfig(new Zone(Environment.prod, regionName), testModel);
- LbServicesConfig.Tenants.Applications.Hosts.Services services = config
- .tenants("foo")
- .applications("foo:prod:" + regionName.value() + ":default")
- .hosts("foo.foo.yahoo.com")
- .services(QRSERVER.serviceName);
-
- assertTrue(services.servicealiases().contains("service1"));
- assertTrue("Missing endpoints in list: " + services.endpointaliases(), services.endpointaliases().containsAll(List.of("foo1.bar1.com", "foo2.bar2.com", rotation1, rotation2)));
List<Endpoints> endpointList = config.tenants("foo").applications("foo:prod:" + regionName.value() + ":default").endpoints();
- // Expect 4 zone endpoints (2 suffixes), 2 global endpoints and 1 application endpoint
- assertEquals(7, endpointList.size());
+ // Expect 2 zone endpoints (2 suffixes), 2 global endpoints and 1 application endpoint
+ assertEquals(5, endpointList.size());
List<Endpoints> zoneEndpoints = endpointList.stream().filter(e -> e.scope() == zone).collect(Collectors.toList());
- assertEquals(4, zoneEndpoints.size());
+ assertEquals(2, zoneEndpoints.size());
assertTrue(zoneEndpoints.stream()
.filter(e -> e.routingMethod() == sharedLayer4)
.map(Endpoints::dnsName).collect(Collectors.toList())
@@ -186,16 +148,11 @@ public class LbServicesProducerTest {
assertContainsEndpoint(applicationEndpoints, "app-endpoint", "mydisc", application, sharedLayer4, 1, List.of("foo.foo.yahoo.com"));
}
-
@Test
public void testRoutingConfigForTesterApplication() {
assumeFalse(useGlobalServiceId);
Map<TenantName, Set<ApplicationInfo>> testModel = createTestModel(new DeployState.Builder());
- LbServicesConfig conf = getLbServicesConfig(Zone.defaultZone(), testModel);
- LbServicesConfig.Tenants.Applications.Hosts.Services services = conf.tenants("foo").applications("foo:prod:default:default").hosts("foo.foo.yahoo.com").services(QRSERVER.serviceName);
- assertEquals(1, services.servicealiases().size());
- assertEquals(2, services.endpointaliases().size());
// No config for tester application
assertNull(getLbServicesConfig(Zone.defaultZone(), testModel)
@@ -231,7 +188,7 @@ public class LbServicesProducerTest {
TenantName baz = TenantName.from("baz");
tMap.put(foo, createTestApplications(foo, deployStateBuilder));
tMap.put(bar, createTestApplications(bar, deployStateBuilder));
- tMap.put(bar, createTestApplications(baz, deployStateBuilder));
+ tMap.put(baz, createTestApplications(baz, deployStateBuilder));
return tMap;
}
diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/rpc/security/MultiTenantRpcAuthorizerTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/rpc/security/MultiTenantRpcAuthorizerTest.java
index 854abee91f5..30d3dcffc30 100644
--- a/configserver/src/test/java/com/yahoo/vespa/config/server/rpc/security/MultiTenantRpcAuthorizerTest.java
+++ b/configserver/src/test/java/com/yahoo/vespa/config/server/rpc/security/MultiTenantRpcAuthorizerTest.java
@@ -116,7 +116,7 @@ public class MultiTenantRpcAuthorizerTest {
new ConfigKey<>(LbServicesConfig.CONFIG_DEF_NAME, "*", LbServicesConfig.CONFIG_DEF_NAMESPACE),
HOSTNAME);
- exceptionRule.expectMessage("Node with type 'tenant' is not allowed to access global config [name=lb-services,namespace=cloud.config,configId=*]");
+ exceptionRule.expectMessage("Node with type 'tenant' is not allowed to access global config [name=cloud.config.lb-services,configId=*]");
exceptionRule.expectCause(instanceOf(AuthorizationException.class));
authorizer.authorizeConfigRequest(configRequest)