diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/WhisperServerService.java b/service/src/main/java/org/whispersystems/textsecuregcm/WhisperServerService.java index 5d62486f5..e090b356f 100644 --- a/service/src/main/java/org/whispersystems/textsecuregcm/WhisperServerService.java +++ b/service/src/main/java/org/whispersystems/textsecuregcm/WhisperServerService.java @@ -487,7 +487,8 @@ public class WhisperServerService extends Application getExperimentEnrollmentConfiguration( final String experimentName) { return Optional.ofNullable(experiments.get(experimentName)); @@ -94,4 +97,8 @@ public class DynamicConfiguration { public DynamicRateLimitChallengeConfiguration getRateLimitChallengeConfiguration() { return rateLimitChallenge; } + + public DynamicDirectoryReconcilerConfiguration getDirectoryReconcilerConfiguration() { + return directoryReconciler; + } } diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/configuration/dynamic/DynamicDirectoryReconcilerConfiguration.java b/service/src/main/java/org/whispersystems/textsecuregcm/configuration/dynamic/DynamicDirectoryReconcilerConfiguration.java new file mode 100644 index 000000000..bcd4716ea --- /dev/null +++ b/service/src/main/java/org/whispersystems/textsecuregcm/configuration/dynamic/DynamicDirectoryReconcilerConfiguration.java @@ -0,0 +1,18 @@ +/* + * Copyright 2021 Signal Messenger, LLC + * SPDX-License-Identifier: AGPL-3.0-only + */ + +package org.whispersystems.textsecuregcm.configuration.dynamic; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public class DynamicDirectoryReconcilerConfiguration { + + @JsonProperty + private boolean enabled = true; + + public boolean isEnabled() { + return enabled; + } +} diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/storage/DirectoryReconciler.java b/service/src/main/java/org/whispersystems/textsecuregcm/storage/DirectoryReconciler.java index 4343edb52..45ea66abd 100644 --- a/service/src/main/java/org/whispersystems/textsecuregcm/storage/DirectoryReconciler.java +++ b/service/src/main/java/org/whispersystems/textsecuregcm/storage/DirectoryReconciler.java @@ -26,10 +26,13 @@ public class DirectoryReconciler extends AccountDatabaseCrawlerListener { private final String replicationName; private final DirectoryReconciliationClient reconciliationClient; + private final DynamicConfigurationManager dynamicConfigurationManager; - public DirectoryReconciler(String replicationName, DirectoryReconciliationClient reconciliationClient) { + public DirectoryReconciler(String replicationName, DirectoryReconciliationClient reconciliationClient, + DynamicConfigurationManager dynamicConfigurationManager) { this.reconciliationClient = reconciliationClient; this.replicationName = replicationName; + this.dynamicConfigurationManager = dynamicConfigurationManager; } @Override @@ -38,6 +41,10 @@ public class DirectoryReconciler extends AccountDatabaseCrawlerListener { @Override public void onCrawlEnd(Optional fromUuid) { + if (!dynamicConfigurationManager.getConfiguration().getDirectoryReconcilerConfiguration().isEnabled()) { + return; + } + reconciliationClient.complete(); } @@ -45,6 +52,10 @@ public class DirectoryReconciler extends AccountDatabaseCrawlerListener { protected void onCrawlChunk(final Optional fromUuid, final List accounts) throws AccountDatabaseCrawlerRestartException { + if (!dynamicConfigurationManager.getConfiguration().getDirectoryReconcilerConfiguration().isEnabled()) { + return; + } + final DirectoryReconciliationRequest addUsersRequest; final DirectoryReconciliationRequest deleteUsersRequest; { diff --git a/service/src/test/java/org/whispersystems/textsecuregcm/configuration/dynamic/DynamicConfigurationTest.java b/service/src/test/java/org/whispersystems/textsecuregcm/configuration/dynamic/DynamicConfigurationTest.java index 052ee6df0..10ffa0957 100644 --- a/service/src/test/java/org/whispersystems/textsecuregcm/configuration/dynamic/DynamicConfigurationTest.java +++ b/service/src/test/java/org/whispersystems/textsecuregcm/configuration/dynamic/DynamicConfigurationTest.java @@ -374,4 +374,27 @@ class DynamicConfigurationTest { assertThat(rateLimitChallengeConfiguration.isUnsealedSenderLimitEnforced()).isFalse(); } } + + @Test + void testParseDirectoryReconciler() throws JsonProcessingException { + { + final String emptyConfigYaml = "test: true"; + final DynamicConfiguration emptyConfig = + DynamicConfigurationManager.parseConfiguration(emptyConfigYaml).orElseThrow(); + + assertThat(emptyConfig.getDirectoryReconcilerConfiguration().isEnabled()).isTrue(); + } + + { + final String directoryReconcilerConfig = + "directoryReconciler:\n" + + " enabled: false"; + + DynamicDirectoryReconcilerConfiguration directoryReconcilerConfiguration = + DynamicConfigurationManager.parseConfiguration(directoryReconcilerConfig).orElseThrow() + .getDirectoryReconcilerConfiguration(); + + assertThat(directoryReconcilerConfiguration.isEnabled()).isFalse(); + } + } } diff --git a/service/src/test/java/org/whispersystems/textsecuregcm/tests/storage/DirectoryReconcilerTest.java b/service/src/test/java/org/whispersystems/textsecuregcm/tests/storage/DirectoryReconcilerTest.java index 8ca9dc7ca..35f5564b7 100644 --- a/service/src/test/java/org/whispersystems/textsecuregcm/tests/storage/DirectoryReconcilerTest.java +++ b/service/src/test/java/org/whispersystems/textsecuregcm/tests/storage/DirectoryReconcilerTest.java @@ -20,6 +20,7 @@ import java.util.UUID; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.mockito.ArgumentCaptor; +import org.whispersystems.textsecuregcm.configuration.dynamic.DynamicConfiguration; import org.whispersystems.textsecuregcm.entities.DirectoryReconciliationRequest; import org.whispersystems.textsecuregcm.entities.DirectoryReconciliationRequest.User; import org.whispersystems.textsecuregcm.entities.DirectoryReconciliationResponse; @@ -27,6 +28,7 @@ import org.whispersystems.textsecuregcm.storage.Account; import org.whispersystems.textsecuregcm.storage.AccountDatabaseCrawlerRestartException; import org.whispersystems.textsecuregcm.storage.DirectoryReconciler; import org.whispersystems.textsecuregcm.storage.DirectoryReconciliationClient; +import org.whispersystems.textsecuregcm.storage.DynamicConfigurationManager; class DirectoryReconcilerTest { @@ -38,12 +40,17 @@ class DirectoryReconcilerTest { private final Account visibleAccount = mock(Account.class); private final Account undiscoverableAccount = mock(Account.class); private final DirectoryReconciliationClient reconciliationClient = mock(DirectoryReconciliationClient.class); - private final DirectoryReconciler directoryReconciler = new DirectoryReconciler("test", reconciliationClient); + private final DynamicConfigurationManager dynamicConfigurationManager = mock(DynamicConfigurationManager.class); + private final DirectoryReconciler directoryReconciler = new DirectoryReconciler("test", reconciliationClient, + dynamicConfigurationManager); - private final DirectoryReconciliationResponse successResponse = new DirectoryReconciliationResponse(DirectoryReconciliationResponse.Status.OK); + private final DirectoryReconciliationResponse successResponse = new DirectoryReconciliationResponse( + DirectoryReconciliationResponse.Status.OK); @BeforeEach void setup() { + when(dynamicConfigurationManager.getConfiguration()).thenReturn(new DynamicConfiguration()); + when(visibleAccount.getUuid()).thenReturn(VALID_UUID); when(visibleAccount.getNumber()).thenReturn(VALID_NUMBER); when(visibleAccount.shouldBeVisibleInDirectory()).thenReturn(true);