From a96db1f23635a300aad70d4c37cd144c168950b6 Mon Sep 17 00:00:00 2001 From: Ben McIlwain Date: Wed, 8 Dec 2021 16:33:28 -0500 Subject: [PATCH] Allow command to enqueue poll messages for multiple registrars (#1446) * Allow command to enqueue poll messages for multiple registrars --- .../tools/EnqueuePollMessageCommand.java | 63 +++++++++---- .../export/sheet/SyncRegistrarsSheetTest.java | 2 +- .../registry/testing/DatabaseHelper.java | 2 + .../tools/EnqueuePollMessageCommandTest.java | 93 +++++++++++++++++-- 4 files changed, 137 insertions(+), 23 deletions(-) diff --git a/core/src/main/java/google/registry/tools/EnqueuePollMessageCommand.java b/core/src/main/java/google/registry/tools/EnqueuePollMessageCommand.java index ccfc68c09..f92139838 100644 --- a/core/src/main/java/google/registry/tools/EnqueuePollMessageCommand.java +++ b/core/src/main/java/google/registry/tools/EnqueuePollMessageCommand.java @@ -18,14 +18,21 @@ import static com.google.common.base.Preconditions.checkArgument; import static google.registry.model.EppResourceUtils.loadByForeignKey; import static google.registry.model.reporting.HistoryEntry.Type.SYNTHETIC; import static google.registry.persistence.transaction.TransactionManagerFactory.tm; +import static google.registry.util.CollectionUtils.isNullOrEmpty; import com.beust.jcommander.Parameter; import com.beust.jcommander.Parameters; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Streams; +import google.registry.config.RegistryConfig.Config; import google.registry.model.domain.DomainBase; import google.registry.model.domain.DomainHistory; import google.registry.model.poll.PollMessage; +import google.registry.model.registrar.Registrar; import google.registry.model.reporting.HistoryEntry; +import java.util.List; import java.util.Optional; +import javax.inject.Inject; /** * Tool to enqueue a poll message for a registrar. @@ -54,14 +61,26 @@ class EnqueuePollMessageCommand extends MutatingCommand { String domainName; @Parameter( - names = {"-c", "--client"}, + names = {"-c", "--clients"}, description = - "Client identifier of the registrar to send the poll message to, if not the owning" - + " registrar of the domain") - String clientId; + "Comma-delimited list of the client identifier(s) of the registrar(s) to send the poll" + + " message to, if not the owning registrar of the domain") + List clientIds; + + @Parameter( + names = {"-a", "--all"}, + description = "Whether to send the message to all real registrars", + arity = 1) + boolean sendToAll; + + @Inject + @Config("registryAdminClientId") + String registryAdminClientId; @Override protected final void init() { + checkArgument( + !sendToAll || isNullOrEmpty(clientIds), "Cannot specify both --all and --clients"); tm().transact( () -> { Optional domainOpt = @@ -69,27 +88,39 @@ class EnqueuePollMessageCommand extends MutatingCommand { checkArgument( domainOpt.isPresent(), "Domain %s doesn't exist or isn't active", domainName); DomainBase domain = domainOpt.get(); - String registrarId = - Optional.ofNullable(clientId).orElse(domain.getCurrentSponsorRegistrarId()); + ImmutableList registrarIds; + if (sendToAll) { + registrarIds = + Streams.stream(Registrar.loadAllCached()) + .filter(r -> r.isLive() && r.getType() == Registrar.Type.REAL) + .map(Registrar::getRegistrarId) + .collect(ImmutableList.toImmutableList()); + } else if (!isNullOrEmpty(clientIds)) { + registrarIds = ImmutableList.copyOf(clientIds); + } else { + registrarIds = ImmutableList.of(domain.getCurrentSponsorRegistrarId()); + } HistoryEntry historyEntry = new DomainHistory.Builder() .setDomain(domain) .setType(SYNTHETIC) .setBySuperuser(true) - .setReason("Manual enqueueing of poll message") + .setReason("Manual enqueueing of poll message: " + message) .setModificationTime(tm().getTransactionTime()) .setRequestedByRegistrar(false) - .setRegistrarId(registrarId) - .build(); - PollMessage.OneTime pollMessage = - new PollMessage.OneTime.Builder() - .setRegistrarId(registrarId) - .setParent(historyEntry) - .setEventTime(tm().getTransactionTime()) - .setMsg(message) + .setRegistrarId(registryAdminClientId) .build(); stageEntityChange(null, historyEntry); - stageEntityChange(null, pollMessage); + for (String registrarId : registrarIds) { + stageEntityChange( + null, + new PollMessage.OneTime.Builder() + .setRegistrarId(registrarId) + .setParent(historyEntry) + .setEventTime(tm().getTransactionTime()) + .setMsg(message) + .build()); + } }); } } diff --git a/core/src/test/java/google/registry/export/sheet/SyncRegistrarsSheetTest.java b/core/src/test/java/google/registry/export/sheet/SyncRegistrarsSheetTest.java index 884e86371..03149667c 100644 --- a/core/src/test/java/google/registry/export/sheet/SyncRegistrarsSheetTest.java +++ b/core/src/test/java/google/registry/export/sheet/SyncRegistrarsSheetTest.java @@ -344,7 +344,7 @@ public class SyncRegistrarsSheetTest { ImmutableMap row = getOnlyElement(getOnlyElement(rowsCaptor.getAllValues())); assertThat(row).containsEntry("clientIdentifier", "SomeRegistrar"); assertThat(row).containsEntry("registrarName", "Some Registrar"); - assertThat(row).containsEntry("state", ""); + assertThat(row).containsEntry("state", "ACTIVE"); assertThat(row).containsEntry("ianaIdentifier", "8"); assertThat(row).containsEntry("billingIdentifier", ""); assertThat(row).containsEntry("primaryContacts", ""); diff --git a/core/src/test/java/google/registry/testing/DatabaseHelper.java b/core/src/test/java/google/registry/testing/DatabaseHelper.java index 34935a4c3..fe0f45810 100644 --- a/core/src/test/java/google/registry/testing/DatabaseHelper.java +++ b/core/src/test/java/google/registry/testing/DatabaseHelper.java @@ -96,6 +96,7 @@ import google.registry.model.index.ForeignKeyIndex; import google.registry.model.poll.PollMessage; import google.registry.model.pricing.StaticPremiumListPricingEngine; import google.registry.model.registrar.Registrar; +import google.registry.model.registrar.Registrar.State; import google.registry.model.registrar.RegistrarAddress; import google.registry.model.reporting.HistoryEntry; import google.registry.model.reporting.HistoryEntryDao; @@ -758,6 +759,7 @@ public class DatabaseHelper { .setRegistrarId(registrarId) .setRegistrarName(registrarName) .setType(type) + .setState(State.ACTIVE) .setIanaIdentifier(ianaIdentifier) .setLocalizedAddress( new RegistrarAddress.Builder() diff --git a/core/src/test/java/google/registry/tools/EnqueuePollMessageCommandTest.java b/core/src/test/java/google/registry/tools/EnqueuePollMessageCommandTest.java index 5c1817149..47e3a6c97 100644 --- a/core/src/test/java/google/registry/tools/EnqueuePollMessageCommandTest.java +++ b/core/src/test/java/google/registry/tools/EnqueuePollMessageCommandTest.java @@ -20,6 +20,7 @@ import static google.registry.testing.DatabaseHelper.assertPollMessages; import static google.registry.testing.DatabaseHelper.createTld; import static google.registry.testing.DatabaseHelper.getOnlyHistoryEntryOfType; import static google.registry.testing.DatabaseHelper.persistActiveDomain; +import static google.registry.testing.DatabaseHelper.persistNewRegistrar; import static google.registry.testing.HistoryEntrySubject.assertAboutHistoryEntries; import static org.junit.jupiter.api.Assertions.assertThrows; @@ -47,6 +48,8 @@ class EnqueuePollMessageCommandTest extends CommandTestCase runCommandForced("--domain=example.tld")); assertThat(thrown).hasMessageThat().contains("The following option is required: -m, --message"); } + + @TestOfyAndSql + void testCantSpecifyClientIdsAndAll() { + IllegalArgumentException thrown = + assertThrows( + IllegalArgumentException.class, + () -> + runCommandForced( + "--domain=example.tld", + "--message=Domain is ended", + "--all=true", + "--clients=TheRegistrar")); + assertThat(thrown).hasMessageThat().isEqualTo("Cannot specify both --all and --clients"); + } }