From bc35278684908612aa67b8c6fa8664a96fb871d3 Mon Sep 17 00:00:00 2001
From: Jon Chambers <jon@signal.org>
Date: Wed, 30 Aug 2023 13:06:22 -0400
Subject: [PATCH] Drop the old `AccountCleaner`

---
 .../textsecuregcm/storage/AccountCleaner.java | 66 ---------------
 .../workers/CrawlAccountsCommand.java         | 13 ---
 .../storage/AccountCleanerTest.java           | 83 -------------------
 3 files changed, 162 deletions(-)
 delete mode 100644 service/src/main/java/org/whispersystems/textsecuregcm/storage/AccountCleaner.java
 delete mode 100644 service/src/test/java/org/whispersystems/textsecuregcm/storage/AccountCleanerTest.java

diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/storage/AccountCleaner.java b/service/src/main/java/org/whispersystems/textsecuregcm/storage/AccountCleaner.java
deleted file mode 100644
index 96c3040cf..000000000
--- a/service/src/main/java/org/whispersystems/textsecuregcm/storage/AccountCleaner.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright 2013-2020 Signal Messenger, LLC
- * SPDX-License-Identifier: AGPL-3.0-only
- */
-package org.whispersystems.textsecuregcm.storage;
-
-import static org.whispersystems.textsecuregcm.metrics.MetricsUtil.name;
-
-import io.micrometer.core.instrument.Counter;
-import io.micrometer.core.instrument.Metrics;
-import java.util.List;
-import java.util.Optional;
-import java.util.UUID;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.TimeUnit;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class AccountCleaner extends AccountDatabaseCrawlerListener {
-
-  private static final Logger log = LoggerFactory.getLogger(AccountCleaner.class);
-
-  private static final Counter DELETED_ACCOUNT_COUNTER = Metrics.counter(name(AccountCleaner.class, "deletedAccounts"));
-
-  private final AccountsManager accountsManager;
-
-  public AccountCleaner(final AccountsManager accountsManager) {
-    this.accountsManager = accountsManager;
-  }
-
-  @Override
-  public void onCrawlStart() {
-  }
-
-  @Override
-  public void onCrawlEnd() {
-  }
-
-  @Override
-  protected void onCrawlChunk(Optional<UUID> fromUuid, List<Account> chunkAccounts) {
-    final List<CompletableFuture<Void>> deletionFutures = chunkAccounts.stream()
-        .filter(AccountCleaner::isExpired)
-        .map(account -> accountsManager.delete(account, AccountsManager.DeletionReason.EXPIRED)
-            .whenComplete((ignored, throwable) -> {
-              if (throwable != null) {
-                log.warn("Failed to delete account {}", account.getUuid(), throwable);
-              } else {
-                DELETED_ACCOUNT_COUNTER.increment();
-              }
-            }))
-        .toList();
-
-    try {
-      CompletableFuture.allOf(deletionFutures.toArray(new CompletableFuture[0]))
-          .orTimeout(10, TimeUnit.MINUTES)
-          .join();
-    } catch (final Exception e) {
-      log.debug("Failed to delete one or more accounts in chunk", e);
-    }
-  }
-
-  private static boolean isExpired(Account account) {
-    return account.getLastSeen() + TimeUnit.DAYS.toMillis(180) < System.currentTimeMillis();
-  }
-
-}
diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/workers/CrawlAccountsCommand.java b/service/src/main/java/org/whispersystems/textsecuregcm/workers/CrawlAccountsCommand.java
index fb0c9ede0..4f9f06b05 100644
--- a/service/src/main/java/org/whispersystems/textsecuregcm/workers/CrawlAccountsCommand.java
+++ b/service/src/main/java/org/whispersystems/textsecuregcm/workers/CrawlAccountsCommand.java
@@ -25,7 +25,6 @@ import org.whispersystems.textsecuregcm.WhisperServerConfiguration;
 import org.whispersystems.textsecuregcm.configuration.dynamic.DynamicConfiguration;
 import org.whispersystems.textsecuregcm.metrics.MetricsUtil;
 import org.whispersystems.textsecuregcm.redis.FaultTolerantRedisCluster;
-import org.whispersystems.textsecuregcm.storage.AccountCleaner;
 import org.whispersystems.textsecuregcm.storage.AccountDatabaseCrawler;
 import org.whispersystems.textsecuregcm.storage.AccountDatabaseCrawlerCache;
 import org.whispersystems.textsecuregcm.storage.AccountDatabaseCrawlerListener;
@@ -43,7 +42,6 @@ public class CrawlAccountsCommand extends EnvironmentCommand<WhisperServerConfig
 
   public enum CrawlType implements ArgumentType<CrawlType> {
     GENERAL_PURPOSE,
-    ACCOUNT_CLEANER,
     ;
 
     @Override
@@ -124,17 +122,6 @@ public class CrawlAccountsCommand extends EnvironmentCommand<WhisperServerConfig
             configuration.getAccountDatabaseCrawlerConfiguration().getChunkSize()
         );
       }
-      case ACCOUNT_CLEANER -> {
-        final AccountDatabaseCrawlerCache accountDatabaseCrawlerCache = new AccountDatabaseCrawlerCache(
-            cacheCluster, AccountDatabaseCrawlerCache.ACCOUNT_CLEANER_PREFIX);
-
-        yield new AccountDatabaseCrawler("Account cleaner crawler",
-            accountsManager,
-            accountDatabaseCrawlerCache,
-            List.of(new AccountCleaner(accountsManager)),
-            configuration.getAccountDatabaseCrawlerConfiguration().getChunkSize()
-        );
-      }
     };
 
     environment.lifecycle().manage(new CommandStopListener(configuration.getCommandStopListener()));
diff --git a/service/src/test/java/org/whispersystems/textsecuregcm/storage/AccountCleanerTest.java b/service/src/test/java/org/whispersystems/textsecuregcm/storage/AccountCleanerTest.java
deleted file mode 100644
index b79bf4f0a..000000000
--- a/service/src/test/java/org/whispersystems/textsecuregcm/storage/AccountCleanerTest.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright 2013-2022 Signal Messenger, LLC
- * SPDX-License-Identifier: AGPL-3.0-only
- */
-package org.whispersystems.textsecuregcm.storage;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.when;
-
-import java.util.Arrays;
-import java.util.Optional;
-import java.util.UUID;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.TimeUnit;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.whispersystems.textsecuregcm.storage.AccountsManager.DeletionReason;
-
-class AccountCleanerTest {
-
-  private final AccountsManager accountsManager = mock(AccountsManager.class);
-
-  private final Account deletedDisabledAccount   = mock(Account.class);
-  private final Account undeletedDisabledAccount = mock(Account.class);
-  private final Account undeletedEnabledAccount  = mock(Account.class);
-
-  private final Device  deletedDisabledDevice    = mock(Device.class );
-  private final Device  undeletedDisabledDevice  = mock(Device.class );
-  private final Device  undeletedEnabledDevice   = mock(Device.class );
-
-  @BeforeEach
-  void setup() {
-    when(accountsManager.delete(any(), any())).thenReturn(CompletableFuture.completedFuture(null));
-
-    when(deletedDisabledDevice.isEnabled()).thenReturn(false);
-    when(deletedDisabledDevice.getGcmId()).thenReturn(null);
-    when(deletedDisabledDevice.getApnId()).thenReturn(null);
-    when(deletedDisabledDevice.getVoipApnId()).thenReturn(null);
-    when(deletedDisabledDevice.getFetchesMessages()).thenReturn(false);
-    when(deletedDisabledAccount.isEnabled()).thenReturn(false);
-    when(deletedDisabledAccount.getLastSeen()).thenReturn(System.currentTimeMillis() - TimeUnit.DAYS.toMillis(1000));
-    when(deletedDisabledAccount.getMasterDevice()).thenReturn(Optional.of(deletedDisabledDevice));
-    when(deletedDisabledAccount.getNumber()).thenReturn("+14151231234");
-    when(deletedDisabledAccount.getUuid()).thenReturn(UUID.randomUUID());
-
-    when(undeletedDisabledDevice.isEnabled()).thenReturn(false);
-    when(undeletedDisabledDevice.getGcmId()).thenReturn("foo");
-    when(undeletedDisabledAccount.isEnabled()).thenReturn(false);
-    when(undeletedDisabledAccount.getLastSeen()).thenReturn(System.currentTimeMillis() - TimeUnit.DAYS.toMillis(181));
-    when(undeletedDisabledAccount.getMasterDevice()).thenReturn(Optional.of(undeletedDisabledDevice));
-    when(undeletedDisabledAccount.getNumber()).thenReturn("+14152222222");
-    when(undeletedDisabledAccount.getUuid()).thenReturn(UUID.randomUUID());
-
-    when(undeletedEnabledDevice.isEnabled()).thenReturn(true);
-    when(undeletedEnabledDevice.getApnId()).thenReturn("bar");
-    when(undeletedEnabledAccount.isEnabled()).thenReturn(true);
-    when(undeletedEnabledAccount.getMasterDevice()).thenReturn(Optional.of(undeletedEnabledDevice));
-    when(undeletedEnabledAccount.getNumber()).thenReturn("+14153333333");
-    when(undeletedEnabledAccount.getLastSeen()).thenReturn(System.currentTimeMillis() - TimeUnit.DAYS.toMillis(179));
-    when(undeletedEnabledAccount.getUuid()).thenReturn(UUID.randomUUID());
-  }
-
-  @Test
-  void testAccounts() {
-    AccountCleaner accountCleaner = new AccountCleaner(accountsManager);
-    accountCleaner.onCrawlStart();
-    accountCleaner.timeAndProcessCrawlChunk(Optional.empty(),
-        Arrays.asList(deletedDisabledAccount, undeletedDisabledAccount, undeletedEnabledAccount));
-    accountCleaner.onCrawlEnd();
-
-    verify(accountsManager).delete(deletedDisabledAccount, DeletionReason.EXPIRED);
-    verify(accountsManager).delete(undeletedDisabledAccount, DeletionReason.EXPIRED);
-    verify(accountsManager, never()).delete(eq(undeletedEnabledAccount), any());
-
-    verifyNoMoreInteractions(accountsManager);
-  }
-
-}
-- 
GitLab