diff --git a/core/src/main/java/google/registry/batch/AsyncTaskEnqueuer.java b/core/src/main/java/google/registry/batch/AsyncTaskEnqueuer.java index 9932a9410..34e412aab 100644 --- a/core/src/main/java/google/registry/batch/AsyncTaskEnqueuer.java +++ b/core/src/main/java/google/registry/batch/AsyncTaskEnqueuer.java @@ -26,7 +26,6 @@ import com.google.common.collect.ImmutableSortedSet; import com.google.common.flogger.FluentLogger; import google.registry.config.RegistryConfig.Config; import google.registry.model.EppResource; -import google.registry.model.domain.RegistryLock; import google.registry.model.eppcommon.Trid; import google.registry.model.host.HostResource; import google.registry.persistence.VKey; @@ -152,32 +151,6 @@ public final class AsyncTaskEnqueuer { .param(PARAM_REQUESTED_TIME, now.toString())); } - /** - * Enqueues a task to asynchronously re-lock a registry-locked domain after it was unlocked. - * - *

Note: the relockDuration must be present on the lock object. - */ - public void enqueueDomainRelock(RegistryLock lock) { - checkArgument( - lock.getRelockDuration().isPresent(), - "Lock with ID %s not configured for relock", - lock.getRevisionId()); - enqueueDomainRelock(lock.getRelockDuration().get(), lock.getRevisionId(), 0); - } - - /** Enqueues a task to asynchronously re-lock a registry-locked domain after it was unlocked. */ - void enqueueDomainRelock(Duration countdown, long lockRevisionId, int previousAttempts) { - String backendHostname = appEngineServiceUtils.getServiceHostname("backend"); - addTaskToQueueWithRetry( - asyncActionsPushQueue, - TaskOptions.Builder.withUrl(RelockDomainAction.PATH) - .method(Method.POST) - .header("Host", backendHostname) - .param(RelockDomainAction.OLD_UNLOCK_REVISION_ID_PARAM, String.valueOf(lockRevisionId)) - .param(RelockDomainAction.PREVIOUS_ATTEMPTS_PARAM, String.valueOf(previousAttempts)) - .countdownMillis(countdown.getMillis())); - } - /** * Adds a task to a queue with retrying, to avoid aborting the entire flow over a transient issue * enqueuing a task. diff --git a/core/src/main/java/google/registry/batch/RelockDomainAction.java b/core/src/main/java/google/registry/batch/RelockDomainAction.java index 30ea698a1..418fb1273 100644 --- a/core/src/main/java/google/registry/batch/RelockDomainAction.java +++ b/core/src/main/java/google/registry/batch/RelockDomainAction.java @@ -88,7 +88,6 @@ public class RelockDomainAction implements Runnable { private final SendEmailService sendEmailService; private final DomainLockUtils domainLockUtils; private final Response response; - private final AsyncTaskEnqueuer asyncTaskEnqueuer; @Inject public RelockDomainAction( @@ -99,8 +98,7 @@ public class RelockDomainAction implements Runnable { @Config("supportEmail") String supportEmail, SendEmailService sendEmailService, DomainLockUtils domainLockUtils, - Response response, - AsyncTaskEnqueuer asyncTaskEnqueuer) { + Response response) { this.oldUnlockRevisionId = oldUnlockRevisionId; this.previousAttempts = previousAttempts; this.alertRecipientAddress = alertRecipientAddress; @@ -109,7 +107,6 @@ public class RelockDomainAction implements Runnable { this.sendEmailService = sendEmailService; this.domainLockUtils = domainLockUtils; this.response = response; - this.asyncTaskEnqueuer = asyncTaskEnqueuer; } @Override @@ -245,8 +242,7 @@ public class RelockDomainAction implements Runnable { } } Duration timeBeforeRetry = previousAttempts < ATTEMPTS_BEFORE_SLOWDOWN ? TEN_MINUTES : ONE_HOUR; - asyncTaskEnqueuer.enqueueDomainRelock( - timeBeforeRetry, oldUnlockRevisionId, previousAttempts + 1); + domainLockUtils.enqueueDomainRelock(timeBeforeRetry, oldUnlockRevisionId, previousAttempts + 1); } private void sendSuccessEmail(RegistryLock oldLock) { diff --git a/core/src/main/java/google/registry/module/frontend/FrontendComponent.java b/core/src/main/java/google/registry/module/frontend/FrontendComponent.java index ce50f0aa7..f5d3c2008 100644 --- a/core/src/main/java/google/registry/module/frontend/FrontendComponent.java +++ b/core/src/main/java/google/registry/module/frontend/FrontendComponent.java @@ -46,6 +46,7 @@ import javax.inject.Singleton; @Component( modules = { AuthModule.class, + CloudTasksUtilsModule.class, ConfigModule.class, ConsoleConfigModule.class, CredentialModule.class, diff --git a/core/src/main/java/google/registry/tools/DomainLockUtils.java b/core/src/main/java/google/registry/tools/DomainLockUtils.java index 45d18099e..a18310535 100644 --- a/core/src/main/java/google/registry/tools/DomainLockUtils.java +++ b/core/src/main/java/google/registry/tools/DomainLockUtils.java @@ -15,14 +15,16 @@ package google.registry.tools; import static com.google.common.base.Preconditions.checkArgument; +import static google.registry.batch.AsyncTaskEnqueuer.QUEUE_ASYNC_ACTIONS; import static google.registry.model.EppResourceUtils.loadByForeignKeyCached; import static google.registry.persistence.transaction.TransactionManagerFactory.jpaTm; import static google.registry.persistence.transaction.TransactionManagerFactory.tm; import static google.registry.tools.LockOrUnlockDomainCommand.REGISTRY_LOCK_STATUSES; +import com.google.common.collect.ImmutableMultimap; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Sets; -import google.registry.batch.AsyncTaskEnqueuer; +import google.registry.batch.RelockDomainAction; import google.registry.config.RegistryConfig.Config; import google.registry.model.billing.BillingEvent; import google.registry.model.billing.BillingEvent.Reason; @@ -32,6 +34,8 @@ import google.registry.model.domain.RegistryLock; import google.registry.model.reporting.HistoryEntry; import google.registry.model.tld.Registry; import google.registry.model.tld.RegistryLockDao; +import google.registry.request.Action.Service; +import google.registry.util.CloudTasksUtils; import google.registry.util.StringGenerator; import java.util.Optional; import javax.annotation.Nullable; @@ -53,16 +57,16 @@ public final class DomainLockUtils { private final StringGenerator stringGenerator; private final String registryAdminRegistrarId; - private final AsyncTaskEnqueuer asyncTaskEnqueuer; + private CloudTasksUtils cloudTasksUtils; @Inject public DomainLockUtils( @Named("base58StringGenerator") StringGenerator stringGenerator, @Config("registryAdminClientId") String registryAdminRegistrarId, - AsyncTaskEnqueuer asyncTaskEnqueuer) { + CloudTasksUtils cloudTasksUtils) { this.stringGenerator = stringGenerator; this.registryAdminRegistrarId = registryAdminRegistrarId; - this.asyncTaskEnqueuer = asyncTaskEnqueuer; + this.cloudTasksUtils = cloudTasksUtils; } /** @@ -203,10 +207,38 @@ public final class DomainLockUtils { private void submitRelockIfNecessary(RegistryLock lock) { if (lock.getRelockDuration().isPresent()) { - asyncTaskEnqueuer.enqueueDomainRelock(lock); + enqueueDomainRelock(lock); } } + /** + * Enqueues a task to asynchronously re-lock a registry-locked domain after it was unlocked. + * + *

Note: the relockDuration must be present on the lock object. + */ + public void enqueueDomainRelock(RegistryLock lock) { + checkArgument( + lock.getRelockDuration().isPresent(), + "Lock with ID %s not configured for relock", + lock.getRevisionId()); + enqueueDomainRelock(lock.getRelockDuration().get(), lock.getRevisionId(), 0); + } + + /** Enqueues a task to asynchronously re-lock a registry-locked domain after it was unlocked. */ + public void enqueueDomainRelock(Duration countdown, long lockRevisionId, int previousAttempts) { + cloudTasksUtils.enqueue( + QUEUE_ASYNC_ACTIONS, + cloudTasksUtils.createPostTaskWithDelay( + RelockDomainAction.PATH, + Service.BACKEND.toString(), + ImmutableMultimap.of( + RelockDomainAction.OLD_UNLOCK_REVISION_ID_PARAM, + String.valueOf(lockRevisionId), + RelockDomainAction.PREVIOUS_ATTEMPTS_PARAM, + String.valueOf(previousAttempts)), + countdown)); + } + private void setAsRelock(RegistryLock newLock) { jpaTm() .transact( diff --git a/core/src/test/java/google/registry/batch/AsyncTaskEnqueuerTest.java b/core/src/test/java/google/registry/batch/AsyncTaskEnqueuerTest.java index 65281a438..3282bb4db 100644 --- a/core/src/test/java/google/registry/batch/AsyncTaskEnqueuerTest.java +++ b/core/src/test/java/google/registry/batch/AsyncTaskEnqueuerTest.java @@ -15,7 +15,6 @@ package google.registry.batch; import static com.google.appengine.api.taskqueue.QueueFactory.getQueue; -import static com.google.common.truth.Truth.assertThat; import static google.registry.batch.AsyncTaskEnqueuer.PARAM_REQUESTED_TIME; import static google.registry.batch.AsyncTaskEnqueuer.PARAM_RESAVE_TIMES; import static google.registry.batch.AsyncTaskEnqueuer.PARAM_RESOURCE_KEY; @@ -23,19 +22,16 @@ import static google.registry.batch.AsyncTaskEnqueuer.QUEUE_ASYNC_ACTIONS; import static google.registry.batch.AsyncTaskEnqueuer.QUEUE_ASYNC_DELETE; import static google.registry.batch.AsyncTaskEnqueuer.QUEUE_ASYNC_HOST_RENAME; import static google.registry.testing.DatabaseHelper.persistActiveContact; -import static google.registry.testing.SqlHelper.saveRegistryLock; import static google.registry.testing.TaskQueueHelper.assertNoTasksEnqueued; import static google.registry.testing.TaskQueueHelper.assertTasksEnqueued; import static google.registry.testing.TestLogHandlerUtils.assertLogMessage; import static org.joda.time.Duration.standardDays; import static org.joda.time.Duration.standardHours; import static org.joda.time.Duration.standardSeconds; -import static org.junit.Assert.assertThrows; import static org.mockito.Mockito.when; import com.google.common.collect.ImmutableSortedSet; import google.registry.model.contact.ContactResource; -import google.registry.model.domain.RegistryLock; import google.registry.testing.AppEngineExtension; import google.registry.testing.FakeClock; import google.registry.testing.FakeSleeper; @@ -142,59 +138,4 @@ public class AsyncTaskEnqueuerTest { assertNoTasksEnqueued(QUEUE_ASYNC_ACTIONS); assertLogMessage(logHandler, Level.INFO, "Ignoring async re-save"); } - - @Test - void testEnqueueRelock() { - RegistryLock lock = - saveRegistryLock( - new RegistryLock.Builder() - .setLockCompletionTime(clock.nowUtc()) - .setUnlockRequestTime(clock.nowUtc()) - .setUnlockCompletionTime(clock.nowUtc()) - .isSuperuser(false) - .setDomainName("example.tld") - .setRepoId("repoId") - .setRelockDuration(standardHours(6)) - .setRegistrarId("TheRegistrar") - .setRegistrarPocId("someone@example.com") - .setVerificationCode("hi") - .build()); - asyncTaskEnqueuer.enqueueDomainRelock(lock.getRelockDuration().get(), lock.getRevisionId(), 0); - assertTasksEnqueued( - QUEUE_ASYNC_ACTIONS, - new TaskMatcher() - .url(RelockDomainAction.PATH) - .method("POST") - .header("Host", "backend.hostname.fake") - .param( - RelockDomainAction.OLD_UNLOCK_REVISION_ID_PARAM, - String.valueOf(lock.getRevisionId())) - .param(RelockDomainAction.PREVIOUS_ATTEMPTS_PARAM, "0") - .etaDelta( - standardHours(6).minus(standardSeconds(30)), - standardHours(6).plus(standardSeconds(30)))); - } - - @MockitoSettings(strictness = Strictness.LENIENT) - @Test - void testFailure_enqueueRelock_noDuration() { - RegistryLock lockWithoutDuration = - saveRegistryLock( - new RegistryLock.Builder() - .isSuperuser(false) - .setDomainName("example.tld") - .setRepoId("repoId") - .setRegistrarId("TheRegistrar") - .setRegistrarPocId("someone@example.com") - .setVerificationCode("hi") - .build()); - assertThat( - assertThrows( - IllegalArgumentException.class, - () -> asyncTaskEnqueuer.enqueueDomainRelock(lockWithoutDuration))) - .hasMessageThat() - .isEqualTo( - String.format( - "Lock with ID %s not configured for relock", lockWithoutDuration.getRevisionId())); - } } diff --git a/core/src/test/java/google/registry/batch/RelockDomainActionTest.java b/core/src/test/java/google/registry/batch/RelockDomainActionTest.java index 206aae552..5a8e8dd86 100644 --- a/core/src/test/java/google/registry/batch/RelockDomainActionTest.java +++ b/core/src/test/java/google/registry/batch/RelockDomainActionTest.java @@ -28,27 +28,26 @@ import static google.registry.testing.DatabaseHelper.persistResource; import static google.registry.testing.SqlHelper.getMostRecentVerifiedRegistryLockByRepoId; import static google.registry.testing.SqlHelper.getRegistryLockByVerificationCode; import static google.registry.testing.SqlHelper.saveRegistryLock; -import static google.registry.testing.TaskQueueHelper.assertNoTasksEnqueued; -import static google.registry.testing.TaskQueueHelper.assertTasksEnqueued; import static google.registry.tools.LockOrUnlockDomainCommand.REGISTRY_LOCK_STATUSES; import static javax.servlet.http.HttpServletResponse.SC_NO_CONTENT; import static javax.servlet.http.HttpServletResponse.SC_OK; -import static org.joda.time.Duration.standardSeconds; import static org.mockito.Mockito.lenient; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; +import com.google.cloud.tasks.v2.HttpMethod; import com.google.common.collect.ImmutableSet; import google.registry.model.domain.DomainBase; import google.registry.model.domain.RegistryLock; import google.registry.model.host.HostResource; import google.registry.testing.AppEngineExtension; +import google.registry.testing.CloudTasksHelper; +import google.registry.testing.CloudTasksHelper.TaskMatcher; import google.registry.testing.DeterministicStringGenerator; import google.registry.testing.DualDatabaseTest; import google.registry.testing.FakeClock; import google.registry.testing.FakeResponse; -import google.registry.testing.TaskQueueHelper.TaskMatcher; import google.registry.testing.TestOfyAndSql; import google.registry.testing.UserInfo; import google.registry.tools.DomainLockUtils; @@ -78,12 +77,12 @@ public class RelockDomainActionTest { private final FakeResponse response = new FakeResponse(); private final FakeClock clock = new FakeClock(DateTime.parse("2015-05-18T12:34:56Z")); + private CloudTasksHelper cloudTasksHelper = new CloudTasksHelper(clock); private final DomainLockUtils domainLockUtils = new DomainLockUtils( new DeterministicStringGenerator(Alphabets.BASE_58), "adminreg", - AsyncTaskEnqueuerTest.createForTesting( - mock(AppEngineServiceUtils.class), clock, Duration.ZERO)); + cloudTasksHelper.getTestCloudTasksUtils()); @RegisterExtension public final AppEngineExtension appEngineExtension = @@ -96,7 +95,6 @@ public class RelockDomainActionTest { private DomainBase domain; private RegistryLock oldLock; @Mock private SendEmailService sendEmailService; - private AsyncTaskEnqueuer asyncTaskEnqueuer; private RelockDomainAction action; @BeforeEach @@ -118,8 +116,6 @@ public class RelockDomainActionTest { .when(appEngineServiceUtils.getServiceHostname("backend")) .thenReturn("backend.hostname.fake"); - asyncTaskEnqueuer = - AsyncTaskEnqueuerTest.createForTesting(appEngineServiceUtils, clock, Duration.ZERO); action = createAction(oldLock.getRevisionId()); } @@ -158,7 +154,7 @@ public class RelockDomainActionTest { assertThat(response.getPayload()) .isEqualTo(String.format("Re-lock failed: %s", expectedFailureMessage)); assertNonTransientFailureEmail(expectedFailureMessage); - assertNoTasksEnqueued(QUEUE_ASYNC_ACTIONS); + cloudTasksHelper.assertNoTasksEnqueued(QUEUE_ASYNC_ACTIONS); } @TestOfyAndSql @@ -170,7 +166,7 @@ public class RelockDomainActionTest { assertThat(response.getPayload()) .isEqualTo(String.format("Re-lock failed: %s", expectedFailureMessage)); assertNonTransientFailureEmail(expectedFailureMessage); - assertNoTasksEnqueued(QUEUE_ASYNC_ACTIONS); + cloudTasksHelper.assertNoTasksEnqueued(QUEUE_ASYNC_ACTIONS); } @TestOfyAndSql @@ -180,7 +176,7 @@ public class RelockDomainActionTest { assertThat(response.getStatus()).isEqualTo(SC_NO_CONTENT); assertThat(response.getPayload()) .isEqualTo("Domain example.tld is already manually re-locked, skipping automated re-lock."); - assertNoTasksEnqueued(QUEUE_ASYNC_ACTIONS); + cloudTasksHelper.assertNoTasksEnqueued(QUEUE_ASYNC_ACTIONS); } @TestOfyAndSql @@ -192,7 +188,7 @@ public class RelockDomainActionTest { assertThat(response.getPayload()) .isEqualTo(String.format("Re-lock failed: %s", expectedFailureMessage)); assertNonTransientFailureEmail(expectedFailureMessage); - assertNoTasksEnqueued(QUEUE_ASYNC_ACTIONS); + cloudTasksHelper.assertNoTasksEnqueued(QUEUE_ASYNC_ACTIONS); } @TestOfyAndSql @@ -207,7 +203,7 @@ public class RelockDomainActionTest { assertThat(response.getPayload()) .isEqualTo(String.format("Re-lock failed: %s", expectedFailureMessage)); assertNonTransientFailureEmail(expectedFailureMessage); - assertNoTasksEnqueued(QUEUE_ASYNC_ACTIONS); + cloudTasksHelper.assertNoTasksEnqueued(QUEUE_ASYNC_ACTIONS); } @TestOfyAndSql @@ -253,7 +249,7 @@ public class RelockDomainActionTest { assertThat(response.getStatus()).isEqualTo(SC_NO_CONTENT); assertThat(response.getPayload()) .isEqualTo("Domain example.tld is already manually re-locked, skipping automated re-lock."); - assertNoTasksEnqueued(QUEUE_ASYNC_ACTIONS); + cloudTasksHelper.assertNoTasksEnqueued(QUEUE_ASYNC_ACTIONS); } @TestOfyAndSql @@ -320,17 +316,16 @@ public class RelockDomainActionTest { } private void assertTaskEnqueued(int numAttempts, long oldUnlockRevisionId, Duration duration) { - assertTasksEnqueued( + cloudTasksHelper.assertTasksEnqueued( QUEUE_ASYNC_ACTIONS, new TaskMatcher() .url(RelockDomainAction.PATH) - .method("POST") - .header("Host", "backend.hostname.fake") + .method(HttpMethod.POST) .param( RelockDomainAction.OLD_UNLOCK_REVISION_ID_PARAM, String.valueOf(oldUnlockRevisionId)) .param(RelockDomainAction.PREVIOUS_ATTEMPTS_PARAM, String.valueOf(numAttempts)) - .etaDelta(duration.minus(standardSeconds(30)), duration.plus(standardSeconds(30)))); + .scheduleTime(clock.nowUtc().plus(duration))); } private RelockDomainAction createAction(Long oldUnlockRevisionId) throws Exception { @@ -349,7 +344,6 @@ public class RelockDomainActionTest { "support@example.com", sendEmailService, domainLockUtils, - response, - asyncTaskEnqueuer); + response); } } diff --git a/core/src/test/java/google/registry/tools/DomainLockUtilsTest.java b/core/src/test/java/google/registry/tools/DomainLockUtilsTest.java index 723f8fb84..5bf845fd9 100644 --- a/core/src/test/java/google/registry/tools/DomainLockUtilsTest.java +++ b/core/src/test/java/google/registry/tools/DomainLockUtilsTest.java @@ -26,17 +26,16 @@ import static google.registry.testing.DatabaseHelper.persistActiveHost; import static google.registry.testing.DatabaseHelper.persistResource; import static google.registry.testing.SqlHelper.getRegistryLockByRevisionId; import static google.registry.testing.SqlHelper.getRegistryLockByVerificationCode; -import static google.registry.testing.TaskQueueHelper.assertTasksEnqueued; +import static google.registry.testing.SqlHelper.saveRegistryLock; import static google.registry.tools.LockOrUnlockDomainCommand.REGISTRY_LOCK_STATUSES; import static org.joda.time.Duration.standardDays; import static org.joda.time.Duration.standardHours; -import static org.joda.time.Duration.standardSeconds; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; +import com.google.cloud.tasks.v2.HttpMethod; import com.google.common.collect.ImmutableList; -import google.registry.batch.AsyncTaskEnqueuerTest; import google.registry.batch.RelockDomainAction; import google.registry.model.billing.BillingEvent; import google.registry.model.billing.BillingEvent.Reason; @@ -47,12 +46,13 @@ import google.registry.model.host.HostResource; import google.registry.model.reporting.HistoryEntry; import google.registry.model.tld.Registry; import google.registry.testing.AppEngineExtension; +import google.registry.testing.CloudTasksHelper; +import google.registry.testing.CloudTasksHelper.TaskMatcher; import google.registry.testing.DatabaseHelper; import google.registry.testing.DeterministicStringGenerator; import google.registry.testing.DualDatabaseTest; import google.registry.testing.FakeClock; import google.registry.testing.SqlHelper; -import google.registry.testing.TaskQueueHelper.TaskMatcher; import google.registry.testing.TestOfyAndSql; import google.registry.testing.UserInfo; import google.registry.util.AppEngineServiceUtils; @@ -62,8 +62,11 @@ import java.util.Set; import java.util.stream.Collectors; import org.joda.time.DateTime; import org.joda.time.DateTimeZone; +import org.junit.Assert; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.extension.RegisterExtension; +import org.mockito.junit.jupiter.MockitoSettings; +import org.mockito.quality.Strictness; /** Unit tests for {@link google.registry.tools.DomainLockUtils}. */ @DualDatabaseTest @@ -74,6 +77,7 @@ public final class DomainLockUtilsTest { private final FakeClock clock = new FakeClock(DateTime.now(DateTimeZone.UTC)); private DomainLockUtils domainLockUtils; + private CloudTasksHelper cloudTasksHelper = new CloudTasksHelper(clock); @RegisterExtension public final AppEngineExtension appEngineExtension = @@ -98,8 +102,7 @@ public final class DomainLockUtilsTest { new DomainLockUtils( new DeterministicStringGenerator(Alphabets.BASE_58), "adminreg", - AsyncTaskEnqueuerTest.createForTesting( - appEngineServiceUtils, clock, standardSeconds(90))); + cloudTasksHelper.getTestCloudTasksUtils()); } @TestOfyAndSql @@ -265,19 +268,17 @@ public final class DomainLockUtilsTest { domainLockUtils.saveNewRegistryUnlockRequest( DOMAIN_NAME, "TheRegistrar", false, Optional.of(standardHours(6))); domainLockUtils.verifyAndApplyUnlock(lock.getVerificationCode(), false); - assertTasksEnqueued( + cloudTasksHelper.assertTasksEnqueued( QUEUE_ASYNC_ACTIONS, new TaskMatcher() .url(RelockDomainAction.PATH) - .method("POST") - .header("Host", "backend.hostname.fake") + .method(HttpMethod.POST) + .service("backend") .param( RelockDomainAction.OLD_UNLOCK_REVISION_ID_PARAM, String.valueOf(lock.getRevisionId())) .param(RelockDomainAction.PREVIOUS_ATTEMPTS_PARAM, "0") - .etaDelta( - standardHours(6).minus(standardSeconds(30)), - standardDays(6).plus(standardSeconds(30)))); + .scheduleTime(clock.nowUtc().plus(lock.getRelockDuration().get()))); } @TestOfyAndSql @@ -477,6 +478,59 @@ public final class DomainLockUtilsTest { assertNoDomainChanges(); } + @TestOfyAndSql + void testEnqueueRelock() { + RegistryLock lock = + saveRegistryLock( + new RegistryLock.Builder() + .setLockCompletionTime(clock.nowUtc()) + .setUnlockRequestTime(clock.nowUtc()) + .setUnlockCompletionTime(clock.nowUtc()) + .isSuperuser(false) + .setDomainName("example.tld") + .setRepoId("repoId") + .setRelockDuration(standardHours(6)) + .setRegistrarId("TheRegistrar") + .setRegistrarPocId("someone@example.com") + .setVerificationCode("hi") + .build()); + domainLockUtils.enqueueDomainRelock(lock.getRelockDuration().get(), lock.getRevisionId(), 0); + cloudTasksHelper.assertTasksEnqueued( + QUEUE_ASYNC_ACTIONS, + new CloudTasksHelper.TaskMatcher() + .url(RelockDomainAction.PATH) + .method(HttpMethod.POST) + .service("backend") + .param( + RelockDomainAction.OLD_UNLOCK_REVISION_ID_PARAM, + String.valueOf(lock.getRevisionId())) + .param(RelockDomainAction.PREVIOUS_ATTEMPTS_PARAM, "0") + .scheduleTime(clock.nowUtc().plus(lock.getRelockDuration().get()))); + } + + @MockitoSettings(strictness = Strictness.LENIENT) + @TestOfyAndSql + void testFailure_enqueueRelock_noDuration() { + RegistryLock lockWithoutDuration = + saveRegistryLock( + new RegistryLock.Builder() + .isSuperuser(false) + .setDomainName("example.tld") + .setRepoId("repoId") + .setRegistrarId("TheRegistrar") + .setRegistrarPocId("someone@example.com") + .setVerificationCode("hi") + .build()); + assertThat( + Assert.assertThrows( + IllegalArgumentException.class, + () -> domainLockUtils.enqueueDomainRelock(lockWithoutDuration))) + .hasMessageThat() + .isEqualTo( + String.format( + "Lock with ID %s not configured for relock", lockWithoutDuration.getRevisionId())); + } + private void verifyProperlyLockedDomain(boolean isAdmin) { assertThat(loadByEntity(domain).getStatusValues()) .containsAtLeastElementsIn(REGISTRY_LOCK_STATUSES); diff --git a/core/src/test/java/google/registry/tools/LockDomainCommandTest.java b/core/src/test/java/google/registry/tools/LockDomainCommandTest.java index 1fe4f5d3b..0b25b5dc8 100644 --- a/core/src/test/java/google/registry/tools/LockDomainCommandTest.java +++ b/core/src/test/java/google/registry/tools/LockDomainCommandTest.java @@ -24,19 +24,16 @@ import static google.registry.testing.DatabaseHelper.persistResource; import static google.registry.testing.SqlHelper.getMostRecentRegistryLockByRepoId; import static google.registry.tools.LockOrUnlockDomainCommand.REGISTRY_LOCK_STATUSES; import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.mockito.Mockito.mock; import com.google.common.collect.ImmutableList; -import google.registry.batch.AsyncTaskEnqueuerTest; import google.registry.model.domain.DomainBase; import google.registry.model.registrar.Registrar.Type; +import google.registry.testing.CloudTasksHelper; import google.registry.testing.DeterministicStringGenerator; -import google.registry.util.AppEngineServiceUtils; import google.registry.util.StringGenerator.Alphabets; import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; -import org.joda.time.Duration; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -52,8 +49,7 @@ class LockDomainCommandTest extends CommandTestCase { new DomainLockUtils( new DeterministicStringGenerator(Alphabets.BASE_58), "adminreg", - AsyncTaskEnqueuerTest.createForTesting( - mock(AppEngineServiceUtils.class), fakeClock, Duration.ZERO)); + new CloudTasksHelper(fakeClock).getTestCloudTasksUtils()); } @Test diff --git a/core/src/test/java/google/registry/tools/UnlockDomainCommandTest.java b/core/src/test/java/google/registry/tools/UnlockDomainCommandTest.java index 5a472de18..e6c9d9eca 100644 --- a/core/src/test/java/google/registry/tools/UnlockDomainCommandTest.java +++ b/core/src/test/java/google/registry/tools/UnlockDomainCommandTest.java @@ -25,21 +25,18 @@ import static google.registry.testing.DatabaseHelper.persistResource; import static google.registry.testing.SqlHelper.getMostRecentRegistryLockByRepoId; import static google.registry.tools.LockOrUnlockDomainCommand.REGISTRY_LOCK_STATUSES; import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.mockito.Mockito.mock; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; -import google.registry.batch.AsyncTaskEnqueuerTest; import google.registry.model.domain.DomainBase; import google.registry.model.domain.RegistryLock; import google.registry.model.registrar.Registrar.Type; +import google.registry.testing.CloudTasksHelper; import google.registry.testing.DeterministicStringGenerator; -import google.registry.util.AppEngineServiceUtils; import google.registry.util.StringGenerator.Alphabets; import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; -import org.joda.time.Duration; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -55,8 +52,7 @@ class UnlockDomainCommandTest extends CommandTestCase { new DomainLockUtils( new DeterministicStringGenerator(Alphabets.BASE_58), "adminreg", - AsyncTaskEnqueuerTest.createForTesting( - mock(AppEngineServiceUtils.class), fakeClock, Duration.ZERO)); + new CloudTasksHelper(fakeClock).getTestCloudTasksUtils()); } private DomainBase persistLockedDomain(String domainName, String registrarId) { diff --git a/core/src/test/java/google/registry/ui/server/registrar/RegistryLockPostActionTest.java b/core/src/test/java/google/registry/ui/server/registrar/RegistryLockPostActionTest.java index 0c7e148f9..870cd3093 100644 --- a/core/src/test/java/google/registry/ui/server/registrar/RegistryLockPostActionTest.java +++ b/core/src/test/java/google/registry/ui/server/registrar/RegistryLockPostActionTest.java @@ -26,7 +26,6 @@ import static google.registry.testing.SqlHelper.getRegistryLockByVerificationCod import static google.registry.testing.SqlHelper.saveRegistryLock; import static google.registry.tools.LockOrUnlockDomainCommand.REGISTRY_LOCK_STATUSES; import static google.registry.ui.server.registrar.RegistryLockGetActionTest.userFromRegistrarContact; -import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; @@ -35,7 +34,6 @@ import com.google.appengine.api.users.User; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; -import google.registry.batch.AsyncTaskEnqueuerTest; import google.registry.model.domain.DomainBase; import google.registry.model.domain.RegistryLock; import google.registry.request.JsonActionRunner; @@ -47,10 +45,10 @@ import google.registry.request.auth.AuthenticatedRegistrarAccessor; import google.registry.request.auth.AuthenticatedRegistrarAccessor.Role; import google.registry.request.auth.UserAuthInfo; import google.registry.testing.AppEngineExtension; +import google.registry.testing.CloudTasksHelper; import google.registry.testing.DeterministicStringGenerator; import google.registry.testing.FakeClock; import google.registry.tools.DomainLockUtils; -import google.registry.util.AppEngineServiceUtils; import google.registry.util.EmailMessage; import google.registry.util.SendEmailService; import google.registry.util.StringGenerator.Alphabets; @@ -469,8 +467,7 @@ final class RegistryLockPostActionTest { new DomainLockUtils( new DeterministicStringGenerator(Alphabets.BASE_58), "adminreg", - AsyncTaskEnqueuerTest.createForTesting( - mock(AppEngineServiceUtils.class), clock, Duration.ZERO)); + new CloudTasksHelper(clock).getTestCloudTasksUtils()); return new RegistryLockPostAction( mockRequest, jsonActionRunner, diff --git a/core/src/test/java/google/registry/ui/server/registrar/RegistryLockVerifyActionTest.java b/core/src/test/java/google/registry/ui/server/registrar/RegistryLockVerifyActionTest.java index 275191644..cfb8b6a69 100644 --- a/core/src/test/java/google/registry/ui/server/registrar/RegistryLockVerifyActionTest.java +++ b/core/src/test/java/google/registry/ui/server/registrar/RegistryLockVerifyActionTest.java @@ -33,7 +33,6 @@ import com.google.appengine.api.users.User; import com.google.appengine.api.users.UserService; import com.google.appengine.api.users.UserServiceFactory; import com.google.common.collect.ImmutableMap; -import google.registry.batch.AsyncTaskEnqueuerTest; import google.registry.model.billing.BillingEvent; import google.registry.model.billing.BillingEvent.Reason; import google.registry.model.domain.DomainBase; @@ -47,13 +46,13 @@ import google.registry.request.auth.AuthResult; import google.registry.request.auth.UserAuthInfo; import google.registry.security.XsrfTokenManager; import google.registry.testing.AppEngineExtension; +import google.registry.testing.CloudTasksHelper; import google.registry.testing.DatabaseHelper; import google.registry.testing.DeterministicStringGenerator; import google.registry.testing.FakeClock; import google.registry.testing.FakeResponse; import google.registry.testing.UserInfo; import google.registry.tools.DomainLockUtils; -import google.registry.util.AppEngineServiceUtils; import google.registry.util.StringGenerator; import google.registry.util.StringGenerator.Alphabets; import javax.servlet.http.HttpServletRequest; @@ -86,6 +85,7 @@ final class RegistryLockVerifyActionTest { private DomainBase domain; private AuthResult authResult; private RegistryLockVerifyAction action; + private CloudTasksHelper cloudTasksHelper = new CloudTasksHelper(fakeClock); @BeforeEach void beforeEach() { @@ -329,10 +329,7 @@ final class RegistryLockVerifyActionTest { RegistryLockVerifyAction action = new RegistryLockVerifyAction( new DomainLockUtils( - stringGenerator, - "adminreg", - AsyncTaskEnqueuerTest.createForTesting( - mock(AppEngineServiceUtils.class), fakeClock, Duration.ZERO)), + stringGenerator, "adminreg", cloudTasksHelper.getTestCloudTasksUtils()), lockVerificationCode, isLock); authResult = AuthResult.create(AuthLevel.USER, UserAuthInfo.create(user, false));