diff options
Diffstat (limited to 'configserver/src/main/java')
5 files changed, 29 insertions, 99 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 a4dfec708d6..22de36e98aa 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 @@ -18,7 +18,6 @@ import com.yahoo.vespa.config.server.NotFoundException; import com.yahoo.vespa.config.server.ReloadHandler; import com.yahoo.vespa.config.server.ReloadListener; import com.yahoo.vespa.config.server.RequestHandler; -import com.yahoo.vespa.config.server.deploy.TenantFileSystemDirs; import com.yahoo.vespa.config.server.host.HostRegistry; import com.yahoo.vespa.config.server.host.HostValidator; import com.yahoo.vespa.config.server.monitoring.MetricUpdater; @@ -32,8 +31,6 @@ import com.yahoo.vespa.curator.transaction.CuratorTransaction; import org.apache.curator.framework.CuratorFramework; import org.apache.curator.framework.recipes.cache.PathChildrenCacheEvent; -import java.nio.file.Files; -import java.nio.file.Paths; import java.time.Clock; import java.time.Duration; import java.util.Collection; @@ -76,12 +73,10 @@ public class TenantApplications implements RequestHandler, ReloadHandler, HostVa private final ApplicationMapper applicationMapper = new ApplicationMapper(); private final MetricUpdater tenantMetricUpdater; private final Clock clock = Clock.systemUTC(); - private final TenantFileSystemDirs tenantFileSystemDirs; public TenantApplications(TenantName tenant, Curator curator, StripedExecutor<TenantName> zkWatcherExecutor, ExecutorService zkCacheExecutor, Metrics metrics, ReloadListener reloadListener, - ConfigserverConfig configserverConfig, HostRegistry<ApplicationId> hostRegistry, - TenantFileSystemDirs tenantFileSystemDirs) { + ConfigserverConfig configserverConfig, HostRegistry<ApplicationId> hostRegistry) { this.curator = curator; this.applicationsPath = TenantRepository.getApplicationsPath(tenant); this.locksPath = TenantRepository.getLocksPath(tenant); @@ -95,7 +90,6 @@ public class TenantApplications implements RequestHandler, ReloadHandler, HostVa this.responseFactory = ConfigResponseFactory.create(configserverConfig); this.tenantMetricUpdater = metrics.getOrCreateMetricUpdater(Metrics.createDimensions(tenant)); this.hostRegistry = hostRegistry; - this.tenantFileSystemDirs = tenantFileSystemDirs; } // For testing only @@ -107,8 +101,7 @@ public class TenantApplications implements RequestHandler, ReloadHandler, HostVa componentRegistry.getMetrics(), componentRegistry.getReloadListener(), componentRegistry.getConfigserverConfig(), - componentRegistry.getHostRegistries().createApplicationHostRegistry(tenantName), - new TenantFileSystemDirs(componentRegistry.getConfigServerDB(), tenantName)); + componentRegistry.getHostRegistries().createApplicationHostRegistry(tenantName)); } /** @@ -135,10 +128,6 @@ public class TenantApplications implements RequestHandler, ReloadHandler, HostVa return data.isEmpty() ? Optional.empty() : Optional.of(Long.parseLong(data)); } - public boolean hasLocalSession(long sessionId) { - return Files.exists(Paths.get(tenantFileSystemDirs.sessionsPath().getAbsolutePath(), String.valueOf(sessionId))); - } - /** * Returns a transaction which writes the given session id as the currently active for the given application. * @@ -248,6 +237,12 @@ public class TenantApplications implements RequestHandler, ReloadHandler, HostVa return application.resolveConfig(req, responseFactory); } + // For testing only + long getApplicationGeneration(ApplicationId appId, Optional<Version> vespaVersion) { + Application application = getApplication(appId, vespaVersion); + return application.getApplicationGeneration(); + } + private void notifyReloadListeners(ApplicationSet applicationSet) { reloadListener.hostsUpdated(tenant, hostRegistry.getAllHosts()); reloadListener.configActivated(applicationSet); diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/filedistribution/FileDirectory.java b/configserver/src/main/java/com/yahoo/vespa/config/server/filedistribution/FileDirectory.java index 0865b72dbbf..ab7509a49aa 100644 --- a/configserver/src/main/java/com/yahoo/vespa/config/server/filedistribution/FileDirectory.java +++ b/configserver/src/main/java/com/yahoo/vespa/config/server/filedistribution/FileDirectory.java @@ -55,7 +55,7 @@ public class FileDirectory { return root.getAbsolutePath() + "/" + ref.value(); } - public File getFile(FileReference reference) { + File getFile(FileReference reference) { ensureRootExist(); File dir = new File(getPath(reference)); if (!dir.exists()) { 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 0e538b05931..316f7f7778d 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 @@ -18,9 +18,6 @@ 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; -import com.yahoo.vespa.flags.BooleanFlag; -import com.yahoo.vespa.flags.FlagSource; -import com.yahoo.vespa.flags.Flags; import org.apache.curator.framework.CuratorFramework; import org.apache.curator.framework.recipes.cache.ChildData; import org.apache.curator.framework.recipes.cache.PathChildrenCacheEvent; @@ -56,7 +53,6 @@ public class RemoteSessionRepo { private final ReloadHandler reloadHandler; private final TenantName tenantName; private final MetricUpdater metrics; - private final BooleanFlag distributeApplicationPackage; private final Curator.DirectoryCache directoryCache; private final TenantApplications applicationRepo; private final Executor zkWatcherExecutor; @@ -66,8 +62,7 @@ public class RemoteSessionRepo { SessionFactory sessionFactory, ReloadHandler reloadHandler, TenantName tenantName, - TenantApplications applicationRepo, - FlagSource flagSource) { + TenantApplications applicationRepo) { this.sessionCache = new SessionCache<>(); this.curator = componentRegistry.getCurator(); this.sessionsPath = TenantRepository.getSessionsPath(tenantName); @@ -76,7 +71,6 @@ public class RemoteSessionRepo { this.reloadHandler = reloadHandler; this.tenantName = tenantName; this.metrics = componentRegistry.getMetrics().getOrCreateMetricUpdater(Metrics.createDimensions(tenantName)); - this.distributeApplicationPackage = Flags.CONFIGSERVER_DISTRIBUTE_APPLICATION_PACKAGE.bindTo(flagSource); StripedExecutor<TenantName> zkWatcherExecutor = componentRegistry.getZkWatcherExecutor(); this.zkWatcherExecutor = command -> zkWatcherExecutor.execute(tenantName, command); initializeSessions(); @@ -95,7 +89,6 @@ public class RemoteSessionRepo { public void addSession(RemoteSession session) { sessionCache.addSession(session); - metrics.incAddedSessions(); } public int deleteExpiredSessions(Clock clock, Duration expiryTime) { @@ -162,9 +155,8 @@ public class RemoteSessionRepo { fileCache.addListener(this::nodeChanged); loadSessionIfActive(session); addSession(session); + metrics.incAddedSessions(); sessionStateWatchers.put(sessionId, new RemoteSessionStateWatcher(fileCache, reloadHandler, session, metrics, zkWatcherExecutor)); - if (distributeApplicationPackage.value()) - sessionFactory.createLocalSessionUsingDistributedApplicationPackage(sessionId); } private void sessionRemoved(long sessionId) { diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/session/SessionFactory.java b/configserver/src/main/java/com/yahoo/vespa/config/server/session/SessionFactory.java index 337e9b3e99c..fc4071916ed 100644 --- a/configserver/src/main/java/com/yahoo/vespa/config/server/session/SessionFactory.java +++ b/configserver/src/main/java/com/yahoo/vespa/config/server/session/SessionFactory.java @@ -1,7 +1,6 @@ // 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.config.FileReference; import com.yahoo.config.application.api.ApplicationPackage; import com.yahoo.config.application.api.DeployLogger; import com.yahoo.config.model.application.provider.DeployData; @@ -15,18 +14,15 @@ import com.yahoo.vespa.config.server.GlobalComponentRegistry; import com.yahoo.vespa.config.server.TimeoutBudget; import com.yahoo.vespa.config.server.application.TenantApplications; import com.yahoo.vespa.config.server.deploy.TenantFileSystemDirs; -import com.yahoo.vespa.config.server.filedistribution.FileDirectory; import com.yahoo.vespa.config.server.host.HostValidator; import com.yahoo.vespa.config.server.tenant.TenantRepository; import com.yahoo.vespa.config.server.zookeeper.ConfigCurator; import com.yahoo.vespa.config.server.zookeeper.SessionCounter; import com.yahoo.vespa.curator.Curator; -import com.yahoo.vespa.defaults.Defaults; import com.yahoo.vespa.flags.BooleanFlag; import com.yahoo.vespa.flags.Flags; import java.io.File; -import java.io.IOException; import java.time.Clock; import java.util.List; import java.util.Optional; @@ -35,7 +31,7 @@ import java.util.logging.Logger; /** * Serves as the factory of sessions. Takes care of copying files to the correct folder and initializing the - * session state. There is one SessionFactory per tenant. + * session state. * * @author Ulf Lilleengen */ @@ -90,7 +86,8 @@ public class SessionFactory { } public RemoteSession createRemoteSession(long sessionId) { - SessionZooKeeperClient sessionZKClient = createSessionZooKeeperClient(getSessionPath(sessionId)); + Path sessionPath = sessionsPath.append(String.valueOf(sessionId)); + SessionZooKeeperClient sessionZKClient = createSessionZooKeeperClient(sessionPath); return new RemoteSession(tenant, sessionId, componentRegistry, sessionZKClient); } @@ -118,10 +115,10 @@ public class SessionFactory { private LocalSession createSessionFromApplication(ApplicationPackage applicationPackage, long sessionId, + SessionZooKeeperClient sessionZKClient, TimeoutBudget timeoutBudget, Clock clock) { log.log(Level.FINE, TenantRepository.logPre(tenant) + "Creating session " + sessionId + " in ZooKeeper"); - SessionZooKeeperClient sessionZKClient = createSessionZooKeeperClient(getSessionPath(sessionId)); sessionZKClient.createNewSession(clock.instant()); Curator.CompletionWaiter waiter = sessionZKClient.getUploadWaiter(); LocalSession session = new LocalSession(tenant, sessionId, sessionPreparer, applicationPackage, sessionZKClient, @@ -164,47 +161,23 @@ public class SessionFactory { boolean internalRedeploy, TimeoutBudget timeoutBudget) { long sessionId = getNextSessionId(); try { - ApplicationPackage app = createApplicationPackage(applicationFile, applicationId, - sessionId, currentlyActiveSessionId, internalRedeploy); - return createSessionFromApplication(app, sessionId, timeoutBudget, clock); - } catch (Exception e) { - throw new RuntimeException("Error creating session " + sessionId, e); - } - } - - /** - * This method is used when creating a session based on a remote session and the distributed application package - * It does not wait for session being created on other servers - */ - private LocalSession createLocalSession(File applicationFile, ApplicationId applicationId, - long sessionId, long currentlyActiveSessionId) { - try { - ApplicationPackage applicationPackage = createApplicationPackage(applicationFile, applicationId, - sessionId, currentlyActiveSessionId, false); + ensureSessionPathDoesNotExist(sessionId); SessionZooKeeperClient sessionZooKeeperClient = createSessionZooKeeperClient(getSessionPath(sessionId)); - return new LocalSession(tenant, sessionId, sessionPreparer, applicationPackage, sessionZooKeeperClient, - getSessionAppDir(sessionId), applicationRepo, hostRegistry); + File userApplicationDir = getSessionAppDir(sessionId); + IOUtils.copyDirectory(applicationFile, userApplicationDir); + ApplicationPackage applicationPackage = createApplication(applicationFile, + userApplicationDir, + applicationId, + sessionId, + currentlyActiveSessionId, + internalRedeploy); + applicationPackage.writeMetaData(); + return createSessionFromApplication(applicationPackage, sessionId, sessionZooKeeperClient, timeoutBudget, clock); } catch (Exception e) { throw new RuntimeException("Error creating session " + sessionId, e); } } - private ApplicationPackage createApplicationPackage(File applicationFile, ApplicationId applicationId, - long sessionId, long currentlyActiveSessionId, - boolean internalRedeploy) throws IOException { - ensureSessionPathDoesNotExist(sessionId); - File userApplicationDir = getSessionAppDir(sessionId); - IOUtils.copyDirectory(applicationFile, userApplicationDir); - ApplicationPackage applicationPackage = createApplication(applicationFile, - userApplicationDir, - applicationId, - sessionId, - currentlyActiveSessionId, - internalRedeploy); - applicationPackage.writeMetaData(); - return applicationPackage; - } - /** * Returns a new session instance for the given session id. */ @@ -217,34 +190,6 @@ public class SessionFactory { getSessionAppDir(sessionId), applicationRepo, hostRegistry); } - /** - * Returns a new session instance for the given session id. - */ - LocalSession createLocalSessionUsingDistributedApplicationPackage(long sessionId) { - if (applicationRepo.hasLocalSession(sessionId)) { - log.log(Level.FINE, "Local session for session id " + sessionId + " already exists"); - return createSessionFromId(sessionId); - } - - log.log(Level.INFO, "Creating local session for session id " + sessionId); - SessionZooKeeperClient sessionZKClient = createSessionZooKeeperClient(getSessionPath(sessionId)); - FileReference fileReference = sessionZKClient.readApplicationPackageReference(); - log.log(Level.FINE, "File reference for session id " + sessionId + ": " + fileReference); - if (fileReference != null) { - File rootDir = new File(Defaults.getDefaults().underVespaHome(componentRegistry.getConfigserverConfig().fileReferencesDir())); - File sessionDir = new FileDirectory(rootDir).getFile(fileReference); - if (!sessionDir.exists()) - throw new RuntimeException("File reference for session " + sessionId + " not found (" + sessionDir.getAbsolutePath() + ")"); - ApplicationId applicationId = sessionZKClient.readApplicationId(); - return createLocalSession(sessionDir, - applicationId, - sessionId, - applicationRepo.activeSessionOf(applicationId).orElse(nonExistingActiveSession)); - } - return null; - } - - // Return Optional instead of faking it with nonExistingActiveSession private long getActiveSessionId(ApplicationId applicationId) { List<ApplicationId> applicationIds = applicationRepo.activeApplications(); if (applicationIds.contains(applicationId)) { 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 d34f89a179b..90a03153d30 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 @@ -12,7 +12,6 @@ import com.yahoo.vespa.config.server.GlobalComponentRegistry; 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.deploy.TenantFileSystemDirs; import com.yahoo.vespa.config.server.monitoring.MetricUpdater; import com.yahoo.vespa.config.server.session.LocalSessionRepo; import com.yahoo.vespa.config.server.session.RemoteSessionRepo; @@ -217,8 +216,7 @@ public class TenantRepository { componentRegistry.getMetrics(), componentRegistry.getReloadListener(), componentRegistry.getConfigserverConfig(), - componentRegistry.getHostRegistries().createApplicationHostRegistry(tenantName), - new TenantFileSystemDirs(componentRegistry.getConfigServerDB(), tenantName)); + componentRegistry.getHostRegistries().createApplicationHostRegistry(tenantName)); if (requestHandler == null) requestHandler = applicationRepo; if (reloadHandler == null) @@ -229,8 +227,7 @@ public class TenantRepository { sessionFactory, reloadHandler, tenantName, - applicationRepo, - componentRegistry.getFlagSource()); + applicationRepo); log.log(Level.INFO, "Creating tenant '" + tenantName + "'"); Tenant tenant = new Tenant(tenantName, sessionFactory, localSessionRepo, remoteSessionRepo, requestHandler, reloadHandler, applicationRepo, componentRegistry.getCurator()); @@ -247,6 +244,7 @@ public class TenantRepository { return tenants.get(DEFAULT_TENANT); } + private void removeUnusedApplications() { getAllTenants().forEach(tenant -> tenant.getApplicationRepo().removeUnusedApplications()); } |