AsyncStoragePodWatcher { @ScheduleDelay( unit = MINUTES, initialDelay = 1, delayParameterName = "che.infra.kubernetes.async.storage.shutdown_check_period_min") public void check() { if (isAsyncStoragePodCanBeRun && shutdownTimeoutSec > 0) { for (User user : iterateLazily((maxItems, skipCount) -> userManager.getAll(maxItems, skipCount))) { try { String owner = user.getId(); Map<String, String> preferences = preferenceManager.find(owner); String lastTimeAccess = preferences.get(LAST_ACTIVITY_TIME); String namespace = preferences.get(LAST_ACTIVE_INFRASTRUCTURE_NAMESPACE); if (isNullOrEmpty(namespace) || isNullOrEmpty(lastTimeAccess) || !runtimes.getInProgress(owner).isEmpty()) { continue; } long lastTimeAccessSec = parseLong(lastTimeAccess); Instant expectedShutdownAfter = ofEpochSecond(lastTimeAccessSec).plusSeconds(shutdownTimeoutSec); if (now().isAfter(expectedShutdownAfter)) { removeAsyncStoragePodWithoutDeployment(namespace); RollableScalableResource<Deployment, DoneableDeployment> doneableResource = kubernetesClientFactory .create() .apps() .deployments() .inNamespace(namespace) .withName(ASYNC_STORAGE); if (doneableResource.get() != null) { doneableResource.delete(); } } } catch (InfrastructureException | ServerException e) { LOG.error(e.getMessage(), e); } } } } @Inject  AsyncStoragePodWatcher(
      KubernetesClientFactory kubernetesClientFactory,
      UserManager userManager,
      PreferenceManager preferenceManager,
      WorkspaceRuntimes runtimes,
      @Named("che.infra.kubernetes.async.storage.shutdown_timeout_min") long shutdownTimeoutMin,
      @Named("che.infra.kubernetes.pvc.strategy") String pvcStrategy,
      @Named("che.infra.kubernetes.namespace.allow_user_defined")
          boolean allowUserDefinedNamespaces,
      @Nullable @Named("che.infra.kubernetes.namespace.default") String defaultNamespaceName,
      @Named("che.limits.user.workspaces.run.count") int runtimesPerUser); @ScheduleDelay( unit = MINUTES, initialDelay = 1, delayParameterName = "che.infra.kubernetes.async.storage.shutdown_check_period_min") void check();  }
@Test public void shouldDeleteAsyncStorageDeployment() throws Exception { AsyncStoragePodWatcher watcher = new AsyncStoragePodWatcher( kubernetesClientFactory, userManager, preferenceManager, runtimes, 1, COMMON_STRATEGY, false, "<username>", 1); when(runtimes.getInProgress(USER_ID)).thenReturn(emptySet()); ObjectMeta meta = new ObjectMeta(); meta.setName(ASYNC_STORAGE); Deployment deployment = new Deployment(); deployment.setMetadata(meta); when(deploymentResource.get()).thenReturn(deployment); watcher.check(); verify(preferenceManager).find(USER_ID); verify(deploymentResource).delete(); }
@Test public void shouldNotDeleteAsyncStoragePodIfTooEarly() throws Exception { AsyncStoragePodWatcher watcher = new AsyncStoragePodWatcher( kubernetesClientFactory, userManager, preferenceManager, runtimes, 10, COMMON_STRATEGY, false, "<username>", 1); long epochSecond = now().getEpochSecond(); userPref.put(Constants.LAST_ACTIVITY_TIME, Long.toString(epochSecond)); watcher.check(); verify(preferenceManager).find(USER_ID); verifyNoMoreInteractions(kubernetesClientFactory); verifyNoMoreInteractions(deploymentResource); }
@Test public void shouldNotDeleteAsyncStoragePodIfHasActiveRuntime() throws Exception { AsyncStoragePodWatcher watcher = new AsyncStoragePodWatcher( kubernetesClientFactory, userManager, preferenceManager, runtimes, 1, COMMON_STRATEGY, false, "<username>", 1); InternalRuntime runtime = mock(InternalRuntime.class); when(runtime.getOwner()).thenReturn(USER_ID); when(runtimes.getInProgress(USER_ID)).thenReturn(singleton(WORKSPACE_ID)); when(runtimes.getInternalRuntime(WORKSPACE_ID)).thenReturn(runtime); Page<UserImpl> userPage = new Page<>(Collections.singleton(user), 0, 1, 1); when(userManager.getAll(anyInt(), anyLong())).thenReturn(userPage); watcher.check(); verify(preferenceManager).find(USER_ID); verifyNoMoreInteractions(kubernetesClientFactory); verifyNoMoreInteractions(deploymentResource); }
@Test public void shouldNotDeleteAsyncStoragePodIfNoRecord() throws Exception { AsyncStoragePodWatcher watcher = new AsyncStoragePodWatcher( kubernetesClientFactory, userManager, preferenceManager, runtimes, 1, COMMON_STRATEGY, false, "<username>", 1); when(preferenceManager.find(USER_ID)).thenReturn(emptyMap()); watcher.check(); verify(preferenceManager).find(USER_ID); verifyNoMoreInteractions(kubernetesClientFactory); verifyNoMoreInteractions(deploymentResource); }
@Test public void shouldDoNothingIfNotCommonPvcStrategy() throws Exception { AsyncStoragePodWatcher watcher = new AsyncStoragePodWatcher( kubernetesClientFactory, userManager, preferenceManager, runtimes, 1, "my-own-strategy", false, "<username>", 1); when(preferenceManager.find(USER_ID)).thenReturn(emptyMap()); watcher.check(); verifyNoMoreInteractions(preferenceManager); verifyNoMoreInteractions(kubernetesClientFactory); verifyNoMoreInteractions(deploymentResource); }
@Test public void shouldDoNothingIfAllowedUserDefinedNamespaces() throws Exception { AsyncStoragePodWatcher watcher = new AsyncStoragePodWatcher( kubernetesClientFactory, userManager, preferenceManager, runtimes, 1, "my-own-strategy", true, "<username>", 1); when(preferenceManager.find(USER_ID)).thenReturn(emptyMap()); watcher.check(); verifyNoMoreInteractions(preferenceManager); verifyNoMoreInteractions(kubernetesClientFactory); verifyNoMoreInteractions(deploymentResource); }
@Test public void shouldDoNothingIfDefaultNamespaceNotCorrect() throws Exception { AsyncStoragePodWatcher watcher = new AsyncStoragePodWatcher( kubernetesClientFactory, userManager, preferenceManager, runtimes, 1, "my-own-strategy", true, "<foo-bar>", 1); when(preferenceManager.find(USER_ID)).thenReturn(emptyMap()); watcher.check(); verifyNoMoreInteractions(preferenceManager); verifyNoMoreInteractions(kubernetesClientFactory); verifyNoMoreInteractions(deploymentResource); }
@Test public void shouldDoNothingIfAllowMoreThanOneRuntime() throws Exception { AsyncStoragePodWatcher watcher = new AsyncStoragePodWatcher( kubernetesClientFactory, userManager, preferenceManager, runtimes, 1, "my-own-strategy", true, "<foo-bar>", 2); when(preferenceManager.find(USER_ID)).thenReturn(emptyMap()); watcher.check(); verifyNoMoreInteractions(preferenceManager); verifyNoMoreInteractions(kubernetesClientFactory); verifyNoMoreInteractions(deploymentResource); }
@Test public void shouldDoNothingIfShutdownTimeSetToZero() throws Exception { AsyncStoragePodWatcher watcher = new AsyncStoragePodWatcher( kubernetesClientFactory, userManager, preferenceManager, runtimes, 0, COMMON_STRATEGY, false, "<username>", 1); when(preferenceManager.find(USER_ID)).thenReturn(emptyMap()); watcher.check(); verifyNoMoreInteractions(preferenceManager); verifyNoMoreInteractions(kubernetesClientFactory); verifyNoMoreInteractions(deploymentResource); }