diff options
author | Harald Musum <musum@verizonmedia.com> | 2020-06-22 10:53:54 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-06-22 10:53:54 +0200 |
commit | 549528c9de2aa47e7e6b5d240aea4e3b53b8b8b7 (patch) | |
tree | 09a2a231d78a1253ca8b4363d7adeddc36f102f6 | |
parent | 3a66636ae7790b334467898ab31badf522f70a1e (diff) | |
parent | e29722b5823e5ba1d8284d91a791a9a04f0df153 (diff) |
Merge pull request #13649 from vespa-engine/hmusum/configserver-refactoring-13-take-2
Create local session after maintainer has downloaded application package
7 files changed, 56 insertions, 51 deletions
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/ApplicationRepository.java b/configserver/src/main/java/com/yahoo/vespa/config/server/ApplicationRepository.java index c44a839d24d..becf01c191c 100644 --- a/configserver/src/main/java/com/yahoo/vespa/config/server/ApplicationRepository.java +++ b/configserver/src/main/java/com/yahoo/vespa/config/server/ApplicationRepository.java @@ -490,7 +490,7 @@ public class ApplicationRepository implements com.yahoo.config.provision.Deploye Tenant tenant = tenantRepository.getTenant(applicationId.tenant()); if (tenant == null) throw new NotFoundException("Tenant '" + applicationId.tenant() + "' not found"); long sessionId = getSessionIdForApplication(tenant, applicationId); - RemoteSession session = tenant.getSessionRepo().getRemoteSession(sessionId); + RemoteSession session = tenant.getSessionRepository().getRemoteSession(sessionId); if (session == null) throw new NotFoundException("Remote session " + sessionId + " not found"); return session.ensureApplicationLoaded().getForVersionOrLatest(version, clock.instant()); } catch (NotFoundException e) { @@ -528,7 +528,7 @@ public class ApplicationRepository implements com.yahoo.config.provision.Deploye } private boolean localSessionHasBeenDeleted(ApplicationId applicationId, long sessionId, Duration waitTime) { - SessionRepository sessionRepository = tenantRepository.getTenant(applicationId.tenant()).getSessionRepo(); + SessionRepository sessionRepository = tenantRepository.getTenant(applicationId.tenant()).getSessionRepository(); Instant end = Instant.now().plus(waitTime); do { if (sessionRepository.getRemoteSession(sessionId) == null) return true; @@ -690,7 +690,7 @@ public class ApplicationRepository implements com.yahoo.config.provision.Deploye public int deleteExpiredRemoteSessions(Clock clock, Duration expiryTime) { return tenantRepository.getAllTenants() .stream() - .map(tenant -> tenant.getSessionRepo().deleteExpiredRemoteSessions(clock, expiryTime)) + .map(tenant -> tenant.getSessionRepository().deleteExpiredRemoteSessions(clock, expiryTime)) .mapToInt(i -> i) .sum(); } @@ -765,7 +765,7 @@ public class ApplicationRepository implements com.yahoo.config.provision.Deploye } private RemoteSession getRemoteSession(Tenant tenant, long sessionId) { - RemoteSession session = tenant.getSessionRepo().getRemoteSession(sessionId); + RemoteSession session = tenant.getSessionRepository().getRemoteSession(sessionId); if (session == null) throw new NotFoundException("Session " + sessionId + " was not found"); return session; @@ -816,7 +816,7 @@ public class ApplicationRepository implements com.yahoo.config.provision.Deploye private RemoteSession getActiveSession(Tenant tenant, ApplicationId applicationId) { TenantApplications applicationRepo = tenant.getApplicationRepo(); if (applicationRepo.activeApplications().contains(applicationId)) { - return tenant.getSessionRepo().getRemoteSession(applicationRepo.requireActiveSessionOf(applicationId)); + return tenant.getSessionRepository().getRemoteSession(applicationRepo.requireActiveSessionOf(applicationId)); } return null; } diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/maintenance/ApplicationPackageMaintainer.java b/configserver/src/main/java/com/yahoo/vespa/config/server/maintenance/ApplicationPackageMaintainer.java index 543f9c2e303..56496b06c14 100644 --- a/configserver/src/main/java/com/yahoo/vespa/config/server/maintenance/ApplicationPackageMaintainer.java +++ b/configserver/src/main/java/com/yahoo/vespa/config/server/maintenance/ApplicationPackageMaintainer.java @@ -2,8 +2,11 @@ package com.yahoo.vespa.config.server.maintenance; import com.yahoo.cloud.config.ConfigserverConfig; import com.yahoo.config.FileReference; +import com.yahoo.config.provision.ApplicationId; import com.yahoo.vespa.config.server.ApplicationRepository; import com.yahoo.vespa.config.server.session.RemoteSession; +import com.yahoo.vespa.config.server.session.SessionRepository; +import com.yahoo.vespa.config.server.tenant.Tenant; import com.yahoo.vespa.curator.Curator; import com.yahoo.vespa.defaults.Defaults; import com.yahoo.vespa.filedistribution.FileDownloader; @@ -52,24 +55,37 @@ public class ApplicationPackageMaintainer extends ConfigServerMaintainer { log.fine(() -> "Running"); if (! distributeApplicationPackage.value()) return; - try (var fileDownloader = new FileDownloader(createConnectionPool(configserverConfig), downloadDirectory)){ + try (var fileDownloader = new FileDownloader(createConnectionPool(configserverConfig), downloadDirectory)) { for (var applicationId : applicationRepository.listApplications()) { log.fine(() -> "Verifying application package for " + applicationId); RemoteSession session = applicationRepository.getActiveSession(applicationId); FileReference applicationPackage = session.getApplicationPackageReference(); - log.fine(() -> "Verifying application package file reference " + applicationPackage + " for session " + session.getSessionId()); + long sessionId = session.getSessionId(); + log.fine(() -> "Verifying application package file reference " + applicationPackage + " for session " + sessionId); - if (applicationPackage != null && missingOnDisk(applicationPackage)) { - log.fine(() -> "Downloading missing application package for application " + applicationId + " - session " + session.getSessionId()); + if (applicationPackage != null) { + if (missingOnDisk(applicationPackage)) { + log.fine(() -> "Downloading missing application package for application " + applicationId + " - session " + sessionId); - if (fileDownloader.getFile(applicationPackage).isEmpty()) { - log.warning("Failed to download application package for application " + applicationId + " - session " + session.getSessionId()); + if (fileDownloader.getFile(applicationPackage).isEmpty()) { + log.warning("Failed to download application package for application " + applicationId + " - session " + sessionId); + continue; + } } + createLocalSessionIfMissing(applicationId, sessionId); } } } } + private void createLocalSessionIfMissing(ApplicationId applicationId, long sessionId) { + Tenant tenant = applicationRepository.tenantRepository().getTenant(applicationId.tenant()); + SessionRepository sessionRepository = tenant.getSessionRepository(); + if (sessionRepository.getLocalSession(sessionId) == null) + sessionRepository.createLocalSessionUsingDistributedApplicationPackage(sessionId); + } + + private boolean missingOnDisk(FileReference applicationPackageReference) { Set<String> fileReferencesOnDisk = getFileReferencesOnDisk(downloadDirectory); return ! fileReferencesOnDisk.contains(applicationPackageReference.value()); diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/session/SessionRepository.java b/configserver/src/main/java/com/yahoo/vespa/config/server/session/SessionRepository.java index c7dc295c42d..7e22e4b227e 100644 --- a/configserver/src/main/java/com/yahoo/vespa/config/server/session/SessionRepository.java +++ b/configserver/src/main/java/com/yahoo/vespa/config/server/session/SessionRepository.java @@ -120,9 +120,8 @@ public class SessionRepository { public synchronized void addSession(LocalSession session) { localSessionCache.addSession(session); - 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); + Curator.FileCache fileCache = curator.createFileCache(getSessionStatePath(sessionId).getAbsolute(), false); localSessionStateWatchers.put(sessionId, new LocalSessionStateWatcher(fileCache, session, this, zkWatcherExecutor)); } @@ -319,8 +318,7 @@ public class SessionRepository { public void sessionAdded(long sessionId) { log.log(Level.FINE, () -> "Adding session to SessionRepository: " + sessionId); RemoteSession session = createRemoteSession(sessionId); - Path sessionPath = sessionsPath.append(String.valueOf(sessionId)); - Curator.FileCache fileCache = curator.createFileCache(sessionPath.append(ConfigCurator.SESSIONSTATE_ZK_SUBPATH).getAbsolute(), false); + Curator.FileCache fileCache = curator.createFileCache(getSessionStatePath(sessionId).getAbsolute(), false); fileCache.addListener(this::nodeChanged); loadSessionIfActive(session); addRemoteSession(session); @@ -489,9 +487,9 @@ public class SessionRepository { * 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, Optional<Long> currentlyActiveSessionId) { + private LocalSession createLocalSession(File applicationFile, ApplicationId applicationId, long sessionId) { try { + Optional<Long> currentlyActiveSessionId = getActiveSessionId(applicationId); ApplicationPackage applicationPackage = createApplicationPackage(applicationFile, applicationId, sessionId, currentlyActiveSessionId, false); SessionZooKeeperClient sessionZooKeeperClient = createSessionZooKeeperClient(sessionId); @@ -529,7 +527,7 @@ public class SessionRepository { /** * Returns a new session instance for the given session id. */ - Optional<LocalSession> createLocalSessionUsingDistributedApplicationPackage(long sessionId) { + public Optional<LocalSession> createLocalSessionUsingDistributedApplicationPackage(long sessionId) { if (applicationRepo.hasLocalSession(sessionId)) { log.log(Level.FINE, "Local session for session id " + sessionId + " already exists"); return Optional.of(createSessionFromId(sessionId)); @@ -552,10 +550,9 @@ public class SessionRepository { return Optional.empty(); } ApplicationId applicationId = sessionZKClient.readApplicationId(); - return Optional.of(createLocalSession(sessionDir, - applicationId, - sessionId, - getActiveSessionId(applicationId))); + LocalSession localSession = createLocalSession(sessionDir, applicationId, sessionId); + addSession(localSession); + return Optional.of(localSession); } return Optional.empty(); } @@ -571,10 +568,13 @@ public class SessionRepository { return new SessionCounter(componentRegistry.getConfigCurator(), tenantName).nextSessionId(); } - private Path getSessionPath(long sessionId) { + public Path getSessionPath(long sessionId) { return sessionsPath.append(String.valueOf(sessionId)); } + Path getSessionStatePath(long sessionId) { + return getSessionPath(sessionId).append(ConfigCurator.SESSIONSTATE_ZK_SUBPATH); + } private SessionZooKeeperClient createSessionZooKeeperClient(long sessionId) { String serverId = componentRegistry.getConfigserverConfig().serverId(); 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 f7c8ae9d5c3..cbcb96d0b36 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 @@ -66,10 +66,6 @@ public class Tenant implements TenantHandlerProvider { return requestHandler; } - public SessionRepository getSessionRepo() { - return sessionRepository; - } - public TenantName getName() { return name; } diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/ApplicationRepositoryTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/ApplicationRepositoryTest.java index f0aa38a228e..8745a9bf596 100644 --- a/configserver/src/test/java/com/yahoo/vespa/config/server/ApplicationRepositoryTest.java +++ b/configserver/src/test/java/com/yahoo/vespa/config/server/ApplicationRepositoryTest.java @@ -4,7 +4,6 @@ package com.yahoo.vespa.config.server; import com.yahoo.cloud.config.ConfigserverConfig; import com.yahoo.component.Version; import com.yahoo.config.ConfigInstance; -import com.yahoo.config.FileReference; import com.yahoo.config.SimpletypesConfig; import com.yahoo.config.application.api.ApplicationMetaData; import com.yahoo.config.model.NullConfigModelRegistry; @@ -304,15 +303,16 @@ public class ApplicationRepositoryTest { public void delete() { TenantName tenantName = applicationId().tenant(); Tenant tenant = tenantRepository.getTenant(tenantName); + SessionRepository sessionRepository = tenant.getSessionRepository(); { PrepareResult result = deployApp(testApp); long sessionId = result.sessionId(); - LocalSession applicationData = tenant.getSessionRepository().getLocalSession(sessionId); + LocalSession applicationData = sessionRepository.getLocalSession(sessionId); assertNotNull(applicationData); assertNotNull(applicationData.getApplicationId()); - assertNotNull(tenant.getSessionRepo().getLocalSession(sessionId)); + assertNotNull(sessionRepository.getLocalSession(sessionId)); assertNotNull(applicationRepository.getActiveSession(applicationId())); - String sessionNode = TenantRepository.getSessionsPath(tenantName).append(String.valueOf(sessionId)).getAbsolute(); + String sessionNode = sessionRepository.getSessionPath(sessionId).getAbsolute(); assertTrue(configCurator.exists(sessionNode)); TenantFileSystemDirs tenantFileSystemDirs = tenant.getApplicationRepo().getTenantFileSystemDirs(); File sessionFile = new File(tenantFileSystemDirs.sessionsPath(), String.valueOf(sessionId)); @@ -321,8 +321,8 @@ public class ApplicationRepositoryTest { // Delete app and verify that it has been deleted from repos and provisioner assertTrue(applicationRepository.delete(applicationId())); assertNull(applicationRepository.getActiveSession(applicationId())); - assertNull(tenant.getSessionRepository().getLocalSession(sessionId)); - assertNull(tenant.getSessionRepo().getLocalSession(sessionId)); + assertNull(sessionRepository.getLocalSession(sessionId)); + assertNull(sessionRepository.getLocalSession(sessionId)); assertTrue(provisioner.removed); assertEquals(tenant.getName(), provisioner.lastApplicationId.tenant()); assertEquals(applicationId(), provisioner.lastApplicationId); @@ -364,7 +364,7 @@ public class ApplicationRepositoryTest { // A new delete should cleanup and be successful RemoteSession activeSession = applicationRepository.getActiveSession(applicationId()); assertNull(activeSession); - assertNull(tenant.getSessionRepo().getLocalSession(prepareResult.sessionId())); + assertNull(sessionRepository.getLocalSession(prepareResult.sessionId())); assertTrue(applicationRepository.delete(applicationId())); } diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/HostHandlerTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/HostHandlerTest.java index 37181abfcf4..d8724cb4db2 100644 --- a/configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/HostHandlerTest.java +++ b/configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/HostHandlerTest.java @@ -38,8 +38,9 @@ import java.util.Collections; */ // TODO: Try to move testing to ApplicationRepositoryTest and avoid all the low-level setup code here public class HostHandlerTest { + private static final String urlPrefix = "http://myhost:14000/application/v2/host/"; - private static File testApp = new File("src/test/apps/app"); + private static final File testApp = new File("src/test/apps/app"); private HostHandler handler; private final static TenantName mytenant = TenantName.from("mytenant"); @@ -55,7 +56,7 @@ public class HostHandlerTest { TestComponentRegistry componentRegistry = new TestComponentRegistry.Builder() .modelFactoryRegistry(new ModelFactoryRegistry(Collections.singletonList(new VespaModelFactory(new NullConfigModelRegistry())))) .build(); - tenant.getSessionRepo().addRemoteSession(new RemoteSession(tenant.getName(), sessionId, componentRegistry, new MockSessionZKClient(app))); + tenant.getSessionRepository().addRemoteSession(new RemoteSession(tenant.getName(), sessionId, componentRegistry, new MockSessionZKClient(app))); } @Before diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/session/SessionRepositoryTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/session/SessionRepositoryTest.java index b9e872261c5..13a27e570c2 100644 --- a/configserver/src/test/java/com/yahoo/vespa/config/server/session/SessionRepositoryTest.java +++ b/configserver/src/test/java/com/yahoo/vespa/config/server/session/SessionRepositoryTest.java @@ -10,9 +10,7 @@ import com.yahoo.vespa.config.server.GlobalComponentRegistry; import com.yahoo.vespa.config.server.TestComponentRegistry; import com.yahoo.vespa.config.server.application.OrchestratorMock; import com.yahoo.vespa.config.server.http.SessionHandlerTest; -import com.yahoo.vespa.config.server.tenant.Tenant; 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.curator.mock.MockCurator; import com.yahoo.vespa.flags.FlagSource; @@ -44,6 +42,7 @@ public class SessionRepositoryTest { private MockCurator curator; private TenantRepository tenantRepository; private ApplicationRepository applicationRepository; + private SessionRepository sessionRepository; @Rule public TemporaryFolder temporaryFolder = new TemporaryFolder(); @@ -71,6 +70,7 @@ public class SessionRepositoryTest { new SessionHandlerTest.MockProvisioner(), new OrchestratorMock(), Clock.systemUTC()); + sessionRepository = tenantRepository.getTenant(tenantName).getSessionRepository(); } @Test @@ -78,7 +78,6 @@ public class SessionRepositoryTest { setup(); long firstSessionId = deploy(); long secondSessionId = deploy(); - SessionRepository sessionRepository = tenantRepository.getTenant(tenantName).getSessionRepository(); assertNotNull(sessionRepository.getLocalSession(firstSessionId)); assertNotNull(sessionRepository.getLocalSession(secondSessionId)); assertNull(sessionRepository.getLocalSession(secondSessionId + 1)); @@ -96,7 +95,6 @@ public class SessionRepositoryTest { long firstSessionId = deploy(); long secondSessionId = deploy(); - SessionRepository sessionRepository = tenantRepository.getTenant(tenantName).getSessionRepository(); assertNotNull(sessionRepository.getLocalSession(firstSessionId)); assertNotNull(sessionRepository.getLocalSession(secondSessionId)); assertNull(sessionRepository.getLocalSession(secondSessionId + 1)); @@ -130,7 +128,6 @@ public class SessionRepositoryTest { com.yahoo.path.Path session = TenantRepository.getSessionsPath(tenantName).append("" + sessionId); curator.delete(session); assertSessionRemoved(sessionId); - SessionRepository sessionRepository = tenantRepository.getTenant(tenantName).getSessionRepository(); assertNull(sessionRepository.getRemoteSession(sessionId)); } @@ -145,21 +142,18 @@ public class SessionRepositoryTest { TenantName mytenant = TenantName.from("mytenant"); curator.set(TenantRepository.getApplicationsPath(mytenant).append("mytenant:appX:default"), new byte[0]); // Invalid data tenantRepository.addTenant(mytenant); - Tenant tenant = tenantRepository.getTenant(mytenant); curator.create(TenantRepository.getSessionsPath(mytenant)); - SessionRepository sessionRepository = tenant.getSessionRepo(); assertThat(sessionRepository.getRemoteSessions().size(), is(0)); - createSession(sessionId, true, mytenant); + createSession(sessionId, true); assertThat(sessionRepository.getRemoteSessions().size(), is(1)); } private void createSession(long sessionId, boolean wait) { - createSession(sessionId, wait, tenantName); + createSession(sessionId, wait, sessionRepository); } - private void createSession(long sessionId, boolean wait, TenantName tenantName) { - com.yahoo.path.Path sessionsPath = TenantRepository.getSessionsPath(tenantName); - SessionZooKeeperClient zkc = new SessionZooKeeperClient(curator, sessionsPath.append(String.valueOf(sessionId))); + private void createSession(long sessionId, boolean wait, SessionRepository sessionRepository) { + SessionZooKeeperClient zkc = new SessionZooKeeperClient(curator, sessionRepository.getSessionPath(sessionId)); zkc.createNewSession(Instant.now()); if (wait) { Curator.CompletionWaiter waiter = zkc.getUploadWaiter(); @@ -168,14 +162,13 @@ public class SessionRepositoryTest { } private void assertStatusChange(long sessionId, Session.Status status) throws Exception { - com.yahoo.path.Path statePath = TenantRepository.getSessionsPath(tenantName).append("" + sessionId).append(ConfigCurator.SESSIONSTATE_ZK_SUBPATH); + com.yahoo.path.Path statePath = sessionRepository.getSessionStatePath(sessionId); curator.create(statePath); curator.framework().setData().forPath(statePath.getAbsolute(), Utf8.toBytes(status.toString())); assertRemoteSessionStatus(sessionId, status); } private void assertSessionRemoved(long sessionId) { - SessionRepository sessionRepository = tenantRepository.getTenant(tenantName).getSessionRepository(); waitFor(p -> sessionRepository.getRemoteSession(sessionId) == null, sessionId); assertNull(sessionRepository.getRemoteSession(sessionId)); } @@ -185,7 +178,6 @@ public class SessionRepositoryTest { } private void assertRemoteSessionStatus(long sessionId, Session.Status status) { - SessionRepository sessionRepository = tenantRepository.getTenant(tenantName).getSessionRepository(); waitFor(p -> sessionRepository.getRemoteSession(sessionId) != null && sessionRepository.getRemoteSession(sessionId).getStatus() == status, sessionId); assertNotNull(sessionRepository.getRemoteSession(sessionId)); |