diff options
author | Jon Marius Venstad <venstad@gmail.com> | 2019-02-26 19:35:07 +0100 |
---|---|---|
committer | Jon Marius Venstad <venstad@gmail.com> | 2019-02-26 19:35:07 +0100 |
commit | a666339feaccc25f136614ad710d586645e7e941 (patch) | |
tree | 3eb334aaa74257e36838acbac0925e20a4abbb8e /configserver | |
parent | 2da5e9556bc6114031b6e8d9e6c8632d23df8ebb (diff) |
Reduce heterogeneity by inlining TenantApplications, and some small fixes
Diffstat (limited to 'configserver')
20 files changed, 206 insertions, 379 deletions
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 82231fbf5d8..2c4d3d99408 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,32 +1,109 @@ // 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.google.common.collect.ImmutableSet; +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.text.Utf8; import com.yahoo.transaction.Transaction; +import com.yahoo.vespa.config.server.ReloadHandler; +import com.yahoo.vespa.config.server.tenant.TenantRepository; +import com.yahoo.vespa.curator.Curator; +import com.yahoo.vespa.curator.transaction.CuratorOperations; +import com.yahoo.vespa.curator.transaction.CuratorTransaction; +import org.apache.curator.framework.CuratorFramework; +import org.apache.curator.framework.recipes.cache.PathChildrenCacheEvent; +import java.util.ArrayList; import java.util.List; +import java.util.Optional; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.logging.Logger; /** - * The applications of a tenant + * The applications of a tenant, backed by ZooKeeper. + * + * Each application is stored as a single node under /config/v2/tenants/<tenant>/applications/<applications>, + * named the same as the application id and containing the id of the session storing the content of the application. * * @author Ulf Lilleengen */ -public interface TenantApplications { +public class TenantApplications { + + private static final Logger log = Logger.getLogger(TenantApplications.class.getName()); + + private final Curator curator; + private final Path applicationsPath; + // 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 TenantName tenant; + + private TenantApplications(Curator curator, Path applicationsPath, ReloadHandler reloadHandler, TenantName tenant) { + this.curator = curator; + this.applicationsPath = applicationsPath; + curator.create(applicationsPath); + this.reloadHandler = reloadHandler; + this.tenant = tenant; + this.directoryCache = curator.createDirectoryCache(applicationsPath.getAbsolute(), false, false, pathChildrenExecutor); + this.directoryCache.start(); + this.directoryCache.addListener(this::childEvent); + } + + public static TenantApplications create(Curator curator, ReloadHandler reloadHandler, TenantName tenant) { + try { + return new TenantApplications(curator, TenantRepository.getApplicationsPath(tenant), reloadHandler, tenant); + } catch (Exception e) { + throw new RuntimeException(TenantRepository.logPre(tenant) + "Error creating application repo", e); + } + } /** * List the active applications of a tenant in this config server. * - * @return a list of {@link com.yahoo.config.provision.ApplicationId}s that are active. + * @return a list of {@link ApplicationId}s that are active. */ - List<ApplicationId> listApplications(); + public List<ApplicationId> listApplications() { + try { + List<String> appNodes = curator.framework().getChildren().forPath(applicationsPath.getAbsolute()); + List<ApplicationId> applicationIds = new ArrayList<>(); + for (String appNode : appNodes) { + parseApplication(appNode).ifPresent(applicationIds::add); + } + return applicationIds; + } catch (Exception e) { + throw new RuntimeException(TenantRepository.logPre(tenant)+"Unable to list applications", e); + } + } + + private Optional<ApplicationId> parseApplication(String appNode) { + try { + return Optional.of(ApplicationId.fromSerializedForm(appNode)); + } catch (IllegalArgumentException e) { + log.log(LogLevel.INFO, TenantRepository.logPre(tenant)+"Unable to parse application with id '" + appNode + "', ignoring."); + return Optional.empty(); + } + } /** * Register active application and adds it to the repo. If it already exists it is overwritten. * - * @param applicationId An {@link com.yahoo.config.provision.ApplicationId} that represents an active application. + * @param applicationId An {@link ApplicationId} that represents an active application. * @param sessionId Id of the session containing the application package for this id. */ - Transaction createPutApplicationTransaction(ApplicationId applicationId, long sessionId); + public Transaction createPutApplicationTransaction(ApplicationId applicationId, long sessionId) { + if (listApplications().contains(applicationId)) { + return new CuratorTransaction(curator).add(CuratorOperations.setData(applicationsPath.append(applicationId.serializedForm()).getAbsolute(), Utf8.toAsciiBytes(sessionId))); + } else { + return new CuratorTransaction(curator).add(CuratorOperations.create(applicationsPath.append(applicationId.serializedForm()).getAbsolute(), Utf8.toAsciiBytes(sessionId))); + } + } /** * Return the stored session id for a given application. @@ -35,24 +112,68 @@ public interface TenantApplications { * @return session id of given application id. * @throws IllegalArgumentException if the application does not exist */ - long getSessionIdForApplication(ApplicationId applicationId); + public long getSessionIdForApplication(ApplicationId applicationId) { + String path = applicationsPath.append(applicationId.serializedForm()).getAbsolute(); + try { + return Long.parseLong(Utf8.toString(curator.framework().getData().forPath(path))); + } catch (Exception e) { + throw new IllegalArgumentException(TenantRepository.logPre(applicationId) + "Unable to read the session id from '" + path + "'", e); + } + } /** * Returns a transaction which deletes this application * * @param applicationId an {@link ApplicationId} to delete. */ - Transaction deleteApplication(ApplicationId applicationId); + public CuratorTransaction deleteApplication(ApplicationId applicationId) { + Path path = applicationsPath.append(applicationId.serializedForm()); + return CuratorTransaction.from(CuratorOperations.delete(path.getAbsolute()), curator); + } /** - * Removes unused applications - * - */ - void removeUnusedApplications(); + * Closes the application repo. Once a repo has been closed, it should not be used again. + */ + public void close() { + directoryCache.close(); + } + + 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(); + } + + private void applicationRemoved(ApplicationId applicationId) { + reloadHandler.removeApplication(applicationId); + log.log(LogLevel.INFO, TenantRepository.logPre(applicationId) + "Application removed: " + applicationId); + } + + private void applicationAdded(ApplicationId applicationId) { + log.log(LogLevel.DEBUG, TenantRepository.logPre(applicationId) + "Application added: " + applicationId); + } /** - * Closes the application repo. Once a repo has been closed, it should not be used again. + * Removes unused applications + * */ - void close(); + public void removeUnusedApplications() { + ImmutableSet<ApplicationId> activeApplications = ImmutableSet.copyOf(listApplications()); + reloadHandler.removeApplicationsExcept(activeApplications); + } } diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/application/ZKTenantApplications.java b/configserver/src/main/java/com/yahoo/vespa/config/server/application/ZKTenantApplications.java deleted file mode 100644 index 466df60d688..00000000000 --- a/configserver/src/main/java/com/yahoo/vespa/config/server/application/ZKTenantApplications.java +++ /dev/null @@ -1,160 +0,0 @@ -// 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.google.common.collect.ImmutableSet; -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.text.Utf8; -import com.yahoo.transaction.Transaction; -import com.yahoo.vespa.config.server.ReloadHandler; -import com.yahoo.vespa.config.server.tenant.TenantRepository; -import com.yahoo.vespa.curator.Curator; -import com.yahoo.vespa.curator.transaction.CuratorOperations; -import com.yahoo.vespa.curator.transaction.CuratorTransaction; -import org.apache.curator.framework.CuratorFramework; -import org.apache.curator.framework.recipes.cache.PathChildrenCacheEvent; -import org.apache.curator.framework.recipes.cache.PathChildrenCacheListener; - -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.logging.Logger; - -/** - * The applications of a tenant, backed by ZooKeeper. - * Each application is stored as a single node under /config/v2/tenants/<tenant>/applications/<applications>, - * named the same as the application id and containing the id of the session storing the content of the application. - * - * @author Ulf Lilleengen - */ -// TODO: Merge into interface and separate out curator layer instead -public class ZKTenantApplications implements TenantApplications, PathChildrenCacheListener { - - private static final Logger log = Logger.getLogger(ZKTenantApplications.class.getName()); - - private final Curator curator; - private final Path applicationsPath; - // One thread pool for all instances of this class - private static final ExecutorService pathChildrenExecutor = - Executors.newCachedThreadPool(ThreadFactoryFactory.getDaemonThreadFactory(ZKTenantApplications.class.getName())); - private final Curator.DirectoryCache directoryCache; - private final ReloadHandler reloadHandler; - private final TenantName tenant; - - private ZKTenantApplications(Curator curator, Path applicationsPath, ReloadHandler reloadHandler, TenantName tenant) { - this.curator = curator; - this.applicationsPath = applicationsPath; - curator.create(applicationsPath); - this.reloadHandler = reloadHandler; - this.tenant = tenant; - this.directoryCache = curator.createDirectoryCache(applicationsPath.getAbsolute(), false, false, pathChildrenExecutor); - this.directoryCache.start(); - this.directoryCache.addListener(this); - } - - public static TenantApplications create(Curator curator, ReloadHandler reloadHandler, TenantName tenant) { - try { - return new ZKTenantApplications(curator, TenantRepository.getApplicationsPath(tenant), reloadHandler, tenant); - } catch (Exception e) { - throw new RuntimeException(TenantRepository.logPre(tenant) + "Error creating application repo", e); - } - } - - private long readSessionId(ApplicationId appId, String appNode) { - String path = applicationsPath.append(appNode).getAbsolute(); - try { - return Long.parseLong(Utf8.toString(curator.framework().getData().forPath(path))); - } catch (Exception e) { - throw new IllegalArgumentException(TenantRepository.logPre(appId) + "Unable to read the session id from '" + path + "'", e); - } - } - - @Override - public List<ApplicationId> listApplications() { - try { - List<String> appNodes = curator.framework().getChildren().forPath(applicationsPath.getAbsolute()); - List<ApplicationId> applicationIds = new ArrayList<>(); - for (String appNode : appNodes) { - parseApplication(appNode).ifPresent(applicationIds::add); - } - return applicationIds; - } catch (Exception e) { - throw new RuntimeException(TenantRepository.logPre(tenant)+"Unable to list applications", e); - } - } - - private Optional<ApplicationId> parseApplication(String appNode) { - try { - return Optional.of(ApplicationId.fromSerializedForm(appNode)); - } catch (IllegalArgumentException e) { - log.log(LogLevel.INFO, TenantRepository.logPre(tenant)+"Unable to parse application with id '" + appNode + "', ignoring."); - return Optional.empty(); - } - } - - @Override - public Transaction createPutApplicationTransaction(ApplicationId applicationId, long sessionId) { - if (listApplications().contains(applicationId)) { - return new CuratorTransaction(curator).add(CuratorOperations.setData(applicationsPath.append(applicationId.serializedForm()).getAbsolute(), Utf8.toAsciiBytes(sessionId))); - } else { - return new CuratorTransaction(curator).add(CuratorOperations.create(applicationsPath.append(applicationId.serializedForm()).getAbsolute(), Utf8.toAsciiBytes(sessionId))); - } - } - - @Override - public long getSessionIdForApplication(ApplicationId applicationId) { - return readSessionId(applicationId, applicationId.serializedForm()); - } - - @Override - public CuratorTransaction deleteApplication(ApplicationId applicationId) { - Path path = applicationsPath.append(applicationId.serializedForm()); - return CuratorTransaction.from(CuratorOperations.delete(path.getAbsolute()), curator); - } - - @Override - public void close() { - directoryCache.close(); - } - - @Override - public 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 might have lost events and might need to remove applications (new applications are - // not added by listening for events here, they are added when session is added, see RemoteSessionRepo) - removeUnusedApplications(); - } - - private void applicationRemoved(ApplicationId applicationId) { - reloadHandler.removeApplication(applicationId); - log.log(LogLevel.INFO, TenantRepository.logPre(applicationId) + "Application removed: " + applicationId); - } - - private void applicationAdded(ApplicationId applicationId) { - log.log(LogLevel.DEBUG, TenantRepository.logPre(applicationId) + "Application added: " + applicationId); - } - - public void removeUnusedApplications() { - ImmutableSet<ApplicationId> activeApplications = ImmutableSet.copyOf(listApplications()); - reloadHandler.removeApplicationsExcept(activeApplications); - } - -} 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 cd2052653ed..14c39beb481 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 @@ -45,6 +45,7 @@ public class HttpHandler extends LoggingRequestHandler { return createErrorResponse(request.getMethod()); } } catch (NotFoundException | com.yahoo.vespa.config.server.NotFoundException e) { + e.printStackTrace(); return HttpErrorResponse.notFoundError(getMessage(e, request)); } catch (ActivationConflictException e) { return HttpErrorResponse.conflictWhenActivating(getMessage(e, request)); diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/http/v2/ListApplicationsHandler.java b/configserver/src/main/java/com/yahoo/vespa/config/server/http/v2/ListApplicationsHandler.java index 56895e3516e..6345532d4ff 100644 --- a/configserver/src/main/java/com/yahoo/vespa/config/server/http/v2/ListApplicationsHandler.java +++ b/configserver/src/main/java/com/yahoo/vespa/config/server/http/v2/ListApplicationsHandler.java @@ -9,10 +9,10 @@ import com.yahoo.config.provision.Zone; import com.yahoo.container.jdisc.HttpRequest; import com.yahoo.container.jdisc.HttpResponse; import com.yahoo.jdisc.Response; +import com.yahoo.vespa.config.server.application.TenantApplications; import com.yahoo.vespa.config.server.tenant.Tenant; import com.yahoo.vespa.config.server.tenant.TenantRepository; import com.yahoo.config.provision.ApplicationId; -import com.yahoo.vespa.config.server.application.TenantApplications; import com.yahoo.vespa.config.server.http.HttpHandler; import com.yahoo.vespa.config.server.http.Utils; 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 198f8e8e917..37082888d70 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 @@ -18,7 +18,7 @@ import java.util.logging.Logger; * * @author Harald Musum */ -public class LocalSessionStateWatcher implements NodeCacheListener { +public class LocalSessionStateWatcher { private static final Logger log = Logger.getLogger(LocalSessionStateWatcher.class.getName()); // One thread pool for all instances of this class @@ -33,7 +33,7 @@ public class LocalSessionStateWatcher implements NodeCacheListener { this.session = session; this.localSessionRepo = localSessionRepo; this.fileCache.start(); - this.fileCache.addListener(this); + this.fileCache.addListener(this::nodeChanged); } // Will delete session if it exists in local session repo @@ -59,7 +59,6 @@ public class LocalSessionStateWatcher implements NodeCacheListener { } } - @Override public void nodeChanged() { executor.execute(() -> { try { 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 fe29c27abbe..15182813a22 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 @@ -17,12 +17,12 @@ import com.yahoo.config.provision.TenantName; import com.yahoo.log.LogLevel; import com.yahoo.path.Path; import com.yahoo.vespa.config.server.application.ApplicationSet; +import com.yahoo.vespa.config.server.application.TenantApplications; import com.yahoo.vespa.config.server.tenant.TenantRepository; import com.yahoo.vespa.curator.Curator; import com.yahoo.yolean.Exceptions; import com.yahoo.vespa.config.server.ReloadHandler; import com.yahoo.config.provision.ApplicationId; -import com.yahoo.vespa.config.server.application.TenantApplications; import com.yahoo.vespa.config.server.monitoring.MetricUpdater; import com.yahoo.vespa.config.server.zookeeper.ConfigCurator; @@ -38,7 +38,7 @@ import org.apache.curator.framework.recipes.cache.*; * @author Vegard Havdal * @author Ulf Lilleengen */ -public class RemoteSessionRepo extends SessionRepo<RemoteSession> implements NodeCacheListener, PathChildrenCacheListener { +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 @@ -77,7 +77,7 @@ public class RemoteSessionRepo extends SessionRepo<RemoteSession> implements Nod this.metrics = metricUpdater; initializeSessions(); this.directoryCache = curator.createDirectoryCache(sessionsPath.getAbsolute(), false, false, pathChildrenExecutor); - this.directoryCache.addListener(this); + this.directoryCache.addListener(this::childEvent); this.directoryCache.start(); } @@ -172,7 +172,7 @@ public class RemoteSessionRepo extends SessionRepo<RemoteSession> implements Nod RemoteSession session = remoteSessionFactory.createSession(sessionId); Path sessionPath = sessionsPath.append(String.valueOf(sessionId)); Curator.FileCache fileCache = curator.createFileCache(sessionPath.append(ConfigCurator.SESSIONSTATE_ZK_SUBPATH).getAbsolute(), false); - fileCache.addListener(this); + fileCache.addListener(this::nodeChanged); loadSessionIfActive(session); sessionStateWatchers.put(sessionId, new RemoteSessionStateWatcher(fileCache, reloadHandler, session, metrics)); addSession(session); @@ -215,8 +215,7 @@ public class RemoteSessionRepo extends SessionRepo<RemoteSession> implements Nod } } - @Override - public void nodeChanged() { + private void nodeChanged() { Multiset<Session.Status> sessionMetrics = HashMultiset.create(); for (RemoteSession session : listSessions()) { sessionMetrics.add(session.getStatus()); @@ -227,8 +226,7 @@ public class RemoteSessionRepo extends SessionRepo<RemoteSession> implements Nod metrics.setDeactivatedSessions(sessionMetrics.count(Session.Status.DEACTIVATE)); } - @Override - public void childEvent(CuratorFramework framework, PathChildrenCacheEvent event) { + private void childEvent(CuratorFramework framework, PathChildrenCacheEvent event) { if (log.isLoggable(LogLevel.DEBUG)) { log.log(LogLevel.DEBUG, "Got child event: " + event); } @@ -254,4 +252,5 @@ public class RemoteSessionRepo extends SessionRepo<RemoteSession> implements Nod session.confirmUpload(); } } + } 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 1a891c65c49..ef59e28f458 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 @@ -20,7 +20,7 @@ import java.util.logging.Logger; * * @author Vegard Havdal */ -public class RemoteSessionStateWatcher implements NodeCacheListener { +public class RemoteSessionStateWatcher { private static final Logger log = Logger.getLogger(RemoteSessionStateWatcher.class.getName()); // One thread pool for all instances of this class @@ -41,7 +41,7 @@ public class RemoteSessionStateWatcher implements NodeCacheListener { this.session = session; this.metrics = metrics; this.fileCache.start(); - this.fileCache.addListener(this); + this.fileCache.addListener(this::nodeChanged); } private void sessionChanged(Session.Status status) { @@ -72,7 +72,6 @@ public class RemoteSessionStateWatcher implements NodeCacheListener { } } - @Override public void nodeChanged() { executor.execute(() -> { try { 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 95d58ecd5bb..078b6e861a9 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 @@ -10,7 +10,6 @@ import com.yahoo.vespa.config.server.host.HostValidator; import com.yahoo.vespa.config.server.ReloadHandler; import com.yahoo.vespa.config.server.RequestHandler; import com.yahoo.vespa.config.server.application.TenantApplications; -import com.yahoo.vespa.config.server.application.ZKTenantApplications; import com.yahoo.vespa.config.server.deploy.TenantFileSystemDirs; import com.yahoo.vespa.config.server.monitoring.Metrics; import com.yahoo.vespa.config.server.session.*; @@ -121,7 +120,7 @@ public class TenantBuilder { private void createApplicationRepo() { if (applicationRepo == null) { - applicationRepo = ZKTenantApplications.create(componentRegistry.getCurator(), reloadHandler, tenant); + applicationRepo = TenantApplications.create(componentRegistry.getCurator(), reloadHandler, tenant); } } 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 bcdd14f8344..cc35219de74 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 @@ -20,6 +20,7 @@ import org.apache.curator.framework.state.ConnectionStateListener; import org.apache.zookeeper.KeeperException; import java.time.Duration; +import java.time.temporal.ChronoUnit; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -37,6 +38,7 @@ import java.util.concurrent.Future; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.TimeUnit; +import java.util.logging.Level; import java.util.logging.Logger; import java.util.stream.Collectors; @@ -57,7 +59,7 @@ import java.util.stream.Collectors; * @author Vegard Havdal * @author Ulf Lilleengen */ -public class TenantRepository implements ConnectionStateListener, PathChildrenCacheListener { +public class TenantRepository { public static final TenantName HOSTED_VESPA_TENANT = TenantName.from("hosted-vespa"); private static final TenantName DEFAULT_TENANT = TenantName.defaultName(); @@ -104,7 +106,7 @@ public class TenantRepository implements ConnectionStateListener, PathChildrenCa this.curator = globalComponentRegistry.getCurator(); metricUpdater = globalComponentRegistry.getMetrics().getOrCreateMetricUpdater(Collections.emptyMap()); this.tenantListeners.add(globalComponentRegistry.getTenantListener()); - curator.framework().getConnectionStateListenable().addListener(this); + curator.framework().getConnectionStateListenable().addListener(this::stateChanged); curator.create(tenantsPath); createSystemTenants(configserverConfig); @@ -113,7 +115,7 @@ public class TenantRepository implements ConnectionStateListener, PathChildrenCa if (useZooKeeperWatchForTenantChanges) { this.directoryCache = Optional.of(curator.createDirectoryCache(tenantsPath.getAbsolute(), false, false, pathChildrenExecutor)); this.directoryCache.get().start(); - this.directoryCache.get().addListener(this); + this.directoryCache.get().addListener(this::childEvent); } else { this.directoryCache = Optional.empty(); } @@ -318,8 +320,7 @@ public class TenantRepository implements ConnectionStateListener, PathChildrenCa return ret.toString(); } - @Override - public void stateChanged(CuratorFramework framework, ConnectionState connectionState) { + private void stateChanged(CuratorFramework framework, ConnectionState connectionState) { switch (connectionState) { case CONNECTED: metricUpdater.incZKConnected(); @@ -339,8 +340,7 @@ public class TenantRepository implements ConnectionStateListener, PathChildrenCa } } - @Override - public void childEvent(CuratorFramework framework, PathChildrenCacheEvent event) { + private void childEvent(CuratorFramework framework, PathChildrenCacheEvent event) { switch (event.getType()) { case CHILD_ADDED: case CHILD_REMOVED: @@ -351,8 +351,16 @@ public class TenantRepository implements ConnectionStateListener, PathChildrenCa public void close() { directoryCache.ifPresent(Curator.DirectoryCache::close); - pathChildrenExecutor.shutdown(); - checkForRemovedApplicationsService.shutdown(); + try { + pathChildrenExecutor.shutdown(); + checkForRemovedApplicationsService.shutdown(); + pathChildrenExecutor.awaitTermination(50, TimeUnit.SECONDS); + checkForRemovedApplicationsService.awaitTermination(50, TimeUnit.SECONDS); + } + catch (InterruptedException e) { + log.log(Level.WARNING, "Interrupted while shutting down.", e); + Thread.currentThread().interrupt(); + } } public boolean checkThatTenantExists(TenantName tenant) { diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/application/MemoryTenantApplications.java b/configserver/src/test/java/com/yahoo/vespa/config/server/application/MemoryTenantApplications.java deleted file mode 100644 index ce4b5af7650..00000000000 --- a/configserver/src/test/java/com/yahoo/vespa/config/server/application/MemoryTenantApplications.java +++ /dev/null @@ -1,66 +0,0 @@ -// 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.config.provision.ApplicationId; -import com.yahoo.transaction.Transaction; -import com.yahoo.vespa.config.server.session.DummyTransaction; - -import java.util.ArrayList; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - -/** - * In memory {@link TenantApplications} to be used when testing. - * - * @author Ulf Lilleengen - * @since 5.1 - */ -public class MemoryTenantApplications implements TenantApplications { - - private final Map<ApplicationId, Long> applications = new LinkedHashMap<>(); - private boolean isOpen = true; - - @Override - public List<ApplicationId> listApplications() { - List<ApplicationId> lst = new ArrayList<>(); - lst.addAll(applications.keySet()); - return lst; - } - - @Override - public Transaction createPutApplicationTransaction(ApplicationId applicationId, long sessionId) { - return new DummyTransaction().add((DummyTransaction.RunnableOperation) () -> { - applications.put(applicationId, sessionId); - }); - } - - @Override - public long getSessionIdForApplication(ApplicationId id) { - if (applications.containsKey(id)) { - return applications.get(id); - } - return 0; - } - - @Override - public Transaction deleteApplication(ApplicationId id) { - return new DummyTransaction().add((DummyTransaction.RunnableOperation) () -> { - applications.remove(id); - }); - } - - @Override - public void removeUnusedApplications() { - // do nothing - } - - @Override - public void close() { - isOpen = false; - } - - public boolean isOpen() { - return isOpen; - } -} 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 3fa1b3fdb5e..a708e4d8ace 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 @@ -13,8 +13,6 @@ import org.apache.curator.framework.CuratorFramework; import org.junit.Before; import org.junit.Test; -import java.util.Arrays; -import java.util.Collections; import java.util.List; import static org.hamcrest.Matchers.is; @@ -103,36 +101,6 @@ public class TenantApplicationsTest { } @Test - public void require_that_repos_behave_similarly() throws Exception { - TenantApplications zkRepo = createZKAppRepo(); - TenantApplications memRepo = new MemoryTenantApplications(); - for (TenantApplications repo : Arrays.asList(zkRepo, memRepo)) { - ApplicationId id1 = createApplicationId("myapp"); - ApplicationId id2 = createApplicationId("myapp2"); - repo.createPutApplicationTransaction(id1, 4).commit(); - repo.createPutApplicationTransaction(id2, 5).commit(); - List<ApplicationId> lst = repo.listApplications(); - Collections.sort(lst); - assertThat(lst.size(), is(2)); - assertThat(lst.get(0).application(), is(id1.application())); - assertThat(lst.get(1).application(), is(id2.application())); - assertThat(repo.getSessionIdForApplication(id1), is(4l)); - assertThat(repo.getSessionIdForApplication(id2), is(5l)); - repo.createPutApplicationTransaction(id1, 6).commit(); - lst = repo.listApplications(); - Collections.sort(lst); - assertThat(lst.size(), is(2)); - assertThat(lst.get(0).application(), is(id1.application())); - assertThat(lst.get(1).application(), is(id2.application())); - assertThat(repo.getSessionIdForApplication(id1), is(6l)); - assertThat(repo.getSessionIdForApplication(id2), is(5l)); - repo.deleteApplication(id1).commit(); - assertThat(repo.listApplications().size(), is(1)); - repo.deleteApplication(id2).commit(); - } - } - - @Test public void require_that_reload_handler_is_called_when_apps_are_removed() throws Exception { ApplicationId foo = createApplicationId("foo"); writeApplicationData(foo, 3L); @@ -154,7 +122,7 @@ public class TenantApplicationsTest { } private TenantApplications createZKAppRepo(MockReloadHandler reloadHandler) { - return ZKTenantApplications.create(curator, reloadHandler, tenantName); + return TenantApplications.create(curator, 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 f384fda8796..380b76c30af 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 @@ -20,9 +20,9 @@ import com.yahoo.jdisc.Response; import com.yahoo.jdisc.http.HttpRequest; import com.yahoo.slime.JsonFormat; import com.yahoo.vespa.config.server.ApplicationRepository; +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.MemoryTenantApplications; import com.yahoo.vespa.config.server.application.OrchestratorMock; import com.yahoo.vespa.config.server.application.TenantApplications; import com.yahoo.vespa.config.server.deploy.TenantFileSystemDirs; @@ -98,22 +98,22 @@ public class SessionActiveHandlerTest extends SessionHandlerTest { @Before public void setup() { remoteSessionRepo = new RemoteSessionRepo(tenantName); - applicationRepo = new MemoryTenantApplications(); curator = new MockCurator(); - localRepo = new LocalSessionRepo(clock, curator); - pathPrefix = "/application/v2/tenant/" + tenantName + "/session/"; - hostProvisioner = new MockProvisioner(); modelFactory = new VespaModelFactory(new NullConfigModelRegistry()); componentRegistry = new TestComponentRegistry.Builder() .curator(curator) .modelFactoryRegistry(new ModelFactoryRegistry(Collections.singletonList(modelFactory))) .build(); + tenantRepository = new TenantRepository(componentRegistry, false); + applicationRepo = TenantApplications.create(curator, new MockReloadHandler(), tenantName); + localRepo = new LocalSessionRepo(clock, curator); + pathPrefix = "/application/v2/tenant/" + tenantName + "/session/"; + hostProvisioner = new MockProvisioner(); TenantBuilder tenantBuilder = TenantBuilder.create(componentRegistry, tenantName) .withSessionFactory(new MockSessionFactory()) .withLocalSessionRepo(localRepo) .withRemoteSessionRepo(remoteSessionRepo) .withApplicationRepo(applicationRepo); - tenantRepository = new TenantRepository(componentRegistry, false); tenantRepository.addTenant(tenantBuilder); handler = createHandler(); } 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 803a87ada1c..94d3b126bd7 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 @@ -7,8 +7,8 @@ import com.yahoo.config.provision.TenantName; import com.yahoo.container.jdisc.HttpRequest; import com.yahoo.container.jdisc.HttpResponse; import com.yahoo.vespa.config.server.ApplicationRepository; +import com.yahoo.vespa.config.server.MockReloadHandler; import com.yahoo.vespa.config.server.TestComponentRegistry; -import com.yahoo.vespa.config.server.application.MemoryTenantApplications; import com.yahoo.vespa.config.server.application.OrchestratorMock; import com.yahoo.vespa.config.server.application.TenantApplications; import com.yahoo.vespa.config.server.http.CompressedApplicationInputStreamTest; @@ -18,6 +18,7 @@ import com.yahoo.vespa.config.server.http.SessionHandlerTest; import com.yahoo.vespa.config.server.session.LocalSessionRepo; import com.yahoo.vespa.config.server.tenant.TenantBuilder; import com.yahoo.vespa.config.server.tenant.TenantRepository; +import com.yahoo.vespa.curator.Curator; import com.yahoo.vespa.curator.mock.MockCurator; import org.junit.Before; import org.junit.Ignore; @@ -70,8 +71,9 @@ public class SessionCreateHandlerTest extends SessionHandlerTest { @Before public void setupRepo() { - applicationRepo = new MemoryTenantApplications(); - localSessionRepo = new LocalSessionRepo(Clock.systemUTC(), new MockCurator()); + Curator curator = new MockCurator(); + applicationRepo = TenantApplications.create(curator, new MockReloadHandler(), tenant); + localSessionRepo = new LocalSessionRepo(Clock.systemUTC(), curator); tenantRepository = new TenantRepository(componentRegistry, false); sessionFactory = new MockSessionFactory(); TenantBuilder tenantBuilder = TenantBuilder.create(componentRegistry, tenant) 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 330d6592a2d..11c0cf057cc 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 @@ -19,11 +19,12 @@ import com.yahoo.slime.Slime; import com.yahoo.transaction.NestedTransaction; import com.yahoo.transaction.Transaction; import com.yahoo.vespa.config.server.ApplicationRepository; +import com.yahoo.vespa.config.server.MockReloadHandler; import com.yahoo.vespa.config.server.TestComponentRegistry; import com.yahoo.vespa.config.server.application.ApplicationSet; import com.yahoo.vespa.config.server.application.OrchestratorMock; +import com.yahoo.vespa.config.server.application.TenantApplications; import com.yahoo.vespa.config.server.host.HostRegistry; -import com.yahoo.vespa.config.server.application.MemoryTenantApplications; import com.yahoo.vespa.config.server.configchange.ConfigChangeActions; import com.yahoo.vespa.config.server.configchange.MockRefeedAction; import com.yahoo.vespa.config.server.configchange.MockRestartAction; @@ -86,7 +87,7 @@ public class SessionPrepareHandlerTest extends SessionHandlerTest { .withSessionFactory(new MockSessionFactory()) .withLocalSessionRepo(localRepo) .withRemoteSessionRepo(remoteSessionRepo) - .withApplicationRepo(new MemoryTenantApplications()); + .withApplicationRepo(TenantApplications.create(curator, new MockReloadHandler(), tenant)); tenantRepository.addTenant(tenantBuilder); } 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 7b9389ada9b..3626c6269cc 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 @@ -5,8 +5,9 @@ import com.yahoo.config.model.application.provider.FilesApplicationPackage; import com.yahoo.test.ManualClock; import com.yahoo.config.provision.TenantName; 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.MemoryTenantApplications; +import com.yahoo.vespa.config.server.application.TenantApplications; import com.yahoo.vespa.config.server.deploy.TenantFileSystemDirs; import com.yahoo.io.IOUtils; import com.yahoo.vespa.config.server.host.HostRegistry; @@ -54,7 +55,7 @@ public class LocalSessionRepoTest { } clock = new ManualClock(Instant.ofEpochSecond(1)); LocalSessionLoader loader = new SessionFactoryImpl(globalComponentRegistry, - new MemoryTenantApplications(), + TenantApplications.create(new MockCurator(), new MockReloadHandler(), tenantName), tenantFileSystemDirs, new HostRegistry<>(), tenantName); repo = new LocalSessionRepo(tenantFileSystemDirs, loader, clock, 5, globalComponentRegistry.getCurator()); 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 37784b313b6..e7db4dcf58f 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 @@ -15,8 +15,9 @@ import com.yahoo.config.provision.TenantName; 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.application.MemoryTenantApplications; +import com.yahoo.vespa.config.server.application.TenantApplications; import com.yahoo.vespa.config.server.deploy.DeployHandlerLogger; import com.yahoo.vespa.config.server.deploy.TenantFileSystemDirs; import com.yahoo.vespa.config.server.deploy.ZooKeeperClient; @@ -200,7 +201,7 @@ public class LocalSessionTest { FilesApplicationPackage.fromFile(testApp), zkc, sessionDir, - new MemoryTenantApplications(), + TenantApplications.create(curator, new MockReloadHandler(), tenant), new HostRegistry<>(), superModelGenerationCounter, flagSource)); diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/session/MockSessionZKClient.java b/configserver/src/test/java/com/yahoo/vespa/config/server/session/MockSessionZKClient.java index 2290ee5890b..e22185ae69b 100644 --- a/configserver/src/test/java/com/yahoo/vespa/config/server/session/MockSessionZKClient.java +++ b/configserver/src/test/java/com/yahoo/vespa/config/server/session/MockSessionZKClient.java @@ -7,6 +7,7 @@ import com.yahoo.config.provision.AllocatedHosts; import com.yahoo.config.provision.TenantName; import com.yahoo.transaction.Transaction; import com.yahoo.path.Path; +import com.yahoo.vespa.config.server.session.Session.Status; import com.yahoo.vespa.config.server.tenant.TenantRepository; import com.yahoo.vespa.curator.Curator; import com.yahoo.vespa.curator.mock.MockCurator; @@ -20,12 +21,12 @@ import java.util.Optional; */ public class MockSessionZKClient extends SessionZooKeeperClient { - private ApplicationPackage app = null; + private ApplicationPackage app; private Optional<AllocatedHosts> info = Optional.empty(); - private Session.Status sessionStatus; + private Status sessionStatus; public MockSessionZKClient(Curator curator, TenantName tenantName, long sessionId) { - this(curator, tenantName, sessionId, (ApplicationPackage)null); + this(curator, tenantName, sessionId, (ApplicationPackage) null); } public MockSessionZKClient(Curator curator, TenantName tenantName, long sessionId, Optional<AllocatedHosts> allocatedHosts) { @@ -36,11 +37,11 @@ public class MockSessionZKClient extends SessionZooKeeperClient { public MockSessionZKClient(Curator curator, TenantName tenantName, long sessionId, ApplicationPackage application) { super(curator, TenantRepository.getSessionsPath(tenantName).append(String.valueOf(sessionId))); this.app = application; + curator.create(TenantRepository.getSessionsPath(tenantName).append(String.valueOf(sessionId))); } public MockSessionZKClient(ApplicationPackage app) { - super(new MockCurator(), Path.createRoot()); - this.app = app; + this(new MockCurator(), TenantName.defaultName(), 123, app); } @Override @@ -54,15 +55,4 @@ public class MockSessionZKClient extends SessionZooKeeperClient { return info.orElseThrow(() -> new IllegalStateException("Could not find allocated hosts")); } - @Override - public Transaction createWriteStatusTransaction(Session.Status status) { - return new DummyTransaction().add((DummyTransaction.RunnableOperation) () -> { - sessionStatus = status; - }); - } - - @Override - public Session.Status readStatus() { - return sessionStatus; - } } 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 4bbfea48254..9dda653dbc1 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 @@ -6,12 +6,11 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertThat; -import com.yahoo.config.provision.ApplicationId; import com.yahoo.config.provision.TenantName; import com.yahoo.path.Path; import com.yahoo.text.Utf8; -import com.yahoo.transaction.Transaction; +import com.yahoo.vespa.config.server.MockReloadHandler; import com.yahoo.vespa.config.server.TestComponentRegistry; import com.yahoo.vespa.config.server.application.TenantApplications; import com.yahoo.vespa.config.server.tenant.Tenant; @@ -25,8 +24,6 @@ import org.junit.Test; import com.yahoo.vespa.config.server.zookeeper.ConfigCurator; import java.time.Duration; -import java.util.Collections; -import java.util.List; import java.util.concurrent.TimeUnit; import java.util.function.LongPredicate; @@ -102,8 +99,9 @@ public class RemoteSessionRepoTest { @Test public void testBadApplicationRepoOnActivate() { long sessionId = 3L; - TenantApplications applicationRepo = new FailingTenantApplications(); TenantName mytenant = TenantName.from("mytenant"); + TenantApplications applicationRepo = TenantApplications.create(curator, 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(); @@ -151,36 +149,4 @@ public class RemoteSessionRepoTest { } while (System.currentTimeMillis() < endTime && !ok); } - private class FailingTenantApplications implements TenantApplications { - - @Override - public List<ApplicationId> listApplications() { - return Collections.singletonList(ApplicationId.defaultId()); - } - - @Override - public Transaction createPutApplicationTransaction(ApplicationId applicationId, long sessionId) { - return null; - } - - @Override - public long getSessionIdForApplication(ApplicationId applicationId) { - throw new IllegalArgumentException("Bad id " + applicationId); - } - - @Override - public Transaction deleteApplication(ApplicationId applicationId) { - return null; - } - - @Override - public void removeUnusedApplications() { - // do nothing - } - - @Override - public void close() { - - } - } } 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 ac7d6948b22..9ad90e84d86 100644 --- a/configserver/src/test/java/com/yahoo/vespa/config/server/session/SessionPreparerTest.java +++ b/configserver/src/test/java/com/yahoo/vespa/config/server/session/SessionPreparerTest.java @@ -15,11 +15,12 @@ import com.yahoo.log.LogLevel; import com.yahoo.path.Path; import com.yahoo.slime.Slime; import com.yahoo.config.provision.ApplicationId; +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.TimeoutBudgetTest; -import com.yahoo.vespa.config.server.application.MemoryTenantApplications; import com.yahoo.vespa.config.server.application.PermanentApplicationPackage; +import com.yahoo.vespa.config.server.application.TenantApplications; import com.yahoo.vespa.config.server.deploy.DeployHandlerLogger; import com.yahoo.vespa.config.server.host.HostRegistry; import com.yahoo.vespa.config.server.http.InvalidApplicationException; @@ -216,7 +217,8 @@ public class SessionPreparerTest { return new SessionContext(app, new SessionZooKeeperClient(curator, sessionsPath), app.getAppDir(), - new MemoryTenantApplications(), new HostRegistry<>(), + TenantApplications.create(curator, new MockReloadHandler(), TenantName.from("tenant")), + new HostRegistry<>(), new SuperModelGenerationCounter(curator), flagSource); } 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 1b3afeb353b..baab250a508 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 @@ -3,19 +3,22 @@ package com.yahoo.vespa.config.server.tenant; import com.google.common.testing.EqualsTester; import com.yahoo.config.provision.TenantName; +import com.yahoo.vespa.config.server.MockReloadHandler; import com.yahoo.vespa.config.server.TestComponentRegistry; -import com.yahoo.vespa.config.server.application.MemoryTenantApplications; +import com.yahoo.vespa.config.server.application.TenantApplications; +import com.yahoo.vespa.curator.mock.MockCurator; import org.junit.Before; import org.junit.Test; import static org.hamcrest.CoreMatchers.not; import static org.hamcrest.Matchers.is; -import static org.junit.Assert.*; +import static org.junit.Assert.assertThat; /** * @author Ulf Lilleengen */ public class TenantTest { + private final TestComponentRegistry componentRegistry = new TestComponentRegistry.Builder().build(); private Tenant t1; @@ -35,7 +38,7 @@ public class TenantTest { TenantRepository tenantRepository = new TenantRepository(componentRegistry, false); TenantName tenantName = TenantName.from(name); TenantBuilder tenantBuilder = TenantBuilder.create(componentRegistry, tenantName) - .withApplicationRepo(new MemoryTenantApplications()); + .withApplicationRepo(TenantApplications.create(new MockCurator(), new MockReloadHandler(), tenantName)); tenantRepository.addTenant(tenantBuilder); return tenantRepository.getTenant(tenantName); } @@ -56,11 +59,4 @@ public class TenantTest { assertThat(t1.hashCode(), is(not(t4.hashCode()))); } - @Test - public void close() { - MemoryTenantApplications repo = (MemoryTenantApplications) t1.getApplicationRepo(); - assertTrue(repo.isOpen()); - t1.close(); - assertFalse(repo.isOpen()); - } } |