From e9610636e4819693da4cf2816a087c409073d270 Mon Sep 17 00:00:00 2001 From: gbrodman Date: Mon, 16 Mar 2020 17:44:25 -0400 Subject: [PATCH] Add a relockDuration to the RegistryLock SQL object (#514) * Add a relockDuration to the RegistryLock SQL object This is the length of time after an unlock that we will re-lock the domain in question. * Sort by domain name for stability Note: this is likely not the best solution for the UI but we can iterate on this. * Add nullable * Add a converter for Duration --- .../model/registry/RegistryLockDao.java | 6 +- .../converter/DurationConverter.java | 37 ++++++++ .../registry/schema/domain/RegistryLock.java | 15 ++++ .../main/resources/META-INF/persistence.xml | 1 + .../model/registry/RegistryLockDaoTest.java | 3 + .../converter/CurrencyUnitConverterTest.java | 1 + .../converter/DurationConverterTest.java | 80 ++++++++++++++++++ .../registrar/RegistryLockGetActionTest.java | 30 +++---- ...tTest_registryLock_nonEmpty_admin_page.png | Bin 70753 -> 70753 bytes .../sql/flyway/V20__add_relock_duration.sql | 15 ++++ .../sql/schema/db-schema.sql.generated | 1 + .../resources/sql/schema/nomulus.golden.sql | 3 +- 12 files changed, 174 insertions(+), 18 deletions(-) create mode 100644 core/src/main/java/google/registry/persistence/converter/DurationConverter.java create mode 100644 core/src/test/java/google/registry/persistence/converter/DurationConverterTest.java create mode 100644 db/src/main/resources/sql/flyway/V20__add_relock_duration.sql diff --git a/core/src/main/java/google/registry/model/registry/RegistryLockDao.java b/core/src/main/java/google/registry/model/registry/RegistryLockDao.java index 7cf61f3e8..003be5cbc 100644 --- a/core/src/main/java/google/registry/model/registry/RegistryLockDao.java +++ b/core/src/main/java/google/registry/model/registry/RegistryLockDao.java @@ -52,8 +52,10 @@ public final class RegistryLockDao { jpaTm() .getEntityManager() .createQuery( - "SELECT lock FROM RegistryLock lock WHERE lock.registrarId = :registrarId" - + " AND lock.unlockCompletionTimestamp IS NULL", + "SELECT lock FROM RegistryLock lock" + + " WHERE lock.registrarId = :registrarId" + + " AND lock.unlockCompletionTimestamp IS NULL" + + " ORDER BY lock.domainName ASC", RegistryLock.class) .setParameter("registrarId", registrarId) .getResultList()); diff --git a/core/src/main/java/google/registry/persistence/converter/DurationConverter.java b/core/src/main/java/google/registry/persistence/converter/DurationConverter.java new file mode 100644 index 000000000..8808bc371 --- /dev/null +++ b/core/src/main/java/google/registry/persistence/converter/DurationConverter.java @@ -0,0 +1,37 @@ +// 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.persistence.converter; + +import javax.annotation.Nullable; +import javax.persistence.AttributeConverter; +import javax.persistence.Converter; +import org.joda.time.Duration; + +/** JPA converter to for storing/retrieving {@link org.joda.time.DateTime} objects. */ +@Converter(autoApply = true) +public class DurationConverter implements AttributeConverter { + + @Override + @Nullable + public Long convertToDatabaseColumn(@Nullable Duration duration) { + return duration == null ? null : duration.getMillis(); + } + + @Override + @Nullable + public Duration convertToEntityAttribute(@Nullable Long dbData) { + return dbData == null ? null : new Duration(dbData); + } +} diff --git a/core/src/main/java/google/registry/schema/domain/RegistryLock.java b/core/src/main/java/google/registry/schema/domain/RegistryLock.java index 63e213e8e..f6b2ca4e2 100644 --- a/core/src/main/java/google/registry/schema/domain/RegistryLock.java +++ b/core/src/main/java/google/registry/schema/domain/RegistryLock.java @@ -26,6 +26,7 @@ import google.registry.model.UpdateAutoTimestamp; import google.registry.util.DateTimeUtils; import java.time.ZonedDateTime; import java.util.Optional; +import javax.annotation.Nullable; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; @@ -37,6 +38,7 @@ import javax.persistence.JoinColumn; import javax.persistence.OneToOne; import javax.persistence.Table; import org.joda.time.DateTime; +import org.joda.time.Duration; /** * Represents a registry lock/unlock object, meaning that the domain is locked on the registry @@ -131,6 +133,9 @@ public final class RegistryLock extends ImmutableObject implements Buildable { @JoinColumn(name = "relockRevisionId", referencedColumnName = "revisionId") private RegistryLock relock; + /** The duration after which we will re-lock this domain after it is unlocked. */ + private Duration relockDuration; + /** Time that this entity was last updated. */ private UpdateAutoTimestamp lastUpdateTimestamp; @@ -197,6 +202,11 @@ public final class RegistryLock extends ImmutableObject implements Buildable { return relock; } + /** The duration after which we will re-lock this domain after it is unlocked. */ + public Optional getRelockDuration() { + return Optional.ofNullable(relockDuration); + } + public boolean isLocked() { return lockCompletionTimestamp != null && unlockCompletionTimestamp == null; } @@ -289,5 +299,10 @@ public final class RegistryLock extends ImmutableObject implements Buildable { getInstance().relock = relock; return this; } + + public Builder setRelockDuration(@Nullable Duration relockDuration) { + getInstance().relockDuration = relockDuration; + return this; + } } } diff --git a/core/src/main/resources/META-INF/persistence.xml b/core/src/main/resources/META-INF/persistence.xml index 0fead4f17..392aef01c 100644 --- a/core/src/main/resources/META-INF/persistence.xml +++ b/core/src/main/resources/META-INF/persistence.xml @@ -38,6 +38,7 @@ google.registry.persistence.converter.CreateAutoTimestampConverter google.registry.persistence.converter.CurrencyUnitConverter google.registry.persistence.converter.DateTimeConverter + google.registry.persistence.converter.DurationConverter google.registry.persistence.converter.RegistrarPocSetConverter google.registry.persistence.converter.StatusValueSetConverter google.registry.persistence.converter.StringListConverter diff --git a/core/src/test/java/google/registry/model/registry/RegistryLockDaoTest.java b/core/src/test/java/google/registry/model/registry/RegistryLockDaoTest.java index ff5c5d766..c2a2209a5 100644 --- a/core/src/test/java/google/registry/model/registry/RegistryLockDaoTest.java +++ b/core/src/test/java/google/registry/model/registry/RegistryLockDaoTest.java @@ -30,6 +30,7 @@ import google.registry.schema.domain.RegistryLock; import google.registry.testing.AppEngineRule; import google.registry.testing.FakeClock; import java.util.Optional; +import org.joda.time.Duration; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; @@ -88,12 +89,14 @@ public final class RegistryLockDaoTest { .setLockCompletionTimestamp(fakeClock.nowUtc()) .setUnlockRequestTimestamp(fakeClock.nowUtc()) .setUnlockCompletionTimestamp(fakeClock.nowUtc()) + .setRelockDuration(Duration.standardHours(6)) .build()); RegistryLock fromDatabase = getRegistryLockByVerificationCode(lock.getVerificationCode()).get(); assertThat(fromDatabase.getUnlockRequestTimestamp()).isEqualTo(Optional.of(fakeClock.nowUtc())); assertThat(fromDatabase.getUnlockCompletionTimestamp()) .isEqualTo(Optional.of(fakeClock.nowUtc())); assertThat(fromDatabase.isLocked()).isFalse(); + assertThat(fromDatabase.getRelockDuration().get()).isEqualTo(Duration.standardHours(6)); } @Test diff --git a/core/src/test/java/google/registry/persistence/converter/CurrencyUnitConverterTest.java b/core/src/test/java/google/registry/persistence/converter/CurrencyUnitConverterTest.java index d21f08b04..64de67727 100644 --- a/core/src/test/java/google/registry/persistence/converter/CurrencyUnitConverterTest.java +++ b/core/src/test/java/google/registry/persistence/converter/CurrencyUnitConverterTest.java @@ -11,6 +11,7 @@ // 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.persistence.converter; import static com.google.common.truth.Truth.assertThat; diff --git a/core/src/test/java/google/registry/persistence/converter/DurationConverterTest.java b/core/src/test/java/google/registry/persistence/converter/DurationConverterTest.java new file mode 100644 index 000000000..c8e801bb2 --- /dev/null +++ b/core/src/test/java/google/registry/persistence/converter/DurationConverterTest.java @@ -0,0 +1,80 @@ +// 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.persistence.converter; + +import static com.google.common.truth.Truth.assertThat; +import static google.registry.persistence.transaction.TransactionManagerFactory.jpaTm; + +import google.registry.model.ImmutableObject; +import google.registry.persistence.transaction.JpaTestRules; +import google.registry.persistence.transaction.JpaTestRules.JpaUnitTestRule; +import java.math.BigInteger; +import javax.persistence.Entity; +import javax.persistence.Id; +import org.joda.time.Duration; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Unit tests for {@link DurationConverter}. */ +@RunWith(JUnit4.class) +public class DurationConverterTest { + + @Rule + public final JpaUnitTestRule jpaRule = + new JpaTestRules.Builder().withEntityClass(TestEntity.class).buildUnitTestRule(); + + private final DurationConverter converter = new DurationConverter(); + + @Test + public void testNulls() { + assertThat(converter.convertToDatabaseColumn(null)).isNull(); + assertThat(converter.convertToEntityAttribute(null)).isNull(); + } + + @Test + public void testRoundTrip() { + TestEntity entity = new TestEntity(Duration.standardDays(6)); + jpaTm().transact(() -> jpaTm().getEntityManager().persist(entity)); + assertThat( + jpaTm() + .transact( + () -> + jpaTm() + .getEntityManager() + .createNativeQuery( + "SELECT duration FROM \"TestEntity\" WHERE name = 'id'") + .getResultList())) + .containsExactly(BigInteger.valueOf(Duration.standardDays(6).getMillis())); + TestEntity persisted = + jpaTm().transact(() -> jpaTm().getEntityManager().find(TestEntity.class, "id")); + assertThat(persisted.duration).isEqualTo(Duration.standardDays(6)); + } + + @Entity(name = "TestEntity") // Override entity name to avoid the nested class reference. + public static class TestEntity extends ImmutableObject { + + @Id String name = "id"; + + Duration duration; + + public TestEntity() {} + + TestEntity(Duration duration) { + this.duration = duration; + } + } +} diff --git a/core/src/test/java/google/registry/ui/server/registrar/RegistryLockGetActionTest.java b/core/src/test/java/google/registry/ui/server/registrar/RegistryLockGetActionTest.java index b91e465a1..b177e917a 100644 --- a/core/src/test/java/google/registry/ui/server/registrar/RegistryLockGetActionTest.java +++ b/core/src/test/java/google/registry/ui/server/registrar/RegistryLockGetActionTest.java @@ -188,10 +188,10 @@ public final class RegistryLockGetActionTest { "locks", ImmutableList.of( new ImmutableMap.Builder<>() - .put("fullyQualifiedDomainName", "expiredunlock.test") - .put("lockedTime", "2000-06-08T22:00:00.000Z") - .put("lockedBy", "johndoe@theregistrar.com") - .put("userCanUnlock", true) + .put("fullyQualifiedDomainName", "adminexample.test") + .put("lockedTime", "2000-06-09T22:00:00.001Z") + .put("lockedBy", "admin") + .put("userCanUnlock", false) .put("isLockPending", false) .put("isUnlockPending", false) .build(), @@ -204,19 +204,11 @@ public final class RegistryLockGetActionTest { .put("isUnlockPending", false) .build(), new ImmutableMap.Builder<>() - .put("fullyQualifiedDomainName", "adminexample.test") - .put("lockedTime", "2000-06-09T22:00:00.001Z") - .put("lockedBy", "admin") - .put("userCanUnlock", false) - .put("isLockPending", false) - .put("isUnlockPending", false) - .build(), - new ImmutableMap.Builder<>() - .put("fullyQualifiedDomainName", "pending.test") - .put("lockedTime", "") + .put("fullyQualifiedDomainName", "expiredunlock.test") + .put("lockedTime", "2000-06-08T22:00:00.000Z") .put("lockedBy", "johndoe@theregistrar.com") .put("userCanUnlock", true) - .put("isLockPending", true) + .put("isLockPending", false) .put("isUnlockPending", false) .build(), new ImmutableMap.Builder<>() @@ -226,6 +218,14 @@ public final class RegistryLockGetActionTest { .put("userCanUnlock", true) .put("isLockPending", false) .put("isUnlockPending", true) + .build(), + new ImmutableMap.Builder<>() + .put("fullyQualifiedDomainName", "pending.test") + .put("lockedTime", "") + .put("lockedBy", "johndoe@theregistrar.com") + .put("userCanUnlock", true) + .put("isLockPending", true) + .put("isUnlockPending", false) .build())))); } diff --git a/core/src/test/resources/google/registry/webdriver/goldens/chrome-linux/RegistrarConsoleScreenshotTest_registryLock_nonEmpty_admin_page.png b/core/src/test/resources/google/registry/webdriver/goldens/chrome-linux/RegistrarConsoleScreenshotTest_registryLock_nonEmpty_admin_page.png index 6d70e570eb1a22ec5b00a9ba83a0bcf389da3683..c79aa9ab0a97726746429859d840da336a079559 100644 GIT binary patch delta 4885 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 A3;+NC delta 5055 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 diff --git a/db/src/main/resources/sql/flyway/V20__add_relock_duration.sql b/db/src/main/resources/sql/flyway/V20__add_relock_duration.sql new file mode 100644 index 000000000..f6f8e6854 --- /dev/null +++ b/db/src/main/resources/sql/flyway/V20__add_relock_duration.sql @@ -0,0 +1,15 @@ + -- 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. + +ALTER TABLE "RegistryLock" ADD COLUMN relock_duration bigint; diff --git a/db/src/main/resources/sql/schema/db-schema.sql.generated b/db/src/main/resources/sql/schema/db-schema.sql.generated index fb832fa7e..c3a12e586 100644 --- a/db/src/main/resources/sql/schema/db-schema.sql.generated +++ b/db/src/main/resources/sql/schema/db-schema.sql.generated @@ -176,6 +176,7 @@ lock_request_timestamp timestamptz not null, registrar_id text not null, registrar_poc_id text, + relock_duration int8, repo_id text not null, unlock_completion_timestamp timestamptz, unlock_request_timestamp timestamptz, diff --git a/db/src/main/resources/sql/schema/nomulus.golden.sql b/db/src/main/resources/sql/schema/nomulus.golden.sql index f8b9554b9..5186fa432 100644 --- a/db/src/main/resources/sql/schema/nomulus.golden.sql +++ b/db/src/main/resources/sql/schema/nomulus.golden.sql @@ -262,7 +262,8 @@ CREATE TABLE public."RegistryLock" ( unlock_request_timestamp timestamp with time zone, unlock_completion_timestamp timestamp with time zone, last_update_timestamp timestamp with time zone, - relock_revision_id bigint + relock_revision_id bigint, + relock_duration bigint );