From 1e2b17fff700154a9c4553b3d305d98d7830d582 Mon Sep 17 00:00:00 2001 From: gbrodman Date: Mon, 5 Dec 2022 13:23:18 -0500 Subject: [PATCH] Remove usage of the AppEngine remote API (#1858) This is only used for contacting Datastore. With the removal of: 1. All standard usages of Datastore 2. Usage of Datastore for allocation of object IDs 3. Usage of Datastore for GAE user IDs we can remove the remote API without affecting functionality. This also allows us to just use SQL for every command since it's lazily supplied. This simplifies the SQL setup and means that we remove a possible situation where we forget the SQL setup. --- .../tools/AckPollMessagesCommand.java | 2 +- .../registry/tools/CommandWithRemoteApi.java | 23 -- .../registry/tools/CountDomainsCommand.java | 2 +- .../registry/tools/CreateDomainCommand.java | 3 +- .../CreateOrUpdatePremiumListCommand.java | 3 +- .../CreateOrUpdateReservedListCommand.java | 3 +- .../tools/CreateRegistrarCommand.java | 2 +- .../tools/CreateRegistrarGroupsCommand.java | 2 +- .../tools/DeletePremiumListCommand.java | 2 +- .../tools/DeleteReservedListCommand.java | 2 +- .../registry/tools/DeleteTldCommand.java | 2 +- .../tools/EncryptEscrowDepositCommand.java | 2 +- .../google/registry/tools/EppToolCommand.java | 3 +- .../GenerateAllocationTokensCommand.java | 2 +- .../tools/GenerateDnsReportCommand.java | 2 +- .../tools/GenerateEscrowDepositCommand.java | 2 +- .../registry/tools/GenerateLordnCommand.java | 2 +- .../tools/GenerateZoneFilesCommand.java | 2 +- .../tools/GetAllocationTokenCommand.java | 2 +- .../registry/tools/GetClaimsListCommand.java | 2 +- .../GetDatabaseMigrationStateCommand.java | 2 +- .../registry/tools/GetEppResourceCommand.java | 2 +- .../tools/GetHistoryEntriesCommand.java | 2 +- .../tools/GetKeyringSecretCommand.java | 7 +- .../registry/tools/GetPremiumListCommand.java | 2 +- .../registry/tools/GetRegistrarCommand.java | 2 +- .../tools/GetReservedListCommand.java | 2 +- .../google/registry/tools/GetTldCommand.java | 2 +- .../registry/tools/GhostrydeCommand.java | 2 +- .../registry/tools/ListCursorsCommand.java | 2 +- .../registry/tools/ListObjectsCommand.java | 2 +- .../registry/tools/LoadTestCommand.java | 3 +- .../tools/LockOrUnlockDomainCommand.java | 3 +- .../registry/tools/MutatingCommand.java | 2 +- .../registry/tools/PendingEscrowCommand.java | 2 +- .../google/registry/tools/RegistryCli.java | 68 +----- .../google/registry/tools/RegistryTool.java | 7 +- .../registry/tools/RegistryToolComponent.java | 3 - .../registry/tools/RemoteApiOptionsUtil.java | 44 ---- .../tools/SendEscrowReportToIcannCommand.java | 2 +- .../SetDatabaseMigrationStateCommand.java | 3 +- .../tools/SetNumInstancesCommand.java | 2 +- .../registry/tools/SetupOteCommand.java | 2 +- .../registry/tools/UnrenewDomainCommand.java | 2 +- .../registry/tools/UpdateCursorsCommand.java | 2 +- .../tools/UpdateKeyringSecretCommand.java | 2 +- ...UpdateOrDeleteAllocationTokensCommand.java | 3 +- .../tools/UploadClaimsListCommand.java | 2 +- .../ValidateLoginCredentialsCommand.java | 2 +- .../registry/tools/VerifyOteCommand.java | 2 +- .../registry/tools/WhoisQueryCommand.java | 2 +- ...CreateCancellationsForOneTimesCommand.java | 4 +- ...CreateSyntheticDomainHistoriesCommand.java | 207 ------------------ .../java/google/registry/tools/DevTool.java | 5 +- .../registry/tools/ShellCommandTest.java | 73 +++--- 55 files changed, 99 insertions(+), 440 deletions(-) delete mode 100644 core/src/main/java/google/registry/tools/CommandWithRemoteApi.java delete mode 100644 core/src/main/java/google/registry/tools/RemoteApiOptionsUtil.java delete mode 100644 core/src/main/java/google/registry/tools/javascrap/CreateSyntheticDomainHistoriesCommand.java 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")