diff --git a/core/src/main/java/google/registry/tools/AckPollMessagesCommand.java b/core/src/main/java/google/registry/tools/AckPollMessagesCommand.java index 07e0ee4d8..b825dfc23 100644 --- a/core/src/main/java/google/registry/tools/AckPollMessagesCommand.java +++ b/core/src/main/java/google/registry/tools/AckPollMessagesCommand.java @@ -53,7 +53,7 @@ import javax.inject.Inject; * event time is in the past), same as through EPP. */ @Parameters(separators = " =", commandDescription = "Acknowledge one-time poll messages.") -final class AckPollMessagesCommand implements CommandWithRemoteApi { +final class AckPollMessagesCommand implements Command { @Parameter( names = {"-c", "--client"}, diff --git a/core/src/main/java/google/registry/tools/CommandWithRemoteApi.java b/core/src/main/java/google/registry/tools/CommandWithRemoteApi.java deleted file mode 100644 index eab2c48ee..000000000 --- a/core/src/main/java/google/registry/tools/CommandWithRemoteApi.java +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright 2018 The Nomulus Authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package google.registry.tools; - -/** - * Marker interface for commands that use the remote api. - * - *

Just implementing this is sufficient to use the remote api; {@link RegistryTool} will install - * it as needed. - */ -public interface CommandWithRemoteApi extends Command {} diff --git a/core/src/main/java/google/registry/tools/CountDomainsCommand.java b/core/src/main/java/google/registry/tools/CountDomainsCommand.java index 54273c7e7..0b5ff65a1 100644 --- a/core/src/main/java/google/registry/tools/CountDomainsCommand.java +++ b/core/src/main/java/google/registry/tools/CountDomainsCommand.java @@ -28,7 +28,7 @@ import org.joda.time.DateTime; /** Command to show the count of active domains on a given TLD. */ @Parameters(separators = " =", commandDescription = "Show count of domains on TLD") -final class CountDomainsCommand implements CommandWithRemoteApi { +final class CountDomainsCommand implements Command { @Parameter( names = {"-t", "--tld", "--tlds"}, diff --git a/core/src/main/java/google/registry/tools/CreateDomainCommand.java b/core/src/main/java/google/registry/tools/CreateDomainCommand.java index 337e04bfd..5d077b3aa 100644 --- a/core/src/main/java/google/registry/tools/CreateDomainCommand.java +++ b/core/src/main/java/google/registry/tools/CreateDomainCommand.java @@ -33,8 +33,7 @@ import org.joda.time.DateTime; /** A command to create a new domain via EPP. */ @Parameters(separators = " =", commandDescription = "Create a new domain via EPP.") -final class CreateDomainCommand extends CreateOrUpdateDomainCommand - implements CommandWithRemoteApi { +final class CreateDomainCommand extends CreateOrUpdateDomainCommand { @Parameter( names = "--period", diff --git a/core/src/main/java/google/registry/tools/CreateOrUpdatePremiumListCommand.java b/core/src/main/java/google/registry/tools/CreateOrUpdatePremiumListCommand.java index 5f1069002..13ef81552 100644 --- a/core/src/main/java/google/registry/tools/CreateOrUpdatePremiumListCommand.java +++ b/core/src/main/java/google/registry/tools/CreateOrUpdatePremiumListCommand.java @@ -27,8 +27,7 @@ import org.joda.money.CurrencyUnit; * Base class for specification of command line parameters common to creating and updating premium * lists. */ -abstract class CreateOrUpdatePremiumListCommand extends ConfirmingCommand - implements CommandWithRemoteApi { +abstract class CreateOrUpdatePremiumListCommand extends ConfirmingCommand { private static final FluentLogger logger = FluentLogger.forEnclosingClass(); protected List inputData; diff --git a/core/src/main/java/google/registry/tools/CreateOrUpdateReservedListCommand.java b/core/src/main/java/google/registry/tools/CreateOrUpdateReservedListCommand.java index b3b8f1e0b..58229bc7d 100644 --- a/core/src/main/java/google/registry/tools/CreateOrUpdateReservedListCommand.java +++ b/core/src/main/java/google/registry/tools/CreateOrUpdateReservedListCommand.java @@ -26,8 +26,7 @@ import javax.annotation.Nullable; * Base class for specification of command line parameters common to creating and updating reserved * lists. */ -public abstract class CreateOrUpdateReservedListCommand extends ConfirmingCommand - implements CommandWithRemoteApi { +public abstract class CreateOrUpdateReservedListCommand extends ConfirmingCommand { static final FluentLogger logger = FluentLogger.forEnclosingClass(); diff --git a/core/src/main/java/google/registry/tools/CreateRegistrarCommand.java b/core/src/main/java/google/registry/tools/CreateRegistrarCommand.java index 0b2b3acc9..7b75f7c66 100644 --- a/core/src/main/java/google/registry/tools/CreateRegistrarCommand.java +++ b/core/src/main/java/google/registry/tools/CreateRegistrarCommand.java @@ -40,7 +40,7 @@ import javax.annotation.Nullable; /** Command to create a Registrar. */ @Parameters(separators = " =", commandDescription = "Create new registrar account(s)") final class CreateRegistrarCommand extends CreateOrUpdateRegistrarCommand - implements CommandWithConnection, CommandWithRemoteApi { + implements CommandWithConnection { private static final ImmutableSet ENVIRONMENTS_ALLOWING_GROUP_CREATION = ImmutableSet.of(PRODUCTION, SANDBOX, UNITTEST); diff --git a/core/src/main/java/google/registry/tools/CreateRegistrarGroupsCommand.java b/core/src/main/java/google/registry/tools/CreateRegistrarGroupsCommand.java index 8455aa62e..a7115b2b6 100644 --- a/core/src/main/java/google/registry/tools/CreateRegistrarGroupsCommand.java +++ b/core/src/main/java/google/registry/tools/CreateRegistrarGroupsCommand.java @@ -30,7 +30,7 @@ import java.util.List; /** Command to create groups in Google Groups for all contact types for a registrar. */ @Parameters(separators = " =", commandDescription = "Create groups for a registrar.") public class CreateRegistrarGroupsCommand extends ConfirmingCommand - implements CommandWithConnection, CommandWithRemoteApi { + implements CommandWithConnection { @Parameter( description = "Client identifier(s) of the registrar(s) to create groups for", diff --git a/core/src/main/java/google/registry/tools/DeletePremiumListCommand.java b/core/src/main/java/google/registry/tools/DeletePremiumListCommand.java index 036598c15..dc9119edb 100644 --- a/core/src/main/java/google/registry/tools/DeletePremiumListCommand.java +++ b/core/src/main/java/google/registry/tools/DeletePremiumListCommand.java @@ -29,7 +29,7 @@ import javax.annotation.Nullable; * in use on a tld. */ @Parameters(separators = " =", commandDescription = "Delete a PremiumList.") -final class DeletePremiumListCommand extends ConfirmingCommand implements CommandWithRemoteApi { +final class DeletePremiumListCommand extends ConfirmingCommand { @Nullable PremiumList premiumList; diff --git a/core/src/main/java/google/registry/tools/DeleteReservedListCommand.java b/core/src/main/java/google/registry/tools/DeleteReservedListCommand.java index 61d610273..f1b818714 100644 --- a/core/src/main/java/google/registry/tools/DeleteReservedListCommand.java +++ b/core/src/main/java/google/registry/tools/DeleteReservedListCommand.java @@ -28,7 +28,7 @@ import google.registry.model.tld.label.ReservedListDao; * reserved list is currently in use on a tld. */ @Parameters(separators = " =", commandDescription = "Deletes a ReservedList from the database.") -final class DeleteReservedListCommand extends ConfirmingCommand implements CommandWithRemoteApi { +final class DeleteReservedListCommand extends ConfirmingCommand { @Parameter( names = {"-n", "--name"}, diff --git a/core/src/main/java/google/registry/tools/DeleteTldCommand.java b/core/src/main/java/google/registry/tools/DeleteTldCommand.java index 1825f5b43..c96502c4a 100644 --- a/core/src/main/java/google/registry/tools/DeleteTldCommand.java +++ b/core/src/main/java/google/registry/tools/DeleteTldCommand.java @@ -31,7 +31,7 @@ import google.registry.persistence.transaction.QueryComposer.Comparator; *

This command will fail if any domains are currently registered on the TLD. */ @Parameters(separators = " =", commandDescription = "Delete a TLD from Datastore.") -final class DeleteTldCommand extends ConfirmingCommand implements CommandWithRemoteApi { +final class DeleteTldCommand extends ConfirmingCommand { private Registry registry; diff --git a/core/src/main/java/google/registry/tools/EncryptEscrowDepositCommand.java b/core/src/main/java/google/registry/tools/EncryptEscrowDepositCommand.java index 73af5efd8..6eacbeeb2 100644 --- a/core/src/main/java/google/registry/tools/EncryptEscrowDepositCommand.java +++ b/core/src/main/java/google/registry/tools/EncryptEscrowDepositCommand.java @@ -26,7 +26,7 @@ import javax.inject.Inject; /** Command to encrypt an escrow deposit. */ @Parameters(separators = " =", commandDescription = "Encrypt an escrow deposit") -class EncryptEscrowDepositCommand implements CommandWithRemoteApi { +class EncryptEscrowDepositCommand implements Command { @Parameter( names = {"-t", "--tld"}, diff --git a/core/src/main/java/google/registry/tools/EppToolCommand.java b/core/src/main/java/google/registry/tools/EppToolCommand.java index 92c20c770..88ecfbc3e 100644 --- a/core/src/main/java/google/registry/tools/EppToolCommand.java +++ b/core/src/main/java/google/registry/tools/EppToolCommand.java @@ -47,8 +47,7 @@ import java.util.Map; import java.util.Objects; /** A command to execute an epp command. */ -abstract class EppToolCommand extends ConfirmingCommand - implements CommandWithConnection, CommandWithRemoteApi { +abstract class EppToolCommand extends ConfirmingCommand implements CommandWithConnection { @Parameter( names = {"-u", "--superuser"}, diff --git a/core/src/main/java/google/registry/tools/GenerateAllocationTokensCommand.java b/core/src/main/java/google/registry/tools/GenerateAllocationTokensCommand.java index 2c2fe66e2..a02a278d6 100644 --- a/core/src/main/java/google/registry/tools/GenerateAllocationTokensCommand.java +++ b/core/src/main/java/google/registry/tools/GenerateAllocationTokensCommand.java @@ -69,7 +69,7 @@ import org.joda.time.DateTime; "Generates and persists the given number of AllocationTokens, " + "printing each token to stdout.") @NonFinalForTesting -class GenerateAllocationTokensCommand implements CommandWithRemoteApi { +class GenerateAllocationTokensCommand implements Command { @Parameter( names = {"--tokens"}, diff --git a/core/src/main/java/google/registry/tools/GenerateDnsReportCommand.java b/core/src/main/java/google/registry/tools/GenerateDnsReportCommand.java index 73e410855..262ef4b37 100644 --- a/core/src/main/java/google/registry/tools/GenerateDnsReportCommand.java +++ b/core/src/main/java/google/registry/tools/GenerateDnsReportCommand.java @@ -42,7 +42,7 @@ import org.json.simple.JSONValue; /** Command to generate a report of all DNS data. */ @Parameters(separators = " =", commandDescription = "Generate report of all DNS data in a TLD.") -final class GenerateDnsReportCommand implements CommandWithRemoteApi { +final class GenerateDnsReportCommand implements Command { @Parameter( names = {"-t", "--tld"}, diff --git a/core/src/main/java/google/registry/tools/GenerateEscrowDepositCommand.java b/core/src/main/java/google/registry/tools/GenerateEscrowDepositCommand.java index 76ed35e09..c81efc906 100644 --- a/core/src/main/java/google/registry/tools/GenerateEscrowDepositCommand.java +++ b/core/src/main/java/google/registry/tools/GenerateEscrowDepositCommand.java @@ -43,7 +43,7 @@ import org.joda.time.DateTime; * be stored in the specified manual subdirectory of the GCS RDE bucket. */ @Parameters(separators = " =", commandDescription = "Generate an XML escrow deposit.") -final class GenerateEscrowDepositCommand implements CommandWithRemoteApi { +final class GenerateEscrowDepositCommand implements Command { @Parameter( names = {"-t", "--tld"}, diff --git a/core/src/main/java/google/registry/tools/GenerateLordnCommand.java b/core/src/main/java/google/registry/tools/GenerateLordnCommand.java index 8af7305ef..a6bf88e53 100644 --- a/core/src/main/java/google/registry/tools/GenerateLordnCommand.java +++ b/core/src/main/java/google/registry/tools/GenerateLordnCommand.java @@ -33,7 +33,7 @@ import org.joda.time.DateTime; /** Command to generate a LORDN CSV file for an entire TLD. */ @Parameters(separators = " =", commandDescription = "Generate LORDN CSV file") -final class GenerateLordnCommand implements CommandWithRemoteApi { +final class GenerateLordnCommand implements Command { @Parameter( names = {"-t", "--tld"}, diff --git a/core/src/main/java/google/registry/tools/GenerateZoneFilesCommand.java b/core/src/main/java/google/registry/tools/GenerateZoneFilesCommand.java index 9d5652264..908ff783d 100644 --- a/core/src/main/java/google/registry/tools/GenerateZoneFilesCommand.java +++ b/core/src/main/java/google/registry/tools/GenerateZoneFilesCommand.java @@ -30,7 +30,7 @@ import org.joda.time.DateTime; /** Command to generate zone files. */ @Parameters(separators = " =", commandDescription = "Generate zone files") -final class GenerateZoneFilesCommand implements CommandWithConnection, CommandWithRemoteApi { +final class GenerateZoneFilesCommand implements CommandWithConnection { @Parameter( description = "One or more TLDs to generate zone files for", diff --git a/core/src/main/java/google/registry/tools/GetAllocationTokenCommand.java b/core/src/main/java/google/registry/tools/GetAllocationTokenCommand.java index 6800d894e..cbd0e1099 100644 --- a/core/src/main/java/google/registry/tools/GetAllocationTokenCommand.java +++ b/core/src/main/java/google/registry/tools/GetAllocationTokenCommand.java @@ -32,7 +32,7 @@ import java.util.Optional; /** Command to show allocation tokens. */ @Parameters(separators = " =", commandDescription = "Show allocation token(s)") -final class GetAllocationTokenCommand implements CommandWithRemoteApi { +final class GetAllocationTokenCommand implements Command { @Parameter( description = "Allocation token(s)", diff --git a/core/src/main/java/google/registry/tools/GetClaimsListCommand.java b/core/src/main/java/google/registry/tools/GetClaimsListCommand.java index 272b0aa9a..ad59aa9a6 100644 --- a/core/src/main/java/google/registry/tools/GetClaimsListCommand.java +++ b/core/src/main/java/google/registry/tools/GetClaimsListCommand.java @@ -34,7 +34,7 @@ import java.nio.file.Paths; * currently storing in SQL. */ @Parameters(separators = " =", commandDescription = "Download the current claims list") -final class GetClaimsListCommand implements CommandWithRemoteApi { +final class GetClaimsListCommand implements Command { @Parameter( names = {"-o", "--output"}, diff --git a/core/src/main/java/google/registry/tools/GetDatabaseMigrationStateCommand.java b/core/src/main/java/google/registry/tools/GetDatabaseMigrationStateCommand.java index 6571dc28d..16cc2c6cc 100644 --- a/core/src/main/java/google/registry/tools/GetDatabaseMigrationStateCommand.java +++ b/core/src/main/java/google/registry/tools/GetDatabaseMigrationStateCommand.java @@ -23,7 +23,7 @@ import google.registry.model.common.TimedTransitionProperty; /** A command to check the current Registry 3.0 migration state of the database. */ @DeleteAfterMigration @Parameters(separators = " =", commandDescription = "Check current Registry 3.0 migration state") -public class GetDatabaseMigrationStateCommand implements CommandWithRemoteApi { +public class GetDatabaseMigrationStateCommand implements Command { @Override public void run() throws Exception { diff --git a/core/src/main/java/google/registry/tools/GetEppResourceCommand.java b/core/src/main/java/google/registry/tools/GetEppResourceCommand.java index fcd6d052f..700b7ab6a 100644 --- a/core/src/main/java/google/registry/tools/GetEppResourceCommand.java +++ b/core/src/main/java/google/registry/tools/GetEppResourceCommand.java @@ -26,7 +26,7 @@ import org.joda.time.DateTime; /** Abstract command to print one or more resources to stdout. */ @Parameters(separators = " =") -abstract class GetEppResourceCommand implements CommandWithRemoteApi { +abstract class GetEppResourceCommand implements Command { @Parameter( names = "--read_timestamp", diff --git a/core/src/main/java/google/registry/tools/GetHistoryEntriesCommand.java b/core/src/main/java/google/registry/tools/GetHistoryEntriesCommand.java index c33a4937d..09da533ec 100644 --- a/core/src/main/java/google/registry/tools/GetHistoryEntriesCommand.java +++ b/core/src/main/java/google/registry/tools/GetHistoryEntriesCommand.java @@ -34,7 +34,7 @@ import org.joda.time.DateTime; @Parameters( separators = " =", commandDescription = "Show history entries that occurred in a given time range") -final class GetHistoryEntriesCommand implements CommandWithRemoteApi { +final class GetHistoryEntriesCommand implements Command { @Parameter( names = {"-a", "--after"}, diff --git a/core/src/main/java/google/registry/tools/GetKeyringSecretCommand.java b/core/src/main/java/google/registry/tools/GetKeyringSecretCommand.java index 63eb0d6d9..bb5ac9973 100644 --- a/core/src/main/java/google/registry/tools/GetKeyringSecretCommand.java +++ b/core/src/main/java/google/registry/tools/GetKeyringSecretCommand.java @@ -30,10 +30,9 @@ import org.bouncycastle.openpgp.PGPKeyPair; /** Retrieves ASCII-armored secrets from the active {@link Keyring} implementation. */ @Parameters( - separators = " =", - commandDescription = "Retrieves the value of a secret from the keyring." -) -final class GetKeyringSecretCommand implements CommandWithRemoteApi { + separators = " =", + commandDescription = "Retrieves the value of a secret from the keyring.") +final class GetKeyringSecretCommand implements Command { @Inject Keyring keyring; diff --git a/core/src/main/java/google/registry/tools/GetPremiumListCommand.java b/core/src/main/java/google/registry/tools/GetPremiumListCommand.java index 8fed35ebd..d0dc5e06b 100644 --- a/core/src/main/java/google/registry/tools/GetPremiumListCommand.java +++ b/core/src/main/java/google/registry/tools/GetPremiumListCommand.java @@ -26,7 +26,7 @@ import java.util.stream.Collectors; /** Retrieves and prints one or more premium lists. */ @Parameters(separators = " =", commandDescription = "Show one or more premium lists") -public class GetPremiumListCommand implements CommandWithRemoteApi { +public class GetPremiumListCommand implements Command { @Parameter(description = "Name(s) of the premium list(s) to retrieve", required = true) private List mainParameters; diff --git a/core/src/main/java/google/registry/tools/GetRegistrarCommand.java b/core/src/main/java/google/registry/tools/GetRegistrarCommand.java index e70d3a100..fd2eeaa7c 100644 --- a/core/src/main/java/google/registry/tools/GetRegistrarCommand.java +++ b/core/src/main/java/google/registry/tools/GetRegistrarCommand.java @@ -23,7 +23,7 @@ import java.util.List; /** Command to show a registrar record. */ @Parameters(separators = " =", commandDescription = "Show registrar record(s)") -final class GetRegistrarCommand implements CommandWithRemoteApi { +final class GetRegistrarCommand implements Command { @Parameter( description = "Client identifier of the registrar account(s)", diff --git a/core/src/main/java/google/registry/tools/GetReservedListCommand.java b/core/src/main/java/google/registry/tools/GetReservedListCommand.java index 36995f4f7..77138a7e4 100644 --- a/core/src/main/java/google/registry/tools/GetReservedListCommand.java +++ b/core/src/main/java/google/registry/tools/GetReservedListCommand.java @@ -24,7 +24,7 @@ import java.util.stream.Collectors; /** Retrieves and prints one or more reserved lists. */ @Parameters(separators = " =", commandDescription = "Show one or more reserved lists") -public class GetReservedListCommand implements CommandWithRemoteApi { +public class GetReservedListCommand implements Command { @Parameter( names = {"-n", "--name"}, diff --git a/core/src/main/java/google/registry/tools/GetTldCommand.java b/core/src/main/java/google/registry/tools/GetTldCommand.java index 572fe55db..966d6ab20 100644 --- a/core/src/main/java/google/registry/tools/GetTldCommand.java +++ b/core/src/main/java/google/registry/tools/GetTldCommand.java @@ -23,7 +23,7 @@ import java.util.List; /** Command to show a TLD record. */ @Parameters(separators = " =", commandDescription = "Show TLD record(s)") -final class GetTldCommand implements CommandWithRemoteApi { +final class GetTldCommand implements Command { @Parameter( description = "TLD(s) to show", diff --git a/core/src/main/java/google/registry/tools/GhostrydeCommand.java b/core/src/main/java/google/registry/tools/GhostrydeCommand.java index ba219f3d7..e34a300ef 100644 --- a/core/src/main/java/google/registry/tools/GhostrydeCommand.java +++ b/core/src/main/java/google/registry/tools/GhostrydeCommand.java @@ -37,7 +37,7 @@ import org.bouncycastle.openpgp.PGPPublicKey; /** Command to encrypt/decrypt {@code .ghostryde} files. */ @Parameters(separators = " =", commandDescription = "Encrypt/decrypt a ghostryde file.") -final class GhostrydeCommand implements CommandWithRemoteApi { +final class GhostrydeCommand implements Command { @Parameter( names = {"-e", "--encrypt"}, diff --git a/core/src/main/java/google/registry/tools/ListCursorsCommand.java b/core/src/main/java/google/registry/tools/ListCursorsCommand.java index a36080ff8..979e5b282 100644 --- a/core/src/main/java/google/registry/tools/ListCursorsCommand.java +++ b/core/src/main/java/google/registry/tools/ListCursorsCommand.java @@ -32,7 +32,7 @@ import java.util.Optional; /** Lists {@link Cursor} timestamps used by locking rolling cursor tasks, like in RDE. */ @Parameters(separators = " =", commandDescription = "Lists cursor timestamps used by LRC tasks") -final class ListCursorsCommand implements CommandWithRemoteApi { +final class ListCursorsCommand implements Command { @Parameter(names = "--type", description = "Which cursor to list.", required = true) private CursorType cursorType; diff --git a/core/src/main/java/google/registry/tools/ListObjectsCommand.java b/core/src/main/java/google/registry/tools/ListObjectsCommand.java index cee21dd83..0195ad38f 100644 --- a/core/src/main/java/google/registry/tools/ListObjectsCommand.java +++ b/core/src/main/java/google/registry/tools/ListObjectsCommand.java @@ -33,7 +33,7 @@ import org.json.simple.JSONValue; * *

The formatting is done on the server side; this class just dumps the results to the screen. */ -abstract class ListObjectsCommand implements CommandWithConnection, CommandWithRemoteApi { +abstract class ListObjectsCommand implements CommandWithConnection { @Nullable @Parameter( diff --git a/core/src/main/java/google/registry/tools/LoadTestCommand.java b/core/src/main/java/google/registry/tools/LoadTestCommand.java index b0d185937..f47379c04 100644 --- a/core/src/main/java/google/registry/tools/LoadTestCommand.java +++ b/core/src/main/java/google/registry/tools/LoadTestCommand.java @@ -24,8 +24,7 @@ import google.registry.model.tld.Registries; /** Command to initiate a load-test. */ @Parameters(separators = " =", commandDescription = "Run a load test.") -class LoadTestCommand extends ConfirmingCommand - implements CommandWithConnection, CommandWithRemoteApi { +class LoadTestCommand extends ConfirmingCommand implements CommandWithConnection { // This is a mostly arbitrary value, roughly two and a half hours. It served as a generous // timespan for initial backup/restore testing, but has no other special significance. diff --git a/core/src/main/java/google/registry/tools/LockOrUnlockDomainCommand.java b/core/src/main/java/google/registry/tools/LockOrUnlockDomainCommand.java index 5b17f7af8..a2f47ee9a 100644 --- a/core/src/main/java/google/registry/tools/LockOrUnlockDomainCommand.java +++ b/core/src/main/java/google/registry/tools/LockOrUnlockDomainCommand.java @@ -35,8 +35,7 @@ import java.util.List; import javax.inject.Inject; /** Shared base class for commands to registry lock or unlock a domain via EPP. */ -public abstract class LockOrUnlockDomainCommand extends ConfirmingCommand - implements CommandWithRemoteApi { +public abstract class LockOrUnlockDomainCommand extends ConfirmingCommand { private static final FluentLogger logger = FluentLogger.forEnclosingClass(); diff --git a/core/src/main/java/google/registry/tools/MutatingCommand.java b/core/src/main/java/google/registry/tools/MutatingCommand.java index 4fc738a86..3f933bb07 100644 --- a/core/src/main/java/google/registry/tools/MutatingCommand.java +++ b/core/src/main/java/google/registry/tools/MutatingCommand.java @@ -41,7 +41,7 @@ import java.util.Set; import javax.annotation.Nullable; /** A {@link ConfirmingCommand} that changes objects in Datastore. */ -public abstract class MutatingCommand extends ConfirmingCommand implements CommandWithRemoteApi { +public abstract class MutatingCommand extends ConfirmingCommand { /** * A mutation of a specific entity, represented by an old and a new version of the entity. Storing diff --git a/core/src/main/java/google/registry/tools/PendingEscrowCommand.java b/core/src/main/java/google/registry/tools/PendingEscrowCommand.java index 8b837ec27..539e85f0a 100644 --- a/core/src/main/java/google/registry/tools/PendingEscrowCommand.java +++ b/core/src/main/java/google/registry/tools/PendingEscrowCommand.java @@ -25,7 +25,7 @@ import javax.inject.Inject; /** Command to show what escrow deposits are pending generation on the server. */ @Parameters(separators = " =", commandDescription = "List pending RDE/BRDA deposits.") -final class PendingEscrowCommand implements CommandWithRemoteApi { +final class PendingEscrowCommand implements Command { private static final Ordering SORTER = new Ordering() { diff --git a/core/src/main/java/google/registry/tools/RegistryCli.java b/core/src/main/java/google/registry/tools/RegistryCli.java index 5720fcc27..898614e44 100644 --- a/core/src/main/java/google/registry/tools/RegistryCli.java +++ b/core/src/main/java/google/registry/tools/RegistryCli.java @@ -15,25 +15,21 @@ package google.registry.tools; import static com.google.common.base.Preconditions.checkState; +import static google.registry.persistence.transaction.TransactionManagerFactory.jpaTm; import static google.registry.tools.Injector.injectReflectively; -import static java.nio.charset.StandardCharsets.UTF_8; import com.beust.jcommander.JCommander; import com.beust.jcommander.Parameter; import com.beust.jcommander.ParameterException; import com.beust.jcommander.Parameters; import com.beust.jcommander.ParametersDelegate; -import com.google.appengine.tools.remoteapi.RemoteApiInstaller; -import com.google.appengine.tools.remoteapi.RemoteApiOptions; import com.google.common.base.Throwables; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Iterables; -import google.registry.config.RegistryConfig; +import google.registry.persistence.transaction.JpaTransactionManager; import google.registry.persistence.transaction.TransactionManagerFactory; import google.registry.tools.AuthModule.LoginRequiredException; import google.registry.tools.params.ParameterFactory; -import java.io.ByteArrayInputStream; -import java.net.URL; import java.security.Security; import java.util.Map; import java.util.Optional; @@ -42,7 +38,7 @@ import org.postgresql.util.PSQLException; /** Container class to create and run remote commands against a Datastore instance. */ @Parameters(separators = " =", commandDescription = "Command-line interface to the registry") -final class RegistryCli implements AutoCloseable, CommandRunner { +final class RegistryCli implements CommandRunner { // The environment parameter is parsed twice: once here, and once with {@link // RegistryToolEnvironment#parseFromArgs} in the {@link RegistryTool#main} function. @@ -78,9 +74,8 @@ final class RegistryCli implements AutoCloseable, CommandRunner { RegistryToolComponent component; - // These are created lazily on first use. + // This is created lazily on first use. private ServiceConnection connection; - private RemoteApiInstaller installer; // The "shell" command should only exist on first use - so that we can't run "shell" inside // "shell". @@ -206,24 +201,6 @@ final class RegistryCli implements AutoCloseable, CommandRunner { } } - @Override - public void close() { - if (installer != null) { - try { - installer.uninstall(); - installer = null; - } catch (IllegalArgumentException e) { - // There is no point throwing the error if the API is already uninstalled, which is most - // likely caused by something wrong when installing the API. That something (e. g. no - // credential found) must have already thrown an error message earlier (e. g. must run - // "nomulus login" first). This error message here is non-actionable. - if (!e.getMessage().equals("remote API is already uninstalled")) { - throw e; - } - } - } - } - private ServiceConnection getConnection() { // Get the App Engine connection, advise the user if they are not currently logged in.. if (connection == null) { @@ -239,37 +216,14 @@ final class RegistryCli implements AutoCloseable, CommandRunner { ((CommandWithConnection) command).setConnection(getConnection()); } - // CommandWithRemoteApis need to have the remote api installed to work. - if (command instanceof CommandWithRemoteApi) { - if (installer == null) { - installer = new RemoteApiInstaller(); - RemoteApiOptions options = new RemoteApiOptions(); - options.server( - getConnection().getServer().getHost(), getPort(getConnection().getServer())); - if (RegistryConfig.areServersLocal()) { - // Use dev credentials for localhost. - options.useDevelopmentServerCredential(); - } else { - RemoteApiOptionsUtil.useGoogleCredentialStream( - options, new ByteArrayInputStream(component.googleCredentialJson().getBytes(UTF_8))); - } - installer.install(options); - - // Enable Cloud SQL for command that needs remote API as they will very likely use - // Cloud SQL after the database migration. Note that the DB password is stored in Datastore - // and it is already initialized above. - TransactionManagerFactory.setJpaTm( - () -> component.nomulusToolJpaTransactionManager().get()); - TransactionManagerFactory.setReplicaJpaTm( - () -> component.nomulusToolReplicaJpaTransactionManager().get()); - } - } - + // Reset the JPA transaction manager after every command to avoid a situation where a test can + // interfere with other tests + JpaTransactionManager cachedJpaTm = jpaTm(); + TransactionManagerFactory.setJpaTm(() -> component.nomulusToolJpaTransactionManager().get()); + TransactionManagerFactory.setReplicaJpaTm( + () -> component.nomulusToolReplicaJpaTransactionManager().get()); command.run(); - } - - private int getPort(URL url) { - return url.getPort() == -1 ? url.getDefaultPort() : url.getPort(); + TransactionManagerFactory.setJpaTm(() -> cachedJpaTm); } void setEnvironment(RegistryToolEnvironment environment) { diff --git a/core/src/main/java/google/registry/tools/RegistryTool.java b/core/src/main/java/google/registry/tools/RegistryTool.java index 3dca22fa2..7c0154602 100644 --- a/core/src/main/java/google/registry/tools/RegistryTool.java +++ b/core/src/main/java/google/registry/tools/RegistryTool.java @@ -17,7 +17,6 @@ package google.registry.tools; import com.google.common.collect.ImmutableMap; import google.registry.tools.javascrap.CompareEscrowDepositsCommand; import google.registry.tools.javascrap.CreateCancellationsForOneTimesCommand; -import google.registry.tools.javascrap.CreateSyntheticDomainHistoriesCommand; /** Container class to create and run remote commands against a Datastore instance. */ public final class RegistryTool { @@ -48,7 +47,6 @@ public final class RegistryTool { .put("create_registrar", CreateRegistrarCommand.class) .put("create_registrar_groups", CreateRegistrarGroupsCommand.class) .put("create_reserved_list", CreateReservedListCommand.class) - .put("create_synthetic_domain_histories", CreateSyntheticDomainHistoriesCommand.class) .put("create_tld", CreateTldCommand.class) .put("curl", CurlCommand.class) .put("delete_allocation_tokens", DeleteAllocationTokensCommand.class) @@ -123,8 +121,7 @@ public final class RegistryTool { public static void main(String[] args) throws Exception { RegistryToolEnvironment.parseFromArgs(args).setup(); - try (RegistryCli cli = new RegistryCli("nomulus", COMMAND_MAP)) { - cli.run(args); - } + RegistryCli cli = new RegistryCli("nomulus", COMMAND_MAP); + cli.run(args); } } diff --git a/core/src/main/java/google/registry/tools/RegistryToolComponent.java b/core/src/main/java/google/registry/tools/RegistryToolComponent.java index b86ed04eb..b4d3bc55b 100644 --- a/core/src/main/java/google/registry/tools/RegistryToolComponent.java +++ b/core/src/main/java/google/registry/tools/RegistryToolComponent.java @@ -42,7 +42,6 @@ import google.registry.request.Modules.UserServiceModule; import google.registry.tools.AuthModule.LocalCredentialModule; import google.registry.tools.javascrap.CompareEscrowDepositsCommand; import google.registry.tools.javascrap.CreateCancellationsForOneTimesCommand; -import google.registry.tools.javascrap.CreateSyntheticDomainHistoriesCommand; import google.registry.util.UtilsModule; import google.registry.whois.NonCachingWhoisModule; import javax.annotation.Nullable; @@ -106,8 +105,6 @@ interface RegistryToolComponent { void inject(CreateRegistrarCommand command); - void inject(CreateSyntheticDomainHistoriesCommand command); - void inject(CreateTldCommand command); void inject(EncryptEscrowDepositCommand command); diff --git a/core/src/main/java/google/registry/tools/RemoteApiOptionsUtil.java b/core/src/main/java/google/registry/tools/RemoteApiOptionsUtil.java deleted file mode 100644 index 3db65f242..000000000 --- a/core/src/main/java/google/registry/tools/RemoteApiOptionsUtil.java +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright 2018 The Nomulus Authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package google.registry.tools; - -import static com.google.common.base.Preconditions.checkState; - -import com.google.appengine.tools.remoteapi.RemoteApiOptions; -import java.io.InputStream; -import java.lang.reflect.Method; - -/** - * Provides a method to access {@link RemoteApiOptions#useGoogleCredentialStream(InputStream)}, - * which is a package private method. - * - *

This is obviously a hack, but until that method is exposed, we have to do this to set up the - * {@link RemoteApiOptions} with a JSON representing a user credential. - */ -public class RemoteApiOptionsUtil { - public static RemoteApiOptions useGoogleCredentialStream( - RemoteApiOptions options, InputStream stream) throws Exception { - Method method = - options.getClass().getDeclaredMethod("useGoogleCredentialStream", InputStream.class); - checkState( - !method.isAccessible(), - "RemoteApiOptoins#useGoogleCredentialStream(InputStream) is accessible." - + " Stop using RemoteApiOptionsUtil."); - method.setAccessible(true); - method.invoke(options, stream); - method.setAccessible(false); - return options; - } -} diff --git a/core/src/main/java/google/registry/tools/SendEscrowReportToIcannCommand.java b/core/src/main/java/google/registry/tools/SendEscrowReportToIcannCommand.java index 7cfd1870e..35b6ff255 100644 --- a/core/src/main/java/google/registry/tools/SendEscrowReportToIcannCommand.java +++ b/core/src/main/java/google/registry/tools/SendEscrowReportToIcannCommand.java @@ -26,7 +26,7 @@ import javax.inject.Inject; /** Command to send ICANN notification that an escrow deposit was uploaded. */ @Parameters(separators = " =", commandDescription = "Send an ICANN report of an uploaded deposit.") -final class SendEscrowReportToIcannCommand implements CommandWithRemoteApi { +final class SendEscrowReportToIcannCommand implements Command { @Parameter( description = "One or more foo-report.xml files.", diff --git a/core/src/main/java/google/registry/tools/SetDatabaseMigrationStateCommand.java b/core/src/main/java/google/registry/tools/SetDatabaseMigrationStateCommand.java index f880eced6..19d588311 100644 --- a/core/src/main/java/google/registry/tools/SetDatabaseMigrationStateCommand.java +++ b/core/src/main/java/google/registry/tools/SetDatabaseMigrationStateCommand.java @@ -30,8 +30,7 @@ import org.joda.time.DateTime; @Parameters( separators = " =", commandDescription = "Set the current database migration state schedule.") -public class SetDatabaseMigrationStateCommand extends ConfirmingCommand - implements CommandWithRemoteApi { +public class SetDatabaseMigrationStateCommand extends ConfirmingCommand { private static final String WARNING_MESSAGE = "Attempting to change the schedule with an effect that would take place within the next 10 " diff --git a/core/src/main/java/google/registry/tools/SetNumInstancesCommand.java b/core/src/main/java/google/registry/tools/SetNumInstancesCommand.java index 67d94d6ed..c6471328c 100644 --- a/core/src/main/java/google/registry/tools/SetNumInstancesCommand.java +++ b/core/src/main/java/google/registry/tools/SetNumInstancesCommand.java @@ -39,7 +39,7 @@ import javax.inject.Inject; commandDescription = "Set the number of instances for a given service and version. " + "Note that this command only works for manual scaling service.") -final class SetNumInstancesCommand implements CommandWithRemoteApi { +final class SetNumInstancesCommand implements Command { private static final FluentLogger logger = FluentLogger.forEnclosingClass(); diff --git a/core/src/main/java/google/registry/tools/SetupOteCommand.java b/core/src/main/java/google/registry/tools/SetupOteCommand.java index 50a05ae7b..0bc55a19e 100644 --- a/core/src/main/java/google/registry/tools/SetupOteCommand.java +++ b/core/src/main/java/google/registry/tools/SetupOteCommand.java @@ -35,7 +35,7 @@ import javax.inject.Named; /** Composite command to set up OT&E TLDs and accounts. */ @Parameters(separators = " =", commandDescription = "Set up OT&E TLDs and registrars") -final class SetupOteCommand extends ConfirmingCommand implements CommandWithRemoteApi { +final class SetupOteCommand extends ConfirmingCommand { private static final int PASSWORD_LENGTH = 16; diff --git a/core/src/main/java/google/registry/tools/UnrenewDomainCommand.java b/core/src/main/java/google/registry/tools/UnrenewDomainCommand.java index 55916f693..6fb141d0b 100644 --- a/core/src/main/java/google/registry/tools/UnrenewDomainCommand.java +++ b/core/src/main/java/google/registry/tools/UnrenewDomainCommand.java @@ -58,7 +58,7 @@ import org.joda.time.DateTime; */ @Parameters(separators = " =", commandDescription = "Unrenew a domain.") @NonFinalForTesting -class UnrenewDomainCommand extends ConfirmingCommand implements CommandWithRemoteApi { +class UnrenewDomainCommand extends ConfirmingCommand { @Parameter( names = {"-p", "--period"}, diff --git a/core/src/main/java/google/registry/tools/UpdateCursorsCommand.java b/core/src/main/java/google/registry/tools/UpdateCursorsCommand.java index 6a6688e04..140b6c9f6 100644 --- a/core/src/main/java/google/registry/tools/UpdateCursorsCommand.java +++ b/core/src/main/java/google/registry/tools/UpdateCursorsCommand.java @@ -29,7 +29,7 @@ import org.joda.time.DateTime; /** Modifies {@link Cursor} timestamps used by locking rolling cursor tasks, like in RDE. */ @Parameters(separators = " =", commandDescription = "Modifies cursor timestamps used by LRC tasks") -final class UpdateCursorsCommand extends ConfirmingCommand implements CommandWithRemoteApi { +final class UpdateCursorsCommand extends ConfirmingCommand implements Command { @Parameter(description = "TLDs on which to operate. Omit for global cursors.") private List tlds; diff --git a/core/src/main/java/google/registry/tools/UpdateKeyringSecretCommand.java b/core/src/main/java/google/registry/tools/UpdateKeyringSecretCommand.java index a366e484d..3185e85f8 100644 --- a/core/src/main/java/google/registry/tools/UpdateKeyringSecretCommand.java +++ b/core/src/main/java/google/registry/tools/UpdateKeyringSecretCommand.java @@ -31,7 +31,7 @@ import javax.inject.Inject; * Command to set and update ASCII-armored secret from the active {@code Keyring} implementation. */ @Parameters(separators = " =", commandDescription = "Update values of secret in the keyring.") -final class UpdateKeyringSecretCommand implements CommandWithRemoteApi { +final class UpdateKeyringSecretCommand implements Command { @Inject SecretManagerKeyringUpdater secretManagerKeyringUpdater; diff --git a/core/src/main/java/google/registry/tools/UpdateOrDeleteAllocationTokensCommand.java b/core/src/main/java/google/registry/tools/UpdateOrDeleteAllocationTokensCommand.java index acb9310fc..58044ace0 100644 --- a/core/src/main/java/google/registry/tools/UpdateOrDeleteAllocationTokensCommand.java +++ b/core/src/main/java/google/registry/tools/UpdateOrDeleteAllocationTokensCommand.java @@ -26,8 +26,7 @@ import google.registry.persistence.VKey; import java.util.List; /** Shared base class for commands to update or delete allocation tokens. */ -abstract class UpdateOrDeleteAllocationTokensCommand extends ConfirmingCommand - implements CommandWithRemoteApi { +abstract class UpdateOrDeleteAllocationTokensCommand extends ConfirmingCommand { @Parameter( names = {"-p", "--prefix"}, diff --git a/core/src/main/java/google/registry/tools/UploadClaimsListCommand.java b/core/src/main/java/google/registry/tools/UploadClaimsListCommand.java index 6e0753ffd..0463d1605 100644 --- a/core/src/main/java/google/registry/tools/UploadClaimsListCommand.java +++ b/core/src/main/java/google/registry/tools/UploadClaimsListCommand.java @@ -31,7 +31,7 @@ import java.util.List; /** A command to upload a {@link ClaimsList}. */ @Parameters(separators = " =", commandDescription = "Manually upload a new claims list file") -final class UploadClaimsListCommand extends ConfirmingCommand implements CommandWithRemoteApi { +final class UploadClaimsListCommand extends ConfirmingCommand { @Parameter(description = "Claims list filename") private List mainParameters = new ArrayList<>(); diff --git a/core/src/main/java/google/registry/tools/ValidateLoginCredentialsCommand.java b/core/src/main/java/google/registry/tools/ValidateLoginCredentialsCommand.java index 6f7fea899..76c9bd1fa 100644 --- a/core/src/main/java/google/registry/tools/ValidateLoginCredentialsCommand.java +++ b/core/src/main/java/google/registry/tools/ValidateLoginCredentialsCommand.java @@ -35,7 +35,7 @@ import javax.inject.Inject; /** A command to test registrar login credentials. */ @Parameters(separators = " =", commandDescription = "Test registrar login credentials") -final class ValidateLoginCredentialsCommand implements CommandWithRemoteApi { +final class ValidateLoginCredentialsCommand implements Command { @Parameter( names = {"-c", "--client"}, diff --git a/core/src/main/java/google/registry/tools/VerifyOteCommand.java b/core/src/main/java/google/registry/tools/VerifyOteCommand.java index c067e97a9..ec26c4b1e 100644 --- a/core/src/main/java/google/registry/tools/VerifyOteCommand.java +++ b/core/src/main/java/google/registry/tools/VerifyOteCommand.java @@ -45,7 +45,7 @@ import java.util.Objects; @Parameters( separators = " =", commandDescription = "Verify passage of OT&E for specified (or all) registrars") -final class VerifyOteCommand implements CommandWithConnection, CommandWithRemoteApi { +final class VerifyOteCommand implements CommandWithConnection { @Parameter( description = "List of registrar names to check; must be the same names as the ones used " diff --git a/core/src/main/java/google/registry/tools/WhoisQueryCommand.java b/core/src/main/java/google/registry/tools/WhoisQueryCommand.java index df2367a1c..05e7a1ae0 100644 --- a/core/src/main/java/google/registry/tools/WhoisQueryCommand.java +++ b/core/src/main/java/google/registry/tools/WhoisQueryCommand.java @@ -23,7 +23,7 @@ import javax.inject.Inject; /** Command to execute a WHOIS query. */ @Parameters(separators = " =", commandDescription = "Manually perform a WHOIS query") -final class WhoisQueryCommand implements CommandWithRemoteApi { +final class WhoisQueryCommand implements Command { @Parameter( description = "WHOIS query string", diff --git a/core/src/main/java/google/registry/tools/javascrap/CreateCancellationsForOneTimesCommand.java b/core/src/main/java/google/registry/tools/javascrap/CreateCancellationsForOneTimesCommand.java index 4f967d2d6..17537b8fd 100644 --- a/core/src/main/java/google/registry/tools/javascrap/CreateCancellationsForOneTimesCommand.java +++ b/core/src/main/java/google/registry/tools/javascrap/CreateCancellationsForOneTimesCommand.java @@ -24,7 +24,6 @@ import google.registry.model.billing.BillingEvent.Cancellation; import google.registry.model.billing.BillingEvent.OneTime; import google.registry.persistence.VKey; import google.registry.persistence.transaction.QueryComposer.Comparator; -import google.registry.tools.CommandWithRemoteApi; import google.registry.tools.ConfirmingCommand; import google.registry.tools.params.LongParameter; import java.util.List; @@ -37,8 +36,7 @@ import java.util.List; * refunds after the fact. */ @Parameters(separators = " =", commandDescription = "Manually create Cancellations for OneTimes.") -public class CreateCancellationsForOneTimesCommand extends ConfirmingCommand - implements CommandWithRemoteApi { +public class CreateCancellationsForOneTimesCommand extends ConfirmingCommand { @Parameter( description = "Space-delimited billing event ID(s) to cancel", diff --git a/core/src/main/java/google/registry/tools/javascrap/CreateSyntheticDomainHistoriesCommand.java b/core/src/main/java/google/registry/tools/javascrap/CreateSyntheticDomainHistoriesCommand.java deleted file mode 100644 index a4bf0b103..000000000 --- a/core/src/main/java/google/registry/tools/javascrap/CreateSyntheticDomainHistoriesCommand.java +++ /dev/null @@ -1,207 +0,0 @@ -// Copyright 2022 The Nomulus Authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package google.registry.tools.javascrap; - -import static com.google.common.collect.ImmutableSet.toImmutableSet; -import static google.registry.persistence.transaction.TransactionManagerFactory.jpaTm; -import static java.nio.charset.StandardCharsets.UTF_8; - -import com.beust.jcommander.Parameters; -import com.google.appengine.tools.remoteapi.RemoteApiInstaller; -import com.google.appengine.tools.remoteapi.RemoteApiOptions; -import com.google.common.collect.ImmutableSet; -import com.google.common.flogger.FluentLogger; -import google.registry.config.CredentialModule; -import google.registry.config.RegistryConfig; -import google.registry.config.RegistryConfig.Config; -import google.registry.model.domain.Domain; -import google.registry.model.reporting.HistoryEntry; -import google.registry.persistence.VKey; -import google.registry.tools.CommandWithConnection; -import google.registry.tools.CommandWithRemoteApi; -import google.registry.tools.ConfirmingCommand; -import google.registry.tools.RemoteApiOptionsUtil; -import google.registry.tools.ServiceConnection; -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.net.URL; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicInteger; -import javax.inject.Inject; -import org.joda.time.DateTime; - -/** - * Command that creates an additional synthetic history object for domains. - * - *

This is created to fix the issue identified in b/248112997. After b/245940594, there were some - * domains where the most recent history object did not represent the state of the domain as it - * exists in the world. Because RDE loads only from DomainHistory objects, this means that RDE was - * producing wrong data. This command mitigates that issue by creating synthetic history events for - * every domain that was not deleted as of the start of the bad {@link - * google.registry.beam.resave.ResaveAllEppResourcesPipeline} -- then, we can guarantee that this - * new history object represents the state of the domain as far as we know. - * - *

A previous run of this command (in pipeline form) attempted to do this and succeeded in most - * cases. Unfortunately, that pipeline had an issue where it used self-allocated IDs for some of the - * dependent objects (e.g. {@link google.registry.model.domain.secdns.DomainDsDataHistory}). As a - * result, we want to run this again as a command using Datastore-allocated IDs to re-create - * synthetic history objects for any domain whose last history object is one of the - * potentially-incorrect synthetic objects. - * - *

We further restrict the domains to domains whose latest history object is before October 4. - * This is an arbitrary date that is suitably far after the previous incorrect run of this synthetic - * history pipeline, with the purpose of making future runs of this command idempotent (in case the - * command fails, we can just run it again and again). - */ -@Parameters( - separators = " =", - commandDescription = "Create synthetic domain history objects to fix RDE.") -public class CreateSyntheticDomainHistoriesCommand extends ConfirmingCommand - implements CommandWithRemoteApi, CommandWithConnection { - - private static final FluentLogger logger = FluentLogger.forEnclosingClass(); - - private static final String HISTORY_REASON = - "Create synthetic domain histories to fix RDE for b/248112997"; - private static final DateTime BAD_PIPELINE_END_TIME = DateTime.parse("2022-09-10T12:00:00.000Z"); - private static final DateTime NEW_SYNTHETIC_ROUND_START = - DateTime.parse("2022-10-04T00:00:00.000Z"); - - private static final ExecutorService executor = Executors.newFixedThreadPool(20); - private static final AtomicInteger numDomainsProcessed = new AtomicInteger(); - - private ServiceConnection connection; - - @Inject - @Config("registryAdminClientId") - String registryAdminRegistrarId; - - @Inject @CredentialModule.LocalCredentialJson String localCredentialJson; - - private final ThreadLocal installerThreadLocal = - ThreadLocal.withInitial(this::createInstaller); - - private ImmutableSet domainRepoIds; - - @Override - protected String prompt() { - jpaTm() - .transact( - () -> { - domainRepoIds = - jpaTm() - .query( - "SELECT dh.domainRepoId FROM DomainHistory dh JOIN Tld t ON t.tldStr =" - + " dh.domainBase.tld WHERE t.tldType = 'REAL' AND dh.type =" - + " 'SYNTHETIC' AND dh.modificationTime > :badPipelineEndTime AND" - + " dh.modificationTime < :newSyntheticRoundStart AND" - + " (dh.domainRepoId, dh.modificationTime) IN (SELECT domainRepoId," - + " MAX(modificationTime) FROM DomainHistory GROUP BY domainRepoId)", - String.class) - .setParameter("badPipelineEndTime", BAD_PIPELINE_END_TIME) - .setParameter("newSyntheticRoundStart", NEW_SYNTHETIC_ROUND_START) - .getResultStream() - .collect(toImmutableSet()); - }); - return String.format( - "Attempt to create synthetic history entries for %d domains?", domainRepoIds.size()); - } - - @Override - protected String execute() throws Exception { - List> futures = new ArrayList<>(); - for (String domainRepoId : domainRepoIds) { - futures.add( - executor.submit( - () -> { - // Make sure the remote API is installed for ID generation - installerThreadLocal.get(); - jpaTm() - .transact( - () -> { - Domain domain = - jpaTm().loadByKey(VKey.create(Domain.class, domainRepoId)); - jpaTm() - .put( - HistoryEntry.createBuilderForResource(domain) - .setRegistrarId(registryAdminRegistrarId) - .setBySuperuser(true) - .setRequestedByRegistrar(false) - .setModificationTime(jpaTm().getTransactionTime()) - .setReason(HISTORY_REASON) - .setType(HistoryEntry.Type.SYNTHETIC) - .build()); - }); - int numProcessed = numDomainsProcessed.incrementAndGet(); - if (numProcessed % 1000 == 0) { - System.out.printf("Saved histories for %d domains%n", numProcessed); - } - return null; - })); - } - for (Future future : futures) { - try { - future.get(); - } catch (Exception e) { - logger.atSevere().withCause(e).log("Error"); - } - } - executor.shutdown(); - executor.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS); - return String.format("Saved entries for %d domains", numDomainsProcessed.get()); - } - - @Override - public void setConnection(ServiceConnection connection) { - this.connection = connection; - } - - /** - * Installs the remote API so that the worker threads can use Datastore for ID generation. - * - *

Lifted from the RegistryCli class - */ - private RemoteApiInstaller createInstaller() { - RemoteApiInstaller installer = new RemoteApiInstaller(); - RemoteApiOptions options = new RemoteApiOptions(); - options.server(connection.getServer().getHost(), getPort(connection.getServer())); - if (RegistryConfig.areServersLocal()) { - // Use dev credentials for localhost. - options.useDevelopmentServerCredential(); - } else { - try { - RemoteApiOptionsUtil.useGoogleCredentialStream( - options, new ByteArrayInputStream(localCredentialJson.getBytes(UTF_8))); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - try { - installer.install(options); - } catch (IOException e) { - throw new RuntimeException(e); - } - return installer; - } - - private static int getPort(URL url) { - return url.getPort() == -1 ? url.getDefaultPort() : url.getPort(); - } -} diff --git a/core/src/nonprod/java/google/registry/tools/DevTool.java b/core/src/nonprod/java/google/registry/tools/DevTool.java index 0bc8206dd..46c4aee14 100644 --- a/core/src/nonprod/java/google/registry/tools/DevTool.java +++ b/core/src/nonprod/java/google/registry/tools/DevTool.java @@ -33,8 +33,7 @@ public class DevTool { public static void main(String[] args) throws Exception { RegistryToolEnvironment.parseFromArgs(args).setup(); - try (RegistryCli cli = new RegistryCli("devtool", COMMAND_MAP)) { - cli.run(args); - } + RegistryCli cli = new RegistryCli("devtool", COMMAND_MAP); + cli.run(args); } } diff --git a/core/src/test/java/google/registry/tools/ShellCommandTest.java b/core/src/test/java/google/registry/tools/ShellCommandTest.java index 62ba58cee..a3b0a2487 100644 --- a/core/src/test/java/google/registry/tools/ShellCommandTest.java +++ b/core/src/test/java/google/registry/tools/ShellCommandTest.java @@ -145,40 +145,29 @@ class ShellCommandTest { shellCommand.run(); } - static class MockCli implements CommandRunner { - public ArrayList> calls = new ArrayList<>(); - - @Override - public void run(String[] args) { - calls.add(ImmutableList.copyOf(args)); - } - } - @Test void testMultipleCommandInvocations() throws Exception { - try (RegistryCli cli = - new RegistryCli("unittest", ImmutableMap.of("test_command", TestCommand.class))) { - RegistryToolEnvironment.UNITTEST.setup(systemPropertyExtension); - cli.setEnvironment(RegistryToolEnvironment.UNITTEST); - cli.run(new String[] {"test_command", "-x", "xval", "arg1", "arg2"}); - cli.run(new String[] {"test_command", "-x", "otherxval", "arg3"}); - cli.run(new String[] {"test_command"}); - assertThat(TestCommand.commandInvocations) - .containsExactly( - ImmutableList.of("xval", "arg1", "arg2"), - ImmutableList.of("otherxval", "arg3"), - ImmutableList.of("default value")); - } + RegistryCli cli = + new RegistryCli("unittest", ImmutableMap.of("test_command", TestCommand.class)); + RegistryToolEnvironment.UNITTEST.setup(systemPropertyExtension); + cli.setEnvironment(RegistryToolEnvironment.UNITTEST); + cli.run(new String[] {"test_command", "-x", "xval", "arg1", "arg2"}); + cli.run(new String[] {"test_command", "-x", "otherxval", "arg3"}); + cli.run(new String[] {"test_command"}); + assertThat(TestCommand.commandInvocations) + .containsExactly( + ImmutableList.of("xval", "arg1", "arg2"), + ImmutableList.of("otherxval", "arg3"), + ImmutableList.of("default value")); } @Test void testNonExistentCommand() { - try (RegistryCli cli = - new RegistryCli("unittest", ImmutableMap.of("test_command", TestCommand.class))) { + RegistryCli cli = + new RegistryCli("unittest", ImmutableMap.of("test_command", TestCommand.class)); - cli.setEnvironment(RegistryToolEnvironment.UNITTEST); - assertThrows(MissingCommandException.class, () -> cli.run(new String[] {"bad_command"})); - } + cli.setEnvironment(RegistryToolEnvironment.UNITTEST); + assertThrows(MissingCommandException.class, () -> cli.run(new String[] {"bad_command"})); } private void performJCommanderCompletorTest( @@ -341,12 +330,22 @@ class ShellCommandTest { System.setIn(new ByteArrayInputStream("command1\n".getBytes(UTF_8))); } + static class MockCli implements CommandRunner { + public ArrayList> calls = new ArrayList<>(); + + @Override + public void run(String[] args) { + calls.add(ImmutableList.copyOf(args)); + } + } + @Parameters(commandDescription = "Test command") static class TestCommand implements Command { - enum OrgType { - PRIVATE, - PUBLIC - } + // List for recording command invocations by run(). + // + // This has to be static because it gets populated by multiple TestCommand instances, which are + // created in RegistryCli by using reflection to call the constructor. + static final List> commandInvocations = new ArrayList<>(); @Parameter( names = {"-x", "--xparam"}, @@ -357,13 +356,6 @@ class ShellCommandTest { names = {"--xorg"}, description = "test organization") OrgType orgType = OrgType.PRIVATE; - - // List for recording command invocations by run(). - // - // This has to be static because it gets populated by multiple TestCommand instances, which are - // created in RegistryCli by using reflection to call the constructor. - static final List> commandInvocations = new ArrayList<>(); - @Parameter(description = "normal argument") List args; @@ -378,6 +370,11 @@ class ShellCommandTest { } commandInvocations.add(callRecord.build()); } + + enum OrgType { + PRIVATE, + PUBLIC + } } @Parameters(commandDescription = "Another test command")