WorkspaceFsBackupScheduler { @ScheduleRate(initialDelay = 1, period = 1, unit = TimeUnit.MINUTES) public void scheduleBackup() { for (String workspaceId : workspaceRuntimes.getRuntimesIds()) { try { WorkspaceImpl workspace = workspaceManager.getWorkspace(workspaceId); WorkspaceRuntimeImpl runtime = workspace.getRuntime(); if (workspace.getStatus().equals(WorkspaceStatus.RUNNING)) { if (isTimeToBackup(workspaceId)) { executor.execute( () -> { if (workspacesBackupsInProgress.putIfAbsent(workspaceId, workspaceId) == null) { try { String environmentType = workspace .getConfig() .getEnvironments() .get(runtime.getActiveEnv()) .getRecipe() .getType(); EnvironmentBackupManager backupManager = backupManagers.get(environmentType); if (backupManager == null) { throw new ServerException( "Backing up of environment of type " + environmentType + " is not implemented."); } backupManager.backupWorkspace(workspaceId); lastWorkspaceSynchronizationTime.put(workspaceId, System.currentTimeMillis()); } catch (NotFoundException ignore) { } catch (Exception e) { LOG.error(e.getLocalizedMessage(), e); } finally { workspacesBackupsInProgress.remove(workspaceId); } } }); } } } catch (NotFoundException e) { } catch (ServerException e) { LOG.error(e.getLocalizedMessage(), e); } } } @Inject  WorkspaceFsBackupScheduler(
      Map<String, EnvironmentBackupManager> backupManagers,
      WorkspaceRuntimes workspaceRuntimes,
      @Named("machine.backup.backup_period_second") long syncTimeoutSecond,
      WorkspaceManager workspaceManager); @ScheduleRate(initialDelay = 1, period = 1, unit = TimeUnit.MINUTES) void scheduleBackup();  }
@Test public void shouldBackupAllWorkspaces() throws Exception { scheduler.scheduleBackup(); for (String id : ids) { verify(backupManager, timeout(2000)).backupWorkspace(id); } }
@Test public void shouldBackupOtherWorkspacesIfBackupOfPreviousFails() throws Exception { addWorkspace("testWsId3"); addWorkspace("testWsId4"); addWorkspace("testWsId5"); doThrow(new ServerException("server exception")) .when(backupManager) .backupWorkspace(eq("testWsId3")); scheduler.scheduleBackup(); verify(backupManager, timeout(1000)).backupWorkspace(WORKSPACE_ID_1); verify(backupManager, timeout(1000)).backupWorkspace(WORKSPACE_ID_2); verify(backupManager, timeout(1000)).backupWorkspace("testWsId3"); verify(backupManager, timeout(1000)).backupWorkspace("testWsId4"); verify(backupManager, timeout(1000)).backupWorkspace("testWsId5"); }
@Test public void shouldNotBackupWsIfBackupManagerNotFound() throws Exception { ids.clear(); String wsId = "testWsId"; WorkspaceImpl workspace = addWorkspace(wsId); workspace .getConfig() .getEnvironments() .values() .iterator() .next() .getRecipe() .setType("somethingElse"); scheduler.scheduleBackup(); verify(backupManager, after(2000).never()).backupWorkspace(wsId); }
@Test public void shouldNotBackupWSWithNonRunningStatus() throws Exception { WorkspaceImpl wsInSnapshottingState = addWorkspace("ws3"); when(workspaceManager.getWorkspace("ws3")).thenReturn(wsInSnapshottingState); when(wsInSnapshottingState.getStatus()).thenReturn(WorkspaceStatus.SNAPSHOTTING); WorkspaceImpl wsInStoppingState = addWorkspace("ws4"); when(workspaceManager.getWorkspace("ws4")).thenReturn(wsInStoppingState); when(wsInStoppingState.getStatus()).thenReturn(WorkspaceStatus.STOPPING); WorkspaceImpl wsInStartingState = addWorkspace("ws5"); when(workspaceManager.getWorkspace("ws5")).thenReturn(wsInStartingState); when(wsInStartingState.getStatus()).thenReturn(WorkspaceStatus.STARTING); scheduler.scheduleBackup(); verify(backupManager, timeout(2000)).backupWorkspace(WORKSPACE_ID_1); verify(backupManager, timeout(2000)).backupWorkspace(WORKSPACE_ID_2); verify(backupManager, after(2000).never()).backupWorkspace("ws3"); verify(backupManager, never()).backupWorkspace("ws4"); verify(backupManager, never()).backupWorkspace("ws5"); }
@Test public void shouldBackupMachineFsIfLastSyncTimeoutIsExpired() throws Exception { ids.clear(); addWorkspace("ws3"); scheduler = spy( new WorkspaceFsBackupScheduler( Collections.singletonMap(ENV_TYPE, backupManager), workspaceRuntimes, 0, workspaceManager)); scheduler.scheduleBackup(); verify(backupManager, timeout(1000)).backupWorkspace(eq("ws3")); Thread.sleep(100); scheduler.scheduleBackup(); verify(workspaceRuntimes, times(2)).getRuntimesIds(); verify(backupManager, timeout(2000).times(2)).backupWorkspace(eq("ws3")); }
@Test public void shouldNotBackupMachineFsIfPreviousBackupIsStillRunning() throws Exception { ids.clear(); addWorkspace("ws3"); scheduler = spy( new WorkspaceFsBackupScheduler( Collections.singletonMap(ENV_TYPE, backupManager), workspaceRuntimes, 0, workspaceManager)); doAnswer( invocation -> { sleep(FAKE_BACKUP_TIME_MS); return null; }) .when(backupManager) .backupWorkspace("ws3"); scheduler.scheduleBackup(); sleep(FAKE_BACKUP_TIME_MS / 2); scheduler.scheduleBackup(); verify(workspaceRuntimes, times(2)).getRuntimesIds(); verify(backupManager, timeout(2000)).backupWorkspace(eq("ws3")); }