summaryrefslogtreecommitdiffstats
path: root/configserver
diff options
context:
space:
mode:
authorJon Marius Venstad <jonmv@users.noreply.github.com>2019-05-27 13:41:34 +0200
committerGitHub <noreply@github.com>2019-05-27 13:41:34 +0200
commit7a99d5daa193d0281f93c94649a6916a1f50a5ad (patch)
treec3c0f251f7b139e13b18808bbb77eb8a12ea121a /configserver
parentdb1b509e6c6c7ca0bb5ea9605e5934f697b77083 (diff)
parent3ce870109811b6833ef5e9930fb86c2776332b16 (diff)
Merge pull request #9549 from vespa-engine/jvenstad/zk-watcher-serialisation
Jvenstad/zk watcher serialisation
Diffstat (limited to 'configserver')
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/GlobalComponentRegistry.java6
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/InjectedGlobalComponentRegistry.java20
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/application/TenantApplications.java54
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/session/LocalSessionRepo.java21
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/session/LocalSessionStateWatcher.java11
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/session/RemoteSessionRepo.java82
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/session/RemoteSessionStateWatcher.java14
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/tenant/Tenant.java21
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/tenant/TenantBuilder.java20
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/tenant/TenantRepository.java50
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/tenant/TenantRequestHandler.java11
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/TestComponentRegistry.java23
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/application/TenantApplicationsTest.java3
-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/SessionCreateHandlerTest.java2
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/SessionPrepareHandlerTest.java2
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/maintenance/TenantsMaintainerTest.java1
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/session/LocalSessionRepoTest.java8
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/session/LocalSessionTest.java4
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/session/RemoteSessionRepoTest.java10
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/session/SessionPreparerTest.java2
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/tenant/TenantRequestHandlerTest.java2
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/tenant/TenantTest.java2
23 files changed, 226 insertions, 145 deletions
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/GlobalComponentRegistry.java b/configserver/src/main/java/com/yahoo/vespa/config/server/GlobalComponentRegistry.java
index 2f53973f5af..d420c3f21fe 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/GlobalComponentRegistry.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/GlobalComponentRegistry.java
@@ -2,8 +2,10 @@
package com.yahoo.vespa.config.server;
import com.yahoo.cloud.config.ConfigserverConfig;
+import com.yahoo.concurrent.StripedExecutor;
import com.yahoo.config.model.api.ConfigDefinitionRepo;
import com.yahoo.config.provision.Provisioner;
+import com.yahoo.config.provision.TenantName;
import com.yahoo.config.provision.Zone;
import com.yahoo.vespa.config.server.application.PermanentApplicationPackage;
import com.yahoo.vespa.config.server.host.HostRegistries;
@@ -17,6 +19,7 @@ import com.yahoo.vespa.flags.FlagSource;
import java.time.Clock;
import java.util.Optional;
+import java.util.concurrent.ExecutorService;
/**
* Interface representing all global config server components used within the config server.
@@ -40,6 +43,7 @@ public interface GlobalComponentRegistry {
Zone getZone();
Clock getClock();
ConfigServerDB getConfigServerDB();
+ StripedExecutor<TenantName> getZkWatcherExecutor();
FlagSource getFlagSource();
-
+ ExecutorService getZkCacheExecutor();
}
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/InjectedGlobalComponentRegistry.java b/configserver/src/main/java/com/yahoo/vespa/config/server/InjectedGlobalComponentRegistry.java
index f8e53350e5c..ff76afd1c98 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/InjectedGlobalComponentRegistry.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/InjectedGlobalComponentRegistry.java
@@ -3,8 +3,11 @@ package com.yahoo.vespa.config.server;
import com.google.inject.Inject;
import com.yahoo.cloud.config.ConfigserverConfig;
+import com.yahoo.concurrent.StripedExecutor;
+import com.yahoo.concurrent.ThreadFactoryFactory;
import com.yahoo.config.model.api.ConfigDefinitionRepo;
import com.yahoo.config.provision.Provisioner;
+import com.yahoo.config.provision.TenantName;
import com.yahoo.config.provision.Zone;
import com.yahoo.vespa.config.server.application.PermanentApplicationPackage;
import com.yahoo.vespa.config.server.host.HostRegistries;
@@ -14,12 +17,15 @@ import com.yahoo.vespa.config.server.provision.HostProvisionerProvider;
import com.yahoo.vespa.config.server.rpc.RpcServer;
import com.yahoo.vespa.config.server.session.SessionPreparer;
import com.yahoo.vespa.config.server.tenant.TenantListener;
+import com.yahoo.vespa.config.server.tenant.TenantRepository;
import com.yahoo.vespa.config.server.zookeeper.ConfigCurator;
import com.yahoo.vespa.curator.Curator;
import com.yahoo.vespa.flags.FlagSource;
import java.time.Clock;
import java.util.Optional;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
/**
* Registry containing all the "static"/"global" components in a config server in one place.
@@ -42,6 +48,8 @@ public class InjectedGlobalComponentRegistry implements GlobalComponentRegistry
private final Zone zone;
private final ConfigServerDB configServerDB;
private final FlagSource flagSource;
+ private final StripedExecutor<TenantName> zkWatcherExecutor;
+ private final ExecutorService zkCacheExecutor;
@SuppressWarnings("WeakerAccess")
@Inject
@@ -74,6 +82,8 @@ public class InjectedGlobalComponentRegistry implements GlobalComponentRegistry
this.zone = zone;
this.configServerDB = configServerDB;
this.flagSource = flagSource;
+ this.zkWatcherExecutor = new StripedExecutor<>();
+ this.zkCacheExecutor = Executors.newFixedThreadPool(1, ThreadFactoryFactory.getThreadFactory(TenantRepository.class.getName()));
}
@Override
@@ -116,5 +126,15 @@ public class InjectedGlobalComponentRegistry implements GlobalComponentRegistry
public ConfigServerDB getConfigServerDB() { return configServerDB; }
@Override
+ public StripedExecutor<TenantName> getZkWatcherExecutor() {
+ return zkWatcherExecutor;
+ }
+
+ @Override
public FlagSource getFlagSource() { return flagSource; }
+
+ @Override
+ public ExecutorService getZkCacheExecutor() {
+ return zkCacheExecutor;
+ }
}
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 91016e3c91b..bc33336a79b 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
@@ -1,6 +1,7 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.config.server.application;
+import com.yahoo.concurrent.StripedExecutor;
import com.yahoo.concurrent.ThreadFactoryFactory;
import com.yahoo.config.provision.ApplicationId;
import com.yahoo.config.provision.TenantName;
@@ -8,6 +9,7 @@ import com.yahoo.log.LogLevel;
import com.yahoo.path.Path;
import com.yahoo.text.Utf8;
import com.yahoo.transaction.Transaction;
+import com.yahoo.vespa.config.server.GlobalComponentRegistry;
import com.yahoo.vespa.config.server.ReloadHandler;
import com.yahoo.vespa.config.server.tenant.TenantRepository;
import com.yahoo.vespa.curator.Curator;
@@ -25,6 +27,7 @@ import java.util.Optional;
import java.util.OptionalLong;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.logging.Logger;
@@ -48,26 +51,27 @@ public class TenantApplications {
private final Curator curator;
private final Path applicationsPath;
private final Path locksPath;
- // One thread pool for all instances of this class
- private static final ExecutorService pathChildrenExecutor =
- Executors.newCachedThreadPool(ThreadFactoryFactory.getDaemonThreadFactory(TenantApplications.class.getName()));
private final Curator.DirectoryCache directoryCache;
private final ReloadHandler reloadHandler;
private final Map<ApplicationId, Lock> locks;
+ private final Executor zkWatcherExecutor;
- private TenantApplications(Curator curator, ReloadHandler reloadHandler, TenantName tenant) {
+ private TenantApplications(Curator curator, ReloadHandler reloadHandler, TenantName tenant,
+ ExecutorService zkCacheExecutor, StripedExecutor<TenantName> zkWatcherExecutor) {
this.curator = curator;
this.applicationsPath = TenantRepository.getApplicationsPath(tenant);
this.locksPath = TenantRepository.getLocksPath(tenant);
this.locks = new ConcurrentHashMap<>(2);
this.reloadHandler = reloadHandler;
- this.directoryCache = curator.createDirectoryCache(applicationsPath.getAbsolute(), false, false, pathChildrenExecutor);
+ this.zkWatcherExecutor = command -> zkWatcherExecutor.execute(tenant, command);
+ this.directoryCache = curator.createDirectoryCache(applicationsPath.getAbsolute(), false, false, zkCacheExecutor);
this.directoryCache.start();
this.directoryCache.addListener(this::childEvent);
}
- public static TenantApplications create(Curator curator, ReloadHandler reloadHandler, TenantName tenant) {
- return new TenantApplications(curator, reloadHandler, tenant);
+ public static TenantApplications create(GlobalComponentRegistry registry, ReloadHandler reloadHandler, TenantName tenant) {
+ return new TenantApplications(registry.getCurator(), reloadHandler, tenant,
+ registry.getZkCacheExecutor(), registry.getZkWatcherExecutor());
}
/**
@@ -179,23 +183,25 @@ public class TenantApplications {
}
private void childEvent(CuratorFramework client, PathChildrenCacheEvent event) {
- switch (event.getType()) {
- case CHILD_ADDED:
- applicationAdded(ApplicationId.fromSerializedForm(Path.fromString(event.getData().getPath()).getName()));
- break;
- // Event CHILD_REMOVED will be triggered on all config servers if deleteApplication() above is called on one of them
- case CHILD_REMOVED:
- applicationRemoved(ApplicationId.fromSerializedForm(Path.fromString(event.getData().getPath()).getName()));
- break;
- case CHILD_UPDATED:
- // do nothing, application just got redeployed
- break;
- default:
- break;
- }
- // We may have lost events and may need to remove applications.
- // New applications are added when session is added, not here. See RemoteSessionRepo.
- removeUnusedApplications();
+ zkWatcherExecutor.execute(() -> {
+ switch (event.getType()) {
+ case CHILD_ADDED:
+ applicationAdded(ApplicationId.fromSerializedForm(Path.fromString(event.getData().getPath()).getName()));
+ break;
+ // Event CHILD_REMOVED will be triggered on all config servers if deleteApplication() above is called on one of them
+ case CHILD_REMOVED:
+ applicationRemoved(ApplicationId.fromSerializedForm(Path.fromString(event.getData().getPath()).getName()));
+ break;
+ case CHILD_UPDATED:
+ // do nothing, application just got redeployed
+ break;
+ default:
+ break;
+ }
+ // We may have lost events and may need to remove applications.
+ // New applications are added when session is added, not here. See RemoteSessionRepo.
+ removeUnusedApplications();
+ });
}
private void applicationRemoved(ApplicationId applicationId) {
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/session/LocalSessionRepo.java b/configserver/src/main/java/com/yahoo/vespa/config/server/session/LocalSessionRepo.java
index acfd81b33bf..f6d73f33504 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/session/LocalSessionRepo.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/session/LocalSessionRepo.java
@@ -1,9 +1,13 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.config.server.session;
+import com.yahoo.concurrent.InThreadExecutorService;
+import com.yahoo.concurrent.StripedExecutor;
+import com.yahoo.config.provision.TenantName;
import com.yahoo.log.LogLevel;
import com.yahoo.path.Path;
import com.yahoo.transaction.NestedTransaction;
+import com.yahoo.vespa.config.server.GlobalComponentRegistry;
import com.yahoo.vespa.config.server.deploy.TenantFileSystemDirs;
import com.yahoo.vespa.config.server.tenant.TenantRepository;
import com.yahoo.vespa.config.server.zookeeper.ConfigCurator;
@@ -12,10 +16,12 @@ import com.yahoo.vespa.curator.Curator;
import java.io.File;
import java.io.FilenameFilter;
import java.time.Clock;
+import java.time.Duration;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
import java.util.logging.Logger;
@@ -33,23 +39,24 @@ public class LocalSessionRepo extends SessionRepo<LocalSession> {
private final long sessionLifetime; // in seconds
private final Clock clock;
private final Curator curator;
+ private final Executor zkWatcherExecutor;
- public LocalSessionRepo(TenantFileSystemDirs tenantFileSystemDirs, LocalSessionLoader loader,
- Clock clock, long sessionLifeTime, Curator curator) {
- this(clock, curator, sessionLifeTime);
+ public LocalSessionRepo(TenantName tenantName, GlobalComponentRegistry registry, TenantFileSystemDirs tenantFileSystemDirs, LocalSessionLoader loader) {
+ this(registry.getClock(), registry.getCurator(), registry.getConfigserverConfig().sessionLifetime(),
+ command -> registry.getZkWatcherExecutor().execute(tenantName, command));
loadSessions(tenantFileSystemDirs.sessionsPath(), loader);
}
// Constructor public only for testing
public LocalSessionRepo(Clock clock, Curator curator) {
- this(clock, curator, TimeUnit.DAYS.toMillis(1));
+ this(clock, curator, Duration.ofDays(1).toMillis(), Runnable::run);
}
- // Constructor public only for testing
- private LocalSessionRepo(Clock clock, Curator curator, long sessionLifetime) {
+ private LocalSessionRepo(Clock clock, Curator curator, long sessionLifetime, Executor zkWatcherExecutor) {
this.clock = clock;
this.curator = curator;
this.sessionLifetime = sessionLifetime;
+ this.zkWatcherExecutor = zkWatcherExecutor;
}
@Override
@@ -58,7 +65,7 @@ public class LocalSessionRepo extends SessionRepo<LocalSession> {
Path sessionsPath = TenantRepository.getSessionsPath(session.getTenantName());
long sessionId = session.getSessionId();
Curator.FileCache fileCache = curator.createFileCache(sessionsPath.append(String.valueOf(sessionId)).append(ConfigCurator.SESSIONSTATE_ZK_SUBPATH).getAbsolute(), false);
- sessionStateWatchers.put(sessionId, new LocalSessionStateWatcher(fileCache, session, this));
+ sessionStateWatchers.put(sessionId, new LocalSessionStateWatcher(fileCache, session, this, zkWatcherExecutor));
}
private void loadSessions(File applicationsDir, LocalSessionLoader loader) {
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/session/LocalSessionStateWatcher.java b/configserver/src/main/java/com/yahoo/vespa/config/server/session/LocalSessionStateWatcher.java
index 37082888d70..53a472c2b67 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/session/LocalSessionStateWatcher.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/session/LocalSessionStateWatcher.java
@@ -2,11 +2,11 @@
package com.yahoo.vespa.config.server.session;
import com.yahoo.concurrent.ThreadFactoryFactory;
+import com.yahoo.config.provision.TenantName;
import com.yahoo.log.LogLevel;
import com.yahoo.text.Utf8;
import com.yahoo.vespa.curator.Curator;
import org.apache.curator.framework.recipes.cache.ChildData;
-import org.apache.curator.framework.recipes.cache.NodeCacheListener;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
@@ -21,17 +21,18 @@ import java.util.logging.Logger;
public class LocalSessionStateWatcher {
private static final Logger log = Logger.getLogger(LocalSessionStateWatcher.class.getName());
- // One thread pool for all instances of this class
- private static final Executor executor = Executors.newCachedThreadPool(ThreadFactoryFactory.getDaemonThreadFactory(LocalSessionStateWatcher.class.getName()));
private final Curator.FileCache fileCache;
private final LocalSession session;
private final LocalSessionRepo localSessionRepo;
+ private final Executor zkWatcherExecutor;
- LocalSessionStateWatcher(Curator.FileCache fileCache, LocalSession session, LocalSessionRepo localSessionRepo) {
+ LocalSessionStateWatcher(Curator.FileCache fileCache, LocalSession session,
+ LocalSessionRepo localSessionRepo, Executor zkWatcherExecutor) {
this.fileCache = fileCache;
this.session = session;
this.localSessionRepo = localSessionRepo;
+ this.zkWatcherExecutor = zkWatcherExecutor;
this.fileCache.start();
this.fileCache.addListener(this::nodeChanged);
}
@@ -60,7 +61,7 @@ public class LocalSessionStateWatcher {
}
public void nodeChanged() {
- executor.execute(() -> {
+ zkWatcherExecutor.execute(() -> {
try {
ChildData data = fileCache.getCurrentData();
if (data != null) {
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/session/RemoteSessionRepo.java b/configserver/src/main/java/com/yahoo/vespa/config/server/session/RemoteSessionRepo.java
index 27e1a7e43b4..24eb862c528 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/session/RemoteSessionRepo.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/session/RemoteSessionRepo.java
@@ -3,14 +3,18 @@ package com.yahoo.vespa.config.server.session;
import com.google.common.collect.HashMultiset;
import com.google.common.collect.Multiset;
+import com.yahoo.concurrent.InThreadExecutorService;
+import com.yahoo.concurrent.StripedExecutor;
import com.yahoo.concurrent.ThreadFactoryFactory;
import com.yahoo.config.provision.ApplicationId;
import com.yahoo.config.provision.TenantName;
import com.yahoo.log.LogLevel;
import com.yahoo.path.Path;
+import com.yahoo.vespa.config.server.GlobalComponentRegistry;
import com.yahoo.vespa.config.server.ReloadHandler;
import com.yahoo.vespa.config.server.application.TenantApplications;
import com.yahoo.vespa.config.server.monitoring.MetricUpdater;
+import com.yahoo.vespa.config.server.monitoring.Metrics;
import com.yahoo.vespa.config.server.tenant.TenantRepository;
import com.yahoo.vespa.config.server.zookeeper.ConfigCurator;
import com.yahoo.vespa.curator.Curator;
@@ -28,6 +32,7 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.logging.Level;
@@ -45,9 +50,6 @@ import java.util.stream.Collectors;
public class RemoteSessionRepo extends SessionRepo<RemoteSession> {
private static final Logger log = Logger.getLogger(RemoteSessionRepo.class.getName());
- // One thread pool for all instances of this class
- private static final ExecutorService pathChildrenExecutor =
- Executors.newCachedThreadPool(ThreadFactoryFactory.getDaemonThreadFactory(RemoteSessionRepo.class.getName()));
private final Curator curator;
private final Path sessionsPath;
@@ -59,31 +61,26 @@ public class RemoteSessionRepo extends SessionRepo<RemoteSession> {
private final FlagSource flagSource;
private final Curator.DirectoryCache directoryCache;
private final TenantApplications applicationRepo;
+ private final Executor zkWatcherExecutor;
- /**
- * @param curator a {@link Curator} instance.
- * @param remoteSessionFactory a {@link com.yahoo.vespa.config.server.session.RemoteSessionFactory}
- * @param reloadHandler a {@link com.yahoo.vespa.config.server.ReloadHandler}
- * @param tenantName a {@link TenantName} instance.
- * @param applicationRepo a {@link TenantApplications} instance.
- */
- public RemoteSessionRepo(Curator curator,
+ public RemoteSessionRepo(GlobalComponentRegistry registry,
RemoteSessionFactory remoteSessionFactory,
ReloadHandler reloadHandler,
TenantName tenantName,
- TenantApplications applicationRepo,
- MetricUpdater metricUpdater,
- FlagSource flagSource) {
- this.curator = curator;
+ TenantApplications applicationRepo) {
+
+ this.curator = registry.getCurator();
this.sessionsPath = TenantRepository.getSessionsPath(tenantName);
this.applicationRepo = applicationRepo;
this.remoteSessionFactory = remoteSessionFactory;
this.reloadHandler = reloadHandler;
this.tenantName = tenantName;
- this.metrics = metricUpdater;
- this.flagSource = flagSource;
+ this.metrics = registry.getMetrics().getOrCreateMetricUpdater(Metrics.createDimensions(tenantName));
+ this.flagSource = registry.getFlagSource();
+ StripedExecutor<TenantName> zkWatcherExecutor = registry.getZkWatcherExecutor();
+ this.zkWatcherExecutor = command -> zkWatcherExecutor.execute(tenantName, command);
initializeSessions();
- this.directoryCache = curator.createDirectoryCache(sessionsPath.getAbsolute(), false, false, pathChildrenExecutor);
+ this.directoryCache = curator.createDirectoryCache(sessionsPath.getAbsolute(), false, false, registry.getZkCacheExecutor());
this.directoryCache.addListener(this::childEvent);
this.directoryCache.start();
}
@@ -99,6 +96,7 @@ public class RemoteSessionRepo extends SessionRepo<RemoteSession> {
this.directoryCache = null;
this.applicationRepo = null;
this.flagSource = new InMemoryFlagSource();
+ this.zkWatcherExecutor = Runnable::run;
}
public List<Long> getSessions() {
@@ -168,7 +166,7 @@ public class RemoteSessionRepo extends SessionRepo<RemoteSession> {
Curator.FileCache fileCache = curator.createFileCache(sessionPath.append(ConfigCurator.SESSIONSTATE_ZK_SUBPATH).getAbsolute(), false);
fileCache.addListener(this::nodeChanged);
loadSessionIfActive(session);
- sessionStateWatchers.put(sessionId, new RemoteSessionStateWatcher(fileCache, reloadHandler, session, metrics));
+ sessionStateWatchers.put(sessionId, new RemoteSessionStateWatcher(fileCache, reloadHandler, session, metrics, zkWatcherExecutor));
addSession(session);
metrics.incAddedSessions();
} catch (Exception e) {
@@ -208,31 +206,35 @@ public class RemoteSessionRepo extends SessionRepo<RemoteSession> {
}
private void nodeChanged() {
- Multiset<Session.Status> sessionMetrics = HashMultiset.create();
- for (RemoteSession session : listSessions()) {
- sessionMetrics.add(session.getStatus());
- }
- metrics.setNewSessions(sessionMetrics.count(Session.Status.NEW));
- metrics.setPreparedSessions(sessionMetrics.count(Session.Status.PREPARE));
- metrics.setActivatedSessions(sessionMetrics.count(Session.Status.ACTIVATE));
- metrics.setDeactivatedSessions(sessionMetrics.count(Session.Status.DEACTIVATE));
+ zkWatcherExecutor.execute(() -> {
+ Multiset<Session.Status> sessionMetrics = HashMultiset.create();
+ for (RemoteSession session : listSessions()) {
+ sessionMetrics.add(session.getStatus());
+ }
+ metrics.setNewSessions(sessionMetrics.count(Session.Status.NEW));
+ metrics.setPreparedSessions(sessionMetrics.count(Session.Status.PREPARE));
+ metrics.setActivatedSessions(sessionMetrics.count(Session.Status.ACTIVATE));
+ metrics.setDeactivatedSessions(sessionMetrics.count(Session.Status.DEACTIVATE));
+ });
}
@SuppressWarnings("unused")
private void childEvent(CuratorFramework ignored, PathChildrenCacheEvent event) {
- log.log(LogLevel.DEBUG, () -> "Got child event: " + event);
- switch (event.getType()) {
- case CHILD_ADDED:
- sessionsChanged();
- synchronizeOnNew(getSessionListFromDirectoryCache(Collections.singletonList(event.getData())));
- break;
- case CHILD_REMOVED:
- sessionsChanged();
- break;
- case CONNECTION_RECONNECTED:
- sessionsChanged();
- break;
- }
+ zkWatcherExecutor.execute(() -> {
+ log.log(LogLevel.DEBUG, () -> "Got child event: " + event);
+ switch (event.getType()) {
+ case CHILD_ADDED:
+ sessionsChanged();
+ synchronizeOnNew(getSessionListFromDirectoryCache(Collections.singletonList(event.getData())));
+ break;
+ case CHILD_REMOVED:
+ sessionsChanged();
+ break;
+ case CONNECTION_RECONNECTED:
+ sessionsChanged();
+ break;
+ }
+ });
}
private void synchronizeOnNew(List<Long> sessionList) {
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/session/RemoteSessionStateWatcher.java b/configserver/src/main/java/com/yahoo/vespa/config/server/session/RemoteSessionStateWatcher.java
index ef59e28f458..653a2616cbe 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/session/RemoteSessionStateWatcher.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/session/RemoteSessionStateWatcher.java
@@ -1,17 +1,16 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.config.server.session;
-import com.yahoo.concurrent.ThreadFactoryFactory;
+import com.yahoo.concurrent.StripedExecutor;
+import com.yahoo.config.provision.TenantName;
import com.yahoo.log.LogLevel;
import com.yahoo.text.Utf8;
import com.yahoo.vespa.config.server.ReloadHandler;
import com.yahoo.vespa.config.server.monitoring.MetricUpdater;
import com.yahoo.vespa.curator.Curator;
import org.apache.curator.framework.recipes.cache.ChildData;
-import org.apache.curator.framework.recipes.cache.NodeCacheListener;
import java.util.concurrent.Executor;
-import java.util.concurrent.Executors;
import java.util.logging.Logger;
/**
@@ -24,24 +23,25 @@ public class RemoteSessionStateWatcher {
private static final Logger log = Logger.getLogger(RemoteSessionStateWatcher.class.getName());
// One thread pool for all instances of this class
- private static final Executor executor = Executors.newCachedThreadPool(ThreadFactoryFactory.getDaemonThreadFactory(RemoteSessionStateWatcher.class.getName()));
private final Curator.FileCache fileCache;
private final ReloadHandler reloadHandler;
private final RemoteSession session;
private final MetricUpdater metrics;
-
+ private final Executor zkWatcherExecutor;
RemoteSessionStateWatcher(Curator.FileCache fileCache,
ReloadHandler reloadHandler,
RemoteSession session,
- MetricUpdater metrics) {
+ MetricUpdater metrics,
+ Executor zkWatcherExecutor) {
this.fileCache = fileCache;
this.reloadHandler = reloadHandler;
this.session = session;
this.metrics = metrics;
this.fileCache.start();
this.fileCache.addListener(this::nodeChanged);
+ this.zkWatcherExecutor = zkWatcherExecutor;
}
private void sessionChanged(Session.Status status) {
@@ -73,7 +73,7 @@ public class RemoteSessionStateWatcher {
}
public void nodeChanged() {
- executor.execute(() -> {
+ zkWatcherExecutor.execute(() -> {
try {
ChildData data = fileCache.getCurrentData();
if (data != null) {
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/tenant/Tenant.java b/configserver/src/main/java/com/yahoo/vespa/config/server/tenant/Tenant.java
index 88e71d7ddd1..0aed3977625 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/tenant/Tenant.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/tenant/Tenant.java
@@ -142,15 +142,20 @@ public class Tenant implements TenantHandlerProvider {
}
/**
- * Closes any watchers, thread pools that may react to changes in tenant state, and removes any state
- * in filesystem and zookeeper
+ * Closes any watchers, thread pools that may react to changes in tenant state,
+ * and removes any session data in filesystem and zookeeper.
+ * Called by watchers as a reaction to {@link #delete()}.
*/
- public void close() {
- tenantFileSystemDirs.delete();
- remoteSessionRepo.close();
- applicationRepo.close();
- localSessionRepo.deleteAllSessions();
- curator.delete(path);
+ void close() {
+ tenantFileSystemDirs.delete(); // Deletes all local files.
+ remoteSessionRepo.close(); // Closes watchers and clears memory.
+ applicationRepo.close(); // Closes watchers.
+ localSessionRepo.deleteAllSessions(); // Closes watchers, clears memory, and deletes some local files and ZK session state.
+ }
+
+ /** Deletes the tenant tree from ZooKeeper (application and session status for the tenant) and triggers {@link #close()}. */
+ void delete() {
+ curator.delete(path); // Deletes tenant ZK tree: applications and sessions.
}
}
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/tenant/TenantBuilder.java b/configserver/src/main/java/com/yahoo/vespa/config/server/tenant/TenantBuilder.java
index 9b5da267c6e..861b2f91c8f 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/tenant/TenantBuilder.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/tenant/TenantBuilder.java
@@ -98,9 +98,7 @@ public class TenantBuilder {
private void createLocalSessionRepo() {
if (localSessionRepo == null) {
- localSessionRepo = new LocalSessionRepo(tenantFileSystemDirs, localSessionLoader, componentRegistry.getClock(),
- componentRegistry.getConfigserverConfig().sessionLifetime(),
- componentRegistry.getCurator());
+ localSessionRepo = new LocalSessionRepo(tenant, componentRegistry, tenantFileSystemDirs, localSessionLoader);
}
}
@@ -129,8 +127,7 @@ public class TenantBuilder {
tenant,
Collections.singletonList(componentRegistry.getReloadListener()),
ConfigResponseFactory.create(componentRegistry.getConfigserverConfig()),
- componentRegistry.getHostRegistries(),
- componentRegistry.getCurator());
+ componentRegistry);
if (hostValidator == null) {
this.hostValidator = impl;
}
@@ -149,13 +146,12 @@ public class TenantBuilder {
private void createRemoteSessionRepo() {
if (remoteSessionRepo == null) {
- remoteSessionRepo = new RemoteSessionRepo(componentRegistry.getCurator(),
- remoteSessionFactory,
- reloadHandler,
- tenant,
- applicationRepo,
- componentRegistry.getMetrics().getOrCreateMetricUpdater(Metrics.createDimensions(tenant)),
- componentRegistry.getFlagSource());
+ remoteSessionRepo = new RemoteSessionRepo(componentRegistry,
+ remoteSessionFactory,
+ reloadHandler,
+ tenant,
+ applicationRepo);
+
}
}
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 53d01fdf933..ad2472add89 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
@@ -4,6 +4,7 @@ package com.yahoo.vespa.config.server.tenant;
import com.google.common.collect.ImmutableSet;
import com.google.inject.Inject;
import com.yahoo.cloud.config.ConfigserverConfig;
+import com.yahoo.concurrent.StripedExecutor;
import com.yahoo.concurrent.ThreadFactoryFactory;
import com.yahoo.config.provision.ApplicationId;
import com.yahoo.config.provision.TenantName;
@@ -73,7 +74,8 @@ public class TenantRepository {
private final Curator curator;
private final MetricUpdater metricUpdater;
- private final ExecutorService pathChildrenExecutor = Executors.newFixedThreadPool(1, ThreadFactoryFactory.getThreadFactory(TenantRepository.class.getName()));
+ private final ExecutorService zkCacheExecutor;
+ private final StripedExecutor<TenantName> zkWatcherExecutor;
private final ExecutorService bootstrapExecutor;
private final ScheduledExecutorService checkForRemovedApplicationsService = new ScheduledThreadPoolExecutor(1);
private final Optional<Curator.DirectoryCache> directoryCache;
@@ -104,6 +106,8 @@ public class TenantRepository {
this.curator = globalComponentRegistry.getCurator();
metricUpdater = globalComponentRegistry.getMetrics().getOrCreateMetricUpdater(Collections.emptyMap());
this.tenantListeners.add(globalComponentRegistry.getTenantListener());
+ this.zkCacheExecutor = globalComponentRegistry.getZkCacheExecutor();
+ this.zkWatcherExecutor = globalComponentRegistry.getZkWatcherExecutor();
curator.framework().getConnectionStateListenable().addListener(this::stateChanged);
curator.create(tenantsPath);
@@ -112,7 +116,7 @@ public class TenantRepository {
curator.create(vespaPath);
if (useZooKeeperWatchForTenantChanges) {
- this.directoryCache = Optional.of(curator.createDirectoryCache(tenantsPath.getAbsolute(), false, false, pathChildrenExecutor));
+ this.directoryCache = Optional.of(curator.createDirectoryCache(tenantsPath.getAbsolute(), false, false, zkCacheExecutor));
this.directoryCache.get().start();
this.directoryCache.get().addListener(this::childEvent);
} else {
@@ -147,22 +151,19 @@ public class TenantRepository {
return curator.getChildren(tenantsPath).stream().map(TenantName::from).collect(Collectors.toSet());
}
- private synchronized void updateTenants() {
+ /** Public for testing. */
+ public synchronized void updateTenants() {
Set<TenantName> allTenants = readTenantsFromZooKeeper(curator);
log.log(LogLevel.DEBUG, "Create tenants, tenants found in zookeeper: " + allTenants);
- checkForRemovedTenants(allTenants);
- allTenants.stream().filter(tenantName -> ! tenants.containsKey(tenantName)).forEach(this::createTenant);
+ for (TenantName tenantName : Set.copyOf(tenants.keySet()))
+ if ( ! allTenants.contains(tenantName))
+ zkWatcherExecutor.execute(tenantName, () -> closeTenant(tenantName));
+ for (TenantName tenantName : allTenants)
+ if ( ! tenants.containsKey(tenantName))
+ zkWatcherExecutor.execute(tenantName, () -> createTenant(tenantName));
metricUpdater.setTenants(tenants.size());
}
- private void checkForRemovedTenants(Set<TenantName> newTenants) {
- for (TenantName tenantName : ImmutableSet.copyOf(tenants.keySet())) {
- if (!newTenants.contains(tenantName)) {
- deleteTenant(tenantName);
- }
- }
- }
-
private void bootstrapTenants() {
// Keep track of tenants created
Map<TenantName, Future<?>> futures = new HashMap<>();
@@ -273,19 +274,25 @@ public class TenantRepository {
* Removes the given tenant from ZooKeeper and filesystem. Assumes that tenant exists.
*
* @param name name of the tenant
- * @return this TenantRepository instance
*/
- public synchronized TenantRepository deleteTenant(TenantName name) {
+ public synchronized void deleteTenant(TenantName name) {
if (name.equals(DEFAULT_TENANT))
throw new IllegalArgumentException("Deleting 'default' tenant is not allowed");
+ if ( ! tenants.containsKey(name))
+ throw new IllegalArgumentException("Deleting '" + name + "' failed, tenant does not exist");
+
log.log(LogLevel.INFO, "Deleting tenant '" + name + "'");
+ tenants.get(name).delete();
+ }
+
+ public synchronized void closeTenant(TenantName name) {
Tenant tenant = tenants.remove(name);
- if (tenant == null) {
- throw new IllegalArgumentException("Deleting '" + name + "' failed, tenant does not exist");
- }
+ if (tenant == null)
+ throw new IllegalArgumentException("Closing '" + name + "' failed, tenant does not exist");
+
+ log.log(LogLevel.INFO, "Closing tenant '" + name + "'");
notifyRemovedTenant(name);
tenant.close();
- return this;
}
// For unit testing
@@ -353,9 +360,10 @@ public class TenantRepository {
public void close() {
directoryCache.ifPresent(Curator.DirectoryCache::close);
try {
- pathChildrenExecutor.shutdown();
+ zkCacheExecutor.shutdown();
checkForRemovedApplicationsService.shutdown();
- pathChildrenExecutor.awaitTermination(50, TimeUnit.SECONDS);
+ zkWatcherExecutor.shutdownAndWait();
+ zkCacheExecutor.awaitTermination(50, TimeUnit.SECONDS);
checkForRemovedApplicationsService.awaitTermination(50, TimeUnit.SECONDS);
}
catch (InterruptedException e) {
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/tenant/TenantRequestHandler.java b/configserver/src/main/java/com/yahoo/vespa/config/server/tenant/TenantRequestHandler.java
index 65b92558216..2f9a5eb9277 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/tenant/TenantRequestHandler.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/tenant/TenantRequestHandler.java
@@ -2,6 +2,7 @@
package com.yahoo.vespa.config.server.tenant;
import com.yahoo.component.Version;
+import com.yahoo.concurrent.StripedExecutor;
import com.yahoo.config.FileReference;
import com.yahoo.config.provision.ApplicationId;
import com.yahoo.config.provision.TenantName;
@@ -9,6 +10,7 @@ import com.yahoo.log.LogLevel;
import com.yahoo.vespa.config.ConfigKey;
import com.yahoo.vespa.config.GetConfigRequest;
import com.yahoo.vespa.config.protocol.ConfigResponse;
+import com.yahoo.vespa.config.server.GlobalComponentRegistry;
import com.yahoo.vespa.config.server.NotFoundException;
import com.yahoo.vespa.config.server.ReloadHandler;
import com.yahoo.vespa.config.server.ReloadListener;
@@ -33,6 +35,7 @@ import java.util.LinkedHashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;
+import java.util.concurrent.ExecutorService;
import static java.util.stream.Collectors.toSet;
@@ -60,15 +63,15 @@ public class TenantRequestHandler implements RequestHandler, ReloadHandler, Host
TenantName tenant,
List<ReloadListener> reloadListeners,
ConfigResponseFactory responseFactory,
- HostRegistries hostRegistries,
- Curator curator) { // TODO jvenstad: Merge this class with TenantApplications, and straighten this out.
+ GlobalComponentRegistry registry) { // TODO jvenstad: Merge this class with TenantApplications, and straighten this out.
this.metrics = metrics;
this.tenant = tenant;
this.reloadListeners = List.copyOf(reloadListeners);
this.responseFactory = responseFactory;
this.tenantMetricUpdater = metrics.getOrCreateMetricUpdater(Metrics.createDimensions(tenant));
- this.hostRegistry = hostRegistries.createApplicationHostRegistry(tenant);
- this.applications = TenantApplications.create(curator, this, tenant);
+ this.hostRegistry = registry.getHostRegistries().createApplicationHostRegistry(tenant);
+ this.applications = TenantApplications.create(registry, this, tenant);
+
}
/**
diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/TestComponentRegistry.java b/configserver/src/test/java/com/yahoo/vespa/config/server/TestComponentRegistry.java
index e369d5bd3bb..62685734a47 100644
--- a/configserver/src/test/java/com/yahoo/vespa/config/server/TestComponentRegistry.java
+++ b/configserver/src/test/java/com/yahoo/vespa/config/server/TestComponentRegistry.java
@@ -3,9 +3,13 @@ package com.yahoo.vespa.config.server;
import com.google.common.io.Files;
import com.yahoo.cloud.config.ConfigserverConfig;
+import com.yahoo.concurrent.InThreadExecutorService;
+import com.yahoo.concurrent.StripedExecutor;
+import com.yahoo.concurrent.ThreadFactoryFactory;
import com.yahoo.config.model.NullConfigModelRegistry;
import com.yahoo.config.model.api.ConfigDefinitionRepo;
import com.yahoo.config.provision.Provisioner;
+import com.yahoo.config.provision.TenantName;
import com.yahoo.config.provision.Zone;
import com.yahoo.vespa.config.server.application.PermanentApplicationPackage;
import com.yahoo.vespa.config.server.host.HostRegistries;
@@ -17,6 +21,7 @@ import com.yahoo.vespa.config.server.session.MockFileDistributionFactory;
import com.yahoo.vespa.config.server.session.SessionPreparer;
import com.yahoo.vespa.config.server.tenant.MockTenantListener;
import com.yahoo.vespa.config.server.tenant.TenantListener;
+import com.yahoo.vespa.config.server.tenant.TenantRepository;
import com.yahoo.vespa.config.server.tenant.TenantRequestHandlerTest;
import com.yahoo.vespa.config.server.zookeeper.ConfigCurator;
import com.yahoo.vespa.curator.Curator;
@@ -28,6 +33,8 @@ import com.yahoo.vespa.model.VespaModelFactory;
import java.time.Clock;
import java.util.Collections;
import java.util.Optional;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
/**
@@ -51,6 +58,8 @@ public class TestComponentRegistry implements GlobalComponentRegistry {
private final Zone zone;
private final Clock clock;
private final ConfigServerDB configServerDB;
+ private final StripedExecutor<TenantName> zkWatcherExecutor;
+ private final ExecutorService zkCacheExecutor;
private TestComponentRegistry(Curator curator, ConfigCurator configCurator, Metrics metrics,
ModelFactoryRegistry modelFactoryRegistry,
@@ -81,6 +90,8 @@ public class TestComponentRegistry implements GlobalComponentRegistry {
this.zone = zone;
this.clock = clock;
this.configServerDB = new ConfigServerDB(configserverConfig);
+ this.zkWatcherExecutor = new StripedExecutor<>(new InThreadExecutorService());
+ this.zkCacheExecutor = new InThreadExecutorService();
}
public static class Builder {
@@ -90,6 +101,7 @@ public class TestComponentRegistry implements GlobalComponentRegistry {
private ConfigserverConfig configserverConfig = new ConfigserverConfig(
new ConfigserverConfig.Builder()
.configServerDBDir(Files.createTempDir().getAbsolutePath())
+ .sessionLifetime(5)
.configDefinitionsDir(Files.createTempDir().getAbsolutePath()));
private ConfigDefinitionRepo defRepo = new StaticConfigDefinitionRepo();
private TenantRequestHandlerTest.MockReloadListener reloadListener = new TenantRequestHandlerTest.MockReloadListener();
@@ -194,9 +206,20 @@ public class TestComponentRegistry implements GlobalComponentRegistry {
public Clock getClock() { return clock;}
@Override
public ConfigServerDB getConfigServerDB() { return configServerDB;}
+
+ @Override
+ public StripedExecutor<TenantName> getZkWatcherExecutor() {
+ return zkWatcherExecutor;
+ }
+
@Override
public FlagSource getFlagSource() { return new InMemoryFlagSource(); }
+ @Override
+ public ExecutorService getZkCacheExecutor() {
+ return zkCacheExecutor;
+ }
+
public FileDistributionFactory getFileDistributionFactory() { return fileDistributionFactory; }
}
diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/application/TenantApplicationsTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/application/TenantApplicationsTest.java
index ac7ff1e85c5..e3335dded4c 100644
--- a/configserver/src/test/java/com/yahoo/vespa/config/server/application/TenantApplicationsTest.java
+++ b/configserver/src/test/java/com/yahoo/vespa/config/server/application/TenantApplicationsTest.java
@@ -6,6 +6,7 @@ import com.yahoo.config.provision.TenantName;
import com.yahoo.text.Utf8;
import com.yahoo.vespa.config.server.MockReloadHandler;
+import com.yahoo.vespa.config.server.TestComponentRegistry;
import com.yahoo.vespa.config.server.tenant.TenantRepository;
import com.yahoo.vespa.curator.Curator;
import com.yahoo.vespa.curator.mock.MockCurator;
@@ -115,7 +116,7 @@ public class TenantApplicationsTest {
}
private TenantApplications createZKAppRepo(MockReloadHandler reloadHandler) {
- return TenantApplications.create(curator, reloadHandler, tenantName);
+ return TenantApplications.create(new TestComponentRegistry.Builder().curator(curator).build(), reloadHandler, tenantName);
}
private static ApplicationId createApplicationId(String name) {
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 a62a2841995..087a8c0cb8c 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
@@ -105,7 +105,7 @@ public class SessionActiveHandlerTest extends SessionHandlerTest {
.modelFactoryRegistry(new ModelFactoryRegistry(Collections.singletonList(modelFactory)))
.build();
tenantRepository = new TenantRepository(componentRegistry, false);
- applicationRepo = TenantApplications.create(curator, new MockReloadHandler(), tenantName);
+ applicationRepo = TenantApplications.create(componentRegistry, new MockReloadHandler(), tenantName);
localRepo = new LocalSessionRepo(clock, curator);
pathPrefix = "/application/v2/tenant/" + tenantName + "/session/";
hostProvisioner = 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 0946ef3992c..81dd41ac714 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
@@ -72,7 +72,7 @@ public class SessionCreateHandlerTest extends SessionHandlerTest {
@Before
public void setupRepo() {
Curator curator = new MockCurator();
- applicationRepo = TenantApplications.create(curator, new MockReloadHandler(), tenant);
+ applicationRepo = TenantApplications.create(componentRegistry, new MockReloadHandler(), tenant);
localSessionRepo = new LocalSessionRepo(Clock.systemUTC(), curator);
tenantRepository = new TenantRepository(componentRegistry, false);
sessionFactory = new MockSessionFactory();
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 7b0b00caa8b..a264b440af8 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
@@ -88,7 +88,7 @@ public class SessionPrepareHandlerTest extends SessionHandlerTest {
.withSessionFactory(new MockSessionFactory())
.withLocalSessionRepo(localRepo)
.withRemoteSessionRepo(remoteSessionRepo)
- .withApplicationRepo(TenantApplications.create(curator, new MockReloadHandler(), tenant));
+ .withApplicationRepo(TenantApplications.create(componentRegistry, new MockReloadHandler(), tenant));
tenantRepository.addTenant(tenantBuilder);
}
diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/maintenance/TenantsMaintainerTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/maintenance/TenantsMaintainerTest.java
index a2f52bc5321..fdc6ffeacf0 100644
--- a/configserver/src/test/java/com/yahoo/vespa/config/server/maintenance/TenantsMaintainerTest.java
+++ b/configserver/src/test/java/com/yahoo/vespa/config/server/maintenance/TenantsMaintainerTest.java
@@ -37,6 +37,7 @@ public class TenantsMaintainerTest {
assertNotNull(tenantRepository.getTenant(shouldNotBeDeleted));
new TenantsMaintainer(applicationRepository, tester.curator(), Duration.ofDays(1)).run();
+ tenantRepository.updateTenants();
// One tenant should now have been deleted
assertNull(tenantRepository.getTenant(shouldBeDeleted));
diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/session/LocalSessionRepoTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/session/LocalSessionRepoTest.java
index 3626c6269cc..d3f364e30ac 100644
--- a/configserver/src/test/java/com/yahoo/vespa/config/server/session/LocalSessionRepoTest.java
+++ b/configserver/src/test/java/com/yahoo/vespa/config/server/session/LocalSessionRepoTest.java
@@ -46,7 +46,6 @@ public class LocalSessionRepoTest {
}
private void setupSessions(TenantName tenantName, boolean createInitialSessions) throws Exception {
- GlobalComponentRegistry globalComponentRegistry = new TestComponentRegistry.Builder().curator(new MockCurator()).build();
TenantFileSystemDirs tenantFileSystemDirs = new TenantFileSystemDirs(temporaryFolder.newFolder(), tenantName);
if (createInitialSessions) {
IOUtils.copyDirectory(testApp, new File(tenantFileSystemDirs.sessionsPath(), "1"));
@@ -54,11 +53,14 @@ public class LocalSessionRepoTest {
IOUtils.copyDirectory(testApp, new File(tenantFileSystemDirs.sessionsPath(), "3"));
}
clock = new ManualClock(Instant.ofEpochSecond(1));
+ GlobalComponentRegistry globalComponentRegistry = new TestComponentRegistry.Builder().curator(new MockCurator())
+ .clock(clock)
+ .build();
LocalSessionLoader loader = new SessionFactoryImpl(globalComponentRegistry,
- TenantApplications.create(new MockCurator(), new MockReloadHandler(), tenantName),
+ TenantApplications.create(globalComponentRegistry, new MockReloadHandler(), tenantName),
tenantFileSystemDirs, new HostRegistry<>(),
tenantName);
- repo = new LocalSessionRepo(tenantFileSystemDirs, loader, clock, 5, globalComponentRegistry.getCurator());
+ repo = new LocalSessionRepo(tenantName, globalComponentRegistry, tenantFileSystemDirs, loader);
}
@Test
diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/session/LocalSessionTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/session/LocalSessionTest.java
index d7f0914c4cf..96caff9b3a7 100644
--- a/configserver/src/test/java/com/yahoo/vespa/config/server/session/LocalSessionTest.java
+++ b/configserver/src/test/java/com/yahoo/vespa/config/server/session/LocalSessionTest.java
@@ -16,7 +16,7 @@ import com.yahoo.path.Path;
import com.yahoo.slime.Slime;
import com.yahoo.transaction.NestedTransaction;
import com.yahoo.vespa.config.server.MockReloadHandler;
-import com.yahoo.vespa.config.server.SuperModelGenerationCounter;
+import com.yahoo.vespa.config.server.TestComponentRegistry;
import com.yahoo.vespa.config.server.application.TenantApplications;
import com.yahoo.vespa.config.server.deploy.DeployHandlerLogger;
import com.yahoo.vespa.config.server.deploy.TenantFileSystemDirs;
@@ -192,7 +192,7 @@ public class LocalSessionTest {
zkClient.write(Collections.singletonMap(new Version(0, 0, 0), new MockFileRegistry()));
File sessionDir = new File(tenantFileSystemDirs.sessionsPath(), String.valueOf(sessionId));
sessionDir.createNewFile();
- TenantApplications applications = TenantApplications.create(curator, new MockReloadHandler(), tenant);
+ TenantApplications applications = TenantApplications.create(new TestComponentRegistry.Builder().curator(curator).build(), new MockReloadHandler(), tenant);
applications.createApplication(zkc.readApplicationId());
return new LocalSession(tenant, sessionId, preparer,
new SessionContext(
diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/session/RemoteSessionRepoTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/session/RemoteSessionRepoTest.java
index 9dda653dbc1..83183a27666 100644
--- a/configserver/src/test/java/com/yahoo/vespa/config/server/session/RemoteSessionRepoTest.java
+++ b/configserver/src/test/java/com/yahoo/vespa/config/server/session/RemoteSessionRepoTest.java
@@ -10,6 +10,7 @@ import com.yahoo.config.provision.TenantName;
import com.yahoo.path.Path;
import com.yahoo.text.Utf8;
+import com.yahoo.vespa.config.server.GlobalComponentRegistry;
import com.yahoo.vespa.config.server.MockReloadHandler;
import com.yahoo.vespa.config.server.TestComponentRegistry;
import com.yahoo.vespa.config.server.application.TenantApplications;
@@ -100,11 +101,12 @@ public class RemoteSessionRepoTest {
public void testBadApplicationRepoOnActivate() {
long sessionId = 3L;
TenantName mytenant = TenantName.from("mytenant");
- TenantApplications applicationRepo = TenantApplications.create(curator, new MockReloadHandler(), mytenant);
+ GlobalComponentRegistry registry = new TestComponentRegistry.Builder().curator(curator).build();
+ TenantApplications applicationRepo = TenantApplications.create(registry, new MockReloadHandler(), mytenant);
curator.set(TenantRepository.getApplicationsPath(mytenant).append("mytenant:appX:default"), new byte[0]); // Invalid data
- Tenant tenant = TenantBuilder.create(new TestComponentRegistry.Builder().curator(curator).build(), mytenant)
- .withApplicationRepo(applicationRepo)
- .build();
+ Tenant tenant = TenantBuilder.create(registry, mytenant)
+ .withApplicationRepo(applicationRepo)
+ .build();
curator.create(TenantRepository.getSessionsPath(mytenant));
remoteSessionRepo = tenant.getRemoteSessionRepo();
assertThat(remoteSessionRepo.listSessions().size(), is(0));
diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/session/SessionPreparerTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/session/SessionPreparerTest.java
index b80149859cb..072dcf0e26f 100644
--- a/configserver/src/test/java/com/yahoo/vespa/config/server/session/SessionPreparerTest.java
+++ b/configserver/src/test/java/com/yahoo/vespa/config/server/session/SessionPreparerTest.java
@@ -217,7 +217,7 @@ public class SessionPreparerTest {
return new SessionContext(app,
new SessionZooKeeperClient(curator, sessionsPath),
app.getAppDir(),
- TenantApplications.create(curator, new MockReloadHandler(), TenantName.from("tenant")),
+ TenantApplications.create(componentRegistry, new MockReloadHandler(), TenantName.from("tenant")),
new HostRegistry<>(),
flagSource);
}
diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/tenant/TenantRequestHandlerTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/tenant/TenantRequestHandlerTest.java
index 6aa5aa7cd70..4275dc7e16a 100644
--- a/configserver/src/test/java/com/yahoo/vespa/config/server/tenant/TenantRequestHandlerTest.java
+++ b/configserver/src/test/java/com/yahoo/vespa/config/server/tenant/TenantRequestHandlerTest.java
@@ -93,11 +93,11 @@ public class TenantRequestHandlerTest {
Metrics sh = Metrics.createTestMetrics();
List<ReloadListener> listeners = new ArrayList<>();
listeners.add(listener);
- server = new TenantRequestHandler(sh, tenant, listeners, new UncompressedConfigResponseFactory(), new HostRegistries(), curator);
componentRegistry = new TestComponentRegistry.Builder()
.curator(curator)
.modelFactoryRegistry(createRegistry())
.build();
+ server = new TenantRequestHandler(sh, tenant, listeners, new UncompressedConfigResponseFactory(), componentRegistry);
}
private void feedApp(File appDir, long sessionId, ApplicationId appId, boolean internalRedeploy) throws IOException {
diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/tenant/TenantTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/tenant/TenantTest.java
index baab250a508..e140dae3650 100644
--- a/configserver/src/test/java/com/yahoo/vespa/config/server/tenant/TenantTest.java
+++ b/configserver/src/test/java/com/yahoo/vespa/config/server/tenant/TenantTest.java
@@ -38,7 +38,7 @@ public class TenantTest {
TenantRepository tenantRepository = new TenantRepository(componentRegistry, false);
TenantName tenantName = TenantName.from(name);
TenantBuilder tenantBuilder = TenantBuilder.create(componentRegistry, tenantName)
- .withApplicationRepo(TenantApplications.create(new MockCurator(), new MockReloadHandler(), tenantName));
+ .withApplicationRepo(TenantApplications.create(componentRegistry, new MockReloadHandler(), tenantName));
tenantRepository.addTenant(tenantBuilder);
return tenantRepository.getTenant(tenantName);
}