From 08738c54c8c5f051d758d710f92746a3b7d50ad3 Mon Sep 17 00:00:00 2001 From: gbrodman Date: Fri, 11 Dec 2020 17:41:06 -0500 Subject: [PATCH] Add SetSqlReplayCheckpoint command for SQL replay (#895) * Add SetSqlReplayCheckpoint command for SQL replay We should set this to the same time that we initially populate the SQL database from Datastore. --- .../google/registry/tools/RegistryTool.java | 1 + .../registry/tools/RegistryToolComponent.java | 2 + .../tools/SetSqlReplayCheckpointCommand.java | 48 +++++++++++++++++++ .../SetSqlReplayCheckpointCommandTest.java | 42 ++++++++++++++++ 4 files changed, 93 insertions(+) create mode 100644 core/src/main/java/google/registry/tools/SetSqlReplayCheckpointCommand.java create mode 100644 core/src/test/java/google/registry/tools/SetSqlReplayCheckpointCommandTest.java diff --git a/core/src/main/java/google/registry/tools/RegistryTool.java b/core/src/main/java/google/registry/tools/RegistryTool.java index 881260df7..08000e671 100644 --- a/core/src/main/java/google/registry/tools/RegistryTool.java +++ b/core/src/main/java/google/registry/tools/RegistryTool.java @@ -108,6 +108,7 @@ public final class RegistryTool { .put("save_sql_credential", SaveSqlCredentialCommand.class) .put("send_escrow_report_to_icann", SendEscrowReportToIcannCommand.class) .put("set_num_instances", SetNumInstancesCommand.class) + .put("set_sql_replay_checkpoint", SetSqlReplayCheckpointCommand.class) .put("setup_ote", SetupOteCommand.class) .put("uniform_rapid_suspension", UniformRapidSuspensionCommand.class) .put("unlock_domain", UnlockDomainCommand.class) diff --git a/core/src/main/java/google/registry/tools/RegistryToolComponent.java b/core/src/main/java/google/registry/tools/RegistryToolComponent.java index 7d0f82a80..2f420bd3f 100644 --- a/core/src/main/java/google/registry/tools/RegistryToolComponent.java +++ b/core/src/main/java/google/registry/tools/RegistryToolComponent.java @@ -148,6 +148,8 @@ interface RegistryToolComponent { void inject(SetNumInstancesCommand command); + void inject(SetSqlReplayCheckpointCommand command); + void inject(SetupOteCommand command); void inject(UnlockDomainCommand command); diff --git a/core/src/main/java/google/registry/tools/SetSqlReplayCheckpointCommand.java b/core/src/main/java/google/registry/tools/SetSqlReplayCheckpointCommand.java new file mode 100644 index 000000000..06413a958 --- /dev/null +++ b/core/src/main/java/google/registry/tools/SetSqlReplayCheckpointCommand.java @@ -0,0 +1,48 @@ +// Copyright 2020 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.checkArgument; +import static google.registry.persistence.transaction.TransactionManagerFactory.jpaTm; + +import com.beust.jcommander.Parameter; +import com.beust.jcommander.Parameters; +import com.google.common.collect.Iterables; +import google.registry.schema.replay.SqlReplayCheckpoint; +import java.util.List; +import org.joda.time.DateTime; + +/** Command to set {@link SqlReplayCheckpoint} to a particular, post-initial-population time. */ +@Parameters(separators = " =", commandDescription = "Set SqlReplayCheckpoint to a particular time") +public class SetSqlReplayCheckpointCommand extends ConfirmingCommand + implements CommandWithRemoteApi { + + @Parameter(description = "Time to which SqlReplayCheckpoint will be set", required = true) + List mainParameters; + + @Override + protected String prompt() { + checkArgument(mainParameters.size() == 1, "Must provide exactly one DateTime to set"); + return String.format( + "Set SqlReplayCheckpoint to %s?", Iterables.getOnlyElement(mainParameters)); + } + + @Override + protected String execute() { + DateTime dateTime = Iterables.getOnlyElement(mainParameters); + jpaTm().transact(() -> SqlReplayCheckpoint.set(dateTime)); + return String.format("Set SqlReplayCheckpoint time to %s", dateTime); + } +} diff --git a/core/src/test/java/google/registry/tools/SetSqlReplayCheckpointCommandTest.java b/core/src/test/java/google/registry/tools/SetSqlReplayCheckpointCommandTest.java new file mode 100644 index 000000000..d02264774 --- /dev/null +++ b/core/src/test/java/google/registry/tools/SetSqlReplayCheckpointCommandTest.java @@ -0,0 +1,42 @@ +// Copyright 2020 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.truth.Truth.assertThat; +import static google.registry.persistence.transaction.TransactionManagerFactory.jpaTm; +import static google.registry.util.DateTimeUtils.START_OF_TIME; +import static org.junit.Assert.assertThrows; + +import google.registry.schema.replay.SqlReplayCheckpoint; +import org.joda.time.DateTime; +import org.junit.jupiter.api.Test; + +class SetSqlReplayCheckpointCommandTest extends CommandTestCase { + + @Test + void testSuccess() throws Exception { + assertThat(jpaTm().transact(SqlReplayCheckpoint::get)).isEqualTo(START_OF_TIME); + DateTime timeToSet = DateTime.parse("2000-06-06T22:00:00.0Z"); + runCommandForced(timeToSet.toString()); + assertThat(jpaTm().transact(SqlReplayCheckpoint::get)).isEqualTo(timeToSet); + } + + @Test + void testFailure_multipleParams() throws Exception { + DateTime one = DateTime.parse("2000-06-06T22:00:00.0Z"); + DateTime two = DateTime.parse("2001-06-06T22:00:00.0Z"); + assertThrows(IllegalArgumentException.class, () -> runCommand(one.toString(), two.toString())); + } +}