mirror of
https://github.com/google/nomulus.git
synced 2025-05-22 20:29:36 +02:00
Embed a ZonedDateTime as the UpdateAutoTimestamp in SQL (#1033)
* Embed a ZonedDateTime as the UpdateAutoTimestamp in SQL This means we can get rid of the converter and more importantly, means that reading the object from SQL does not affect the last-read time (the test added to UpdateAutoTimestampTest failed prior to the production code change). For now we keep both time fields in UpdateAutoTimestamp however post-migration, we can remove the joda-time field if we wish. Note: I'm not sure why <now> is the time that we started getting LazyInitializationExceptions in the LegacyHistoryObject and ReplayExtension tests but we can solve that by just examining / initializing the object within the transaction.
This commit is contained in:
parent
2de27b5716
commit
bc4cd573b5
28 changed files with 2875 additions and 2932 deletions
|
@ -16,6 +16,8 @@ package google.registry.model;
|
||||||
|
|
||||||
import javax.persistence.Access;
|
import javax.persistence.Access;
|
||||||
import javax.persistence.AccessType;
|
import javax.persistence.AccessType;
|
||||||
|
import javax.persistence.AttributeOverride;
|
||||||
|
import javax.persistence.Column;
|
||||||
import javax.persistence.MappedSuperclass;
|
import javax.persistence.MappedSuperclass;
|
||||||
import javax.xml.bind.annotation.XmlTransient;
|
import javax.xml.bind.annotation.XmlTransient;
|
||||||
|
|
||||||
|
@ -40,6 +42,7 @@ public abstract class BackupGroupRoot extends ImmutableObject {
|
||||||
// Prevents subclasses from unexpectedly accessing as property (e.g., HostResource), which would
|
// Prevents subclasses from unexpectedly accessing as property (e.g., HostResource), which would
|
||||||
// require an unnecessary non-private setter method.
|
// require an unnecessary non-private setter method.
|
||||||
@Access(AccessType.FIELD)
|
@Access(AccessType.FIELD)
|
||||||
|
@AttributeOverride(name = "lastUpdateTime", column = @Column(name = "updateTimestamp"))
|
||||||
UpdateAutoTimestamp updateTimestamp = UpdateAutoTimestamp.create(null);
|
UpdateAutoTimestamp updateTimestamp = UpdateAutoTimestamp.create(null);
|
||||||
|
|
||||||
/** Get the {@link UpdateAutoTimestamp} for this entity. */
|
/** Get the {@link UpdateAutoTimestamp} for this entity. */
|
||||||
|
|
|
@ -14,11 +14,22 @@
|
||||||
|
|
||||||
package google.registry.model;
|
package google.registry.model;
|
||||||
|
|
||||||
|
import static google.registry.persistence.transaction.TransactionManagerFactory.jpaTm;
|
||||||
import static google.registry.util.DateTimeUtils.START_OF_TIME;
|
import static google.registry.util.DateTimeUtils.START_OF_TIME;
|
||||||
|
|
||||||
|
import com.googlecode.objectify.annotation.Ignore;
|
||||||
|
import com.googlecode.objectify.annotation.OnLoad;
|
||||||
import google.registry.model.translators.UpdateAutoTimestampTranslatorFactory;
|
import google.registry.model.translators.UpdateAutoTimestampTranslatorFactory;
|
||||||
|
import google.registry.util.DateTimeUtils;
|
||||||
|
import java.time.ZonedDateTime;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
import javax.persistence.Column;
|
||||||
|
import javax.persistence.Embeddable;
|
||||||
|
import javax.persistence.PostLoad;
|
||||||
|
import javax.persistence.PrePersist;
|
||||||
|
import javax.persistence.PreUpdate;
|
||||||
|
import javax.persistence.Transient;
|
||||||
import org.joda.time.DateTime;
|
import org.joda.time.DateTime;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -26,14 +37,44 @@ import org.joda.time.DateTime;
|
||||||
*
|
*
|
||||||
* @see UpdateAutoTimestampTranslatorFactory
|
* @see UpdateAutoTimestampTranslatorFactory
|
||||||
*/
|
*/
|
||||||
|
@Embeddable
|
||||||
public class UpdateAutoTimestamp extends ImmutableObject {
|
public class UpdateAutoTimestamp extends ImmutableObject {
|
||||||
|
|
||||||
// When set to true, database converters/translators should do tha auto update. When set to
|
// When set to true, database converters/translators should do the auto update. When set to
|
||||||
// false, auto update should be suspended (this exists to allow us to preserve the original value
|
// false, auto update should be suspended (this exists to allow us to preserve the original value
|
||||||
// during a replay).
|
// during a replay).
|
||||||
private static ThreadLocal<Boolean> autoUpdateEnabled = ThreadLocal.withInitial(() -> true);
|
private static ThreadLocal<Boolean> autoUpdateEnabled = ThreadLocal.withInitial(() -> true);
|
||||||
|
|
||||||
DateTime timestamp;
|
@Transient DateTime timestamp;
|
||||||
|
|
||||||
|
@Ignore
|
||||||
|
@Column(nullable = false)
|
||||||
|
ZonedDateTime lastUpdateTime;
|
||||||
|
|
||||||
|
// Unfortunately, we cannot use the @UpdateTimestamp annotation on "lastUpdateTime" in this class
|
||||||
|
// because Hibernate does not allow it to be used on @Embeddable classes, see
|
||||||
|
// https://hibernate.atlassian.net/browse/HHH-13235. This is a workaround.
|
||||||
|
@PrePersist
|
||||||
|
@PreUpdate
|
||||||
|
void setTimestamp() {
|
||||||
|
if (autoUpdateEnabled() || lastUpdateTime == null) {
|
||||||
|
lastUpdateTime = DateTimeUtils.toZonedDateTime(jpaTm().getTransactionTime());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@OnLoad
|
||||||
|
void onLoad() {
|
||||||
|
if (timestamp != null) {
|
||||||
|
lastUpdateTime = DateTimeUtils.toZonedDateTime(timestamp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostLoad
|
||||||
|
void postLoad() {
|
||||||
|
if (lastUpdateTime != null) {
|
||||||
|
timestamp = DateTimeUtils.toJodaDateTime(lastUpdateTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** Returns the timestamp, or {@code START_OF_TIME} if it's null. */
|
/** Returns the timestamp, or {@code START_OF_TIME} if it's null. */
|
||||||
public DateTime getTimestamp() {
|
public DateTime getTimestamp() {
|
||||||
|
@ -43,6 +84,7 @@ public class UpdateAutoTimestamp extends ImmutableObject {
|
||||||
public static UpdateAutoTimestamp create(@Nullable DateTime timestamp) {
|
public static UpdateAutoTimestamp create(@Nullable DateTime timestamp) {
|
||||||
UpdateAutoTimestamp instance = new UpdateAutoTimestamp();
|
UpdateAutoTimestamp instance = new UpdateAutoTimestamp();
|
||||||
instance.timestamp = timestamp;
|
instance.timestamp = timestamp;
|
||||||
|
instance.lastUpdateTime = timestamp == null ? null : DateTimeUtils.toZonedDateTime(timestamp);
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -51,10 +51,8 @@ public final class RegistryLockDao {
|
||||||
return ImmutableList.copyOf(
|
return ImmutableList.copyOf(
|
||||||
jpaTm()
|
jpaTm()
|
||||||
.query(
|
.query(
|
||||||
"SELECT lock FROM RegistryLock lock"
|
"SELECT lock FROM RegistryLock lock WHERE lock.registrarId = :registrarId"
|
||||||
+ " WHERE lock.registrarId = :registrarId"
|
+ " AND lock.unlockCompletionTime IS NULL ORDER BY lock.domainName ASC",
|
||||||
+ " AND lock.unlockCompletionTimestamp IS NULL"
|
|
||||||
+ " ORDER BY lock.domainName ASC",
|
|
||||||
RegistryLock.class)
|
RegistryLock.class)
|
||||||
.setParameter("registrarId", registrarId)
|
.setParameter("registrarId", registrarId)
|
||||||
.getResultList());
|
.getResultList());
|
||||||
|
@ -89,9 +87,8 @@ public final class RegistryLockDao {
|
||||||
return jpaTm()
|
return jpaTm()
|
||||||
.query(
|
.query(
|
||||||
"SELECT lock FROM RegistryLock lock WHERE lock.repoId = :repoId AND"
|
"SELECT lock FROM RegistryLock lock WHERE lock.repoId = :repoId AND"
|
||||||
+ " lock.lockCompletionTimestamp IS NOT NULL AND"
|
+ " lock.lockCompletionTime IS NOT NULL AND lock.unlockCompletionTime IS NULL"
|
||||||
+ " lock.unlockCompletionTimestamp IS NULL ORDER BY lock.revisionId"
|
+ " ORDER BY lock.revisionId DESC",
|
||||||
+ " DESC",
|
|
||||||
RegistryLock.class)
|
RegistryLock.class)
|
||||||
.setParameter("repoId", repoId)
|
.setParameter("repoId", repoId)
|
||||||
.setMaxResults(1)
|
.setMaxResults(1)
|
||||||
|
@ -110,8 +107,7 @@ public final class RegistryLockDao {
|
||||||
return jpaTm()
|
return jpaTm()
|
||||||
.query(
|
.query(
|
||||||
"SELECT lock FROM RegistryLock lock WHERE lock.repoId = :repoId AND"
|
"SELECT lock FROM RegistryLock lock WHERE lock.repoId = :repoId AND"
|
||||||
+ " lock.unlockCompletionTimestamp IS NOT NULL ORDER BY lock.revisionId"
|
+ " lock.unlockCompletionTime IS NOT NULL ORDER BY lock.revisionId DESC",
|
||||||
+ " DESC",
|
|
||||||
RegistryLock.class)
|
RegistryLock.class)
|
||||||
.setParameter("repoId", repoId)
|
.setParameter("repoId", repoId)
|
||||||
.setMaxResults(1)
|
.setMaxResults(1)
|
||||||
|
|
|
@ -1,53 +0,0 @@
|
||||||
// Copyright 2019 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 google.registry.persistence.transaction.TransactionManagerFactory.jpaTm;
|
|
||||||
|
|
||||||
import google.registry.model.UpdateAutoTimestamp;
|
|
||||||
import google.registry.util.DateTimeUtils;
|
|
||||||
import java.sql.Timestamp;
|
|
||||||
import java.time.ZoneOffset;
|
|
||||||
import java.time.ZonedDateTime;
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
import javax.persistence.AttributeConverter;
|
|
||||||
import javax.persistence.Converter;
|
|
||||||
|
|
||||||
/** JPA converter for storing/retrieving UpdateAutoTimestamp objects. */
|
|
||||||
@Converter(autoApply = true)
|
|
||||||
public class UpdateAutoTimestampConverter
|
|
||||||
implements AttributeConverter<UpdateAutoTimestamp, Timestamp> {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Timestamp convertToDatabaseColumn(UpdateAutoTimestamp entity) {
|
|
||||||
return Timestamp.from(
|
|
||||||
DateTimeUtils.toZonedDateTime(
|
|
||||||
UpdateAutoTimestamp.autoUpdateEnabled()
|
|
||||||
|| entity == null
|
|
||||||
|| entity.getTimestamp() == null
|
|
||||||
? jpaTm().getTransactionTime()
|
|
||||||
: entity.getTimestamp())
|
|
||||||
.toInstant());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Nullable
|
|
||||||
public UpdateAutoTimestamp convertToEntityAttribute(@Nullable Timestamp columnValue) {
|
|
||||||
if (columnValue == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
ZonedDateTime zdt = ZonedDateTime.ofInstant(columnValue.toInstant(), ZoneOffset.UTC);
|
|
||||||
return UpdateAutoTimestamp.create(DateTimeUtils.toJodaDateTime(zdt));
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -102,22 +102,22 @@ public final class RegistryLock extends ImmutableObject implements Buildable, Sq
|
||||||
|
|
||||||
/** When the lock is first requested. */
|
/** When the lock is first requested. */
|
||||||
@Column(nullable = false)
|
@Column(nullable = false)
|
||||||
private CreateAutoTimestamp lockRequestTimestamp = CreateAutoTimestamp.create(null);
|
private CreateAutoTimestamp lockRequestTime = CreateAutoTimestamp.create(null);
|
||||||
|
|
||||||
/** When the unlock is first requested. */
|
/** When the unlock is first requested. */
|
||||||
private ZonedDateTime unlockRequestTimestamp;
|
private ZonedDateTime unlockRequestTime;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When the user has verified the lock. If this field is null, it means the lock has not been
|
* When the user has verified the lock. If this field is null, it means the lock has not been
|
||||||
* verified yet (and thus not been put into effect).
|
* verified yet (and thus not been put into effect).
|
||||||
*/
|
*/
|
||||||
private ZonedDateTime lockCompletionTimestamp;
|
private ZonedDateTime lockCompletionTime;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When the user has verified the unlock of this lock. If this field is null, it means the unlock
|
* When the user has verified the unlock of this lock. If this field is null, it means the unlock
|
||||||
* action has not been verified yet (and has not been put into effect).
|
* action has not been verified yet (and has not been put into effect).
|
||||||
*/
|
*/
|
||||||
private ZonedDateTime unlockCompletionTimestamp;
|
private ZonedDateTime unlockCompletionTime;
|
||||||
|
|
||||||
/** The user must provide the random verification code in order to complete the action. */
|
/** The user must provide the random verification code in order to complete the action. */
|
||||||
@Column(nullable = false)
|
@Column(nullable = false)
|
||||||
|
@ -140,7 +140,7 @@ public final class RegistryLock extends ImmutableObject implements Buildable, Sq
|
||||||
private Duration relockDuration;
|
private Duration relockDuration;
|
||||||
|
|
||||||
/** Time that this entity was last updated. */
|
/** Time that this entity was last updated. */
|
||||||
private UpdateAutoTimestamp lastUpdateTimestamp;
|
private UpdateAutoTimestamp lastUpdateTime = UpdateAutoTimestamp.create(null);
|
||||||
|
|
||||||
public String getRepoId() {
|
public String getRepoId() {
|
||||||
return repoId;
|
return repoId;
|
||||||
|
@ -158,25 +158,25 @@ public final class RegistryLock extends ImmutableObject implements Buildable, Sq
|
||||||
return registrarPocId;
|
return registrarPocId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DateTime getLockRequestTimestamp() {
|
public DateTime getLockRequestTime() {
|
||||||
return lockRequestTimestamp.getTimestamp();
|
return lockRequestTime.getTimestamp();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns the unlock request timestamp or null if an unlock has not been requested yet. */
|
/** Returns the unlock request timestamp or null if an unlock has not been requested yet. */
|
||||||
public Optional<DateTime> getUnlockRequestTimestamp() {
|
public Optional<DateTime> getUnlockRequestTime() {
|
||||||
return Optional.ofNullable(unlockRequestTimestamp).map(DateTimeUtils::toJodaDateTime);
|
return Optional.ofNullable(unlockRequestTime).map(DateTimeUtils::toJodaDateTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns the completion timestamp, or empty if this lock has not been completed yet. */
|
/** Returns the completion timestamp, or empty if this lock has not been completed yet. */
|
||||||
public Optional<DateTime> getLockCompletionTimestamp() {
|
public Optional<DateTime> getLockCompletionTime() {
|
||||||
return Optional.ofNullable(lockCompletionTimestamp).map(DateTimeUtils::toJodaDateTime);
|
return Optional.ofNullable(lockCompletionTime).map(DateTimeUtils::toJodaDateTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the unlock completion timestamp, or empty if this unlock has not been completed yet.
|
* Returns the unlock completion timestamp, or empty if this unlock has not been completed yet.
|
||||||
*/
|
*/
|
||||||
public Optional<DateTime> getUnlockCompletionTimestamp() {
|
public Optional<DateTime> getUnlockCompletionTime() {
|
||||||
return Optional.ofNullable(unlockCompletionTimestamp).map(DateTimeUtils::toJodaDateTime);
|
return Optional.ofNullable(unlockCompletionTime).map(DateTimeUtils::toJodaDateTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getVerificationCode() {
|
public String getVerificationCode() {
|
||||||
|
@ -187,8 +187,8 @@ public final class RegistryLock extends ImmutableObject implements Buildable, Sq
|
||||||
return isSuperuser;
|
return isSuperuser;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DateTime getLastUpdateTimestamp() {
|
public DateTime getLastUpdateTime() {
|
||||||
return lastUpdateTimestamp.getTimestamp();
|
return lastUpdateTime.getTimestamp();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Long getRevisionId() {
|
public Long getRevisionId() {
|
||||||
|
@ -211,20 +211,20 @@ public final class RegistryLock extends ImmutableObject implements Buildable, Sq
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isLocked() {
|
public boolean isLocked() {
|
||||||
return lockCompletionTimestamp != null && unlockCompletionTimestamp == null;
|
return lockCompletionTime != null && unlockCompletionTime == null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns true iff the lock was requested >= 1 hour ago and has not been verified. */
|
/** Returns true iff the lock was requested >= 1 hour ago and has not been verified. */
|
||||||
public boolean isLockRequestExpired(DateTime now) {
|
public boolean isLockRequestExpired(DateTime now) {
|
||||||
return !getLockCompletionTimestamp().isPresent()
|
return !getLockCompletionTime().isPresent()
|
||||||
&& isBeforeOrAt(getLockRequestTimestamp(), now.minusHours(1));
|
&& isBeforeOrAt(getLockRequestTime(), now.minusHours(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns true iff the unlock was requested >= 1 hour ago and has not been verified. */
|
/** Returns true iff the unlock was requested >= 1 hour ago and has not been verified. */
|
||||||
public boolean isUnlockRequestExpired(DateTime now) {
|
public boolean isUnlockRequestExpired(DateTime now) {
|
||||||
Optional<DateTime> unlockRequestTimestamp = getUnlockRequestTimestamp();
|
Optional<DateTime> unlockRequestTimestamp = getUnlockRequestTime();
|
||||||
return unlockRequestTimestamp.isPresent()
|
return unlockRequestTimestamp.isPresent()
|
||||||
&& !getUnlockCompletionTimestamp().isPresent()
|
&& !getUnlockCompletionTime().isPresent()
|
||||||
&& isBeforeOrAt(unlockRequestTimestamp.get(), now.minusHours(1));
|
&& isBeforeOrAt(unlockRequestTimestamp.get(), now.minusHours(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -278,18 +278,18 @@ public final class RegistryLock extends ImmutableObject implements Buildable, Sq
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder setUnlockRequestTimestamp(DateTime unlockRequestTimestamp) {
|
public Builder setUnlockRequestTime(DateTime unlockRequestTime) {
|
||||||
getInstance().unlockRequestTimestamp = toZonedDateTime(unlockRequestTimestamp);
|
getInstance().unlockRequestTime = toZonedDateTime(unlockRequestTime);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder setLockCompletionTimestamp(DateTime lockCompletionTimestamp) {
|
public Builder setLockCompletionTime(DateTime lockCompletionTime) {
|
||||||
getInstance().lockCompletionTimestamp = toZonedDateTime(lockCompletionTimestamp);
|
getInstance().lockCompletionTime = toZonedDateTime(lockCompletionTime);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder setUnlockCompletionTimestamp(DateTime unlockCompletionTimestamp) {
|
public Builder setUnlockCompletionTime(DateTime unlockCompletionTime) {
|
||||||
getInstance().unlockCompletionTimestamp = toZonedDateTime(unlockCompletionTimestamp);
|
getInstance().unlockCompletionTime = toZonedDateTime(unlockCompletionTime);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -103,7 +103,7 @@ public final class DomainLockUtils {
|
||||||
RegistryLock lock = getByVerificationCode(verificationCode);
|
RegistryLock lock = getByVerificationCode(verificationCode);
|
||||||
|
|
||||||
checkArgument(
|
checkArgument(
|
||||||
!lock.getLockCompletionTimestamp().isPresent(),
|
!lock.getLockCompletionTime().isPresent(),
|
||||||
"Domain %s is already locked",
|
"Domain %s is already locked",
|
||||||
lock.getDomainName());
|
lock.getDomainName());
|
||||||
|
|
||||||
|
@ -115,7 +115,7 @@ public final class DomainLockUtils {
|
||||||
!lock.isSuperuser() || isAdmin, "Non-admin user cannot complete admin lock");
|
!lock.isSuperuser() || isAdmin, "Non-admin user cannot complete admin lock");
|
||||||
|
|
||||||
RegistryLock newLock =
|
RegistryLock newLock =
|
||||||
RegistryLockDao.save(lock.asBuilder().setLockCompletionTimestamp(now).build());
|
RegistryLockDao.save(lock.asBuilder().setLockCompletionTime(now).build());
|
||||||
setAsRelock(newLock);
|
setAsRelock(newLock);
|
||||||
tm().transact(() -> applyLockStatuses(newLock, now, isAdmin));
|
tm().transact(() -> applyLockStatuses(newLock, now, isAdmin));
|
||||||
return newLock;
|
return newLock;
|
||||||
|
@ -131,7 +131,7 @@ public final class DomainLockUtils {
|
||||||
DateTime now = jpaTm().getTransactionTime();
|
DateTime now = jpaTm().getTransactionTime();
|
||||||
RegistryLock previousLock = getByVerificationCode(verificationCode);
|
RegistryLock previousLock = getByVerificationCode(verificationCode);
|
||||||
checkArgument(
|
checkArgument(
|
||||||
!previousLock.getUnlockCompletionTimestamp().isPresent(),
|
!previousLock.getUnlockCompletionTime().isPresent(),
|
||||||
"Domain %s is already unlocked",
|
"Domain %s is already unlocked",
|
||||||
previousLock.getDomainName());
|
previousLock.getDomainName());
|
||||||
|
|
||||||
|
@ -145,7 +145,7 @@ public final class DomainLockUtils {
|
||||||
|
|
||||||
RegistryLock newLock =
|
RegistryLock newLock =
|
||||||
RegistryLockDao.save(
|
RegistryLockDao.save(
|
||||||
previousLock.asBuilder().setUnlockCompletionTimestamp(now).build());
|
previousLock.asBuilder().setUnlockCompletionTime(now).build());
|
||||||
tm().transact(() -> removeLockStatuses(newLock, isAdmin, now));
|
tm().transact(() -> removeLockStatuses(newLock, isAdmin, now));
|
||||||
return newLock;
|
return newLock;
|
||||||
});
|
});
|
||||||
|
@ -169,7 +169,7 @@ public final class DomainLockUtils {
|
||||||
RegistryLock newLock =
|
RegistryLock newLock =
|
||||||
RegistryLockDao.save(
|
RegistryLockDao.save(
|
||||||
createLockBuilder(domainName, registrarId, registrarPocId, isAdmin)
|
createLockBuilder(domainName, registrarId, registrarPocId, isAdmin)
|
||||||
.setLockCompletionTimestamp(now)
|
.setLockCompletionTime(now)
|
||||||
.build());
|
.build());
|
||||||
tm().transact(() -> applyLockStatuses(newLock, now, isAdmin));
|
tm().transact(() -> applyLockStatuses(newLock, now, isAdmin));
|
||||||
setAsRelock(newLock);
|
setAsRelock(newLock);
|
||||||
|
@ -192,7 +192,7 @@ public final class DomainLockUtils {
|
||||||
RegistryLock result =
|
RegistryLock result =
|
||||||
RegistryLockDao.save(
|
RegistryLockDao.save(
|
||||||
createUnlockBuilder(domainName, registrarId, isAdmin, relockDuration)
|
createUnlockBuilder(domainName, registrarId, isAdmin, relockDuration)
|
||||||
.setUnlockCompletionTimestamp(now)
|
.setUnlockCompletionTime(now)
|
||||||
.build());
|
.build());
|
||||||
tm().transact(() -> removeLockStatuses(result, isAdmin, now));
|
tm().transact(() -> removeLockStatuses(result, isAdmin, now));
|
||||||
return result;
|
return result;
|
||||||
|
@ -230,7 +230,7 @@ public final class DomainLockUtils {
|
||||||
previousLock ->
|
previousLock ->
|
||||||
checkArgument(
|
checkArgument(
|
||||||
previousLock.isLockRequestExpired(now)
|
previousLock.isLockRequestExpired(now)
|
||||||
|| previousLock.getUnlockCompletionTimestamp().isPresent()
|
|| previousLock.getUnlockCompletionTime().isPresent()
|
||||||
|| isAdmin,
|
|| isAdmin,
|
||||||
"A pending or completed lock action already exists for %s",
|
"A pending or completed lock action already exists for %s",
|
||||||
previousLock.getDomainName()));
|
previousLock.getDomainName()));
|
||||||
|
@ -264,7 +264,7 @@ public final class DomainLockUtils {
|
||||||
new RegistryLock.Builder()
|
new RegistryLock.Builder()
|
||||||
.setRepoId(domainBase.getRepoId())
|
.setRepoId(domainBase.getRepoId())
|
||||||
.setDomainName(domainName)
|
.setDomainName(domainName)
|
||||||
.setLockCompletionTimestamp(now)
|
.setLockCompletionTime(now)
|
||||||
.setRegistrarId(registrarId));
|
.setRegistrarId(registrarId));
|
||||||
} else {
|
} else {
|
||||||
RegistryLock lock =
|
RegistryLock lock =
|
||||||
|
@ -275,7 +275,7 @@ public final class DomainLockUtils {
|
||||||
checkArgument(
|
checkArgument(
|
||||||
lock.isLocked(), "Lock object for domain %s is not currently locked", domainName);
|
lock.isLocked(), "Lock object for domain %s is not currently locked", domainName);
|
||||||
checkArgument(
|
checkArgument(
|
||||||
!lock.getUnlockRequestTimestamp().isPresent() || lock.isUnlockRequestExpired(now),
|
!lock.getUnlockRequestTime().isPresent() || lock.isUnlockRequestExpired(now),
|
||||||
"A pending unlock action already exists for %s",
|
"A pending unlock action already exists for %s",
|
||||||
domainName);
|
domainName);
|
||||||
checkArgument(
|
checkArgument(
|
||||||
|
@ -290,7 +290,7 @@ public final class DomainLockUtils {
|
||||||
return newLockBuilder
|
return newLockBuilder
|
||||||
.setVerificationCode(stringGenerator.createString(VERIFICATION_CODE_LENGTH))
|
.setVerificationCode(stringGenerator.createString(VERIFICATION_CODE_LENGTH))
|
||||||
.isSuperuser(isAdmin)
|
.isSuperuser(isAdmin)
|
||||||
.setUnlockRequestTimestamp(now)
|
.setUnlockRequestTime(now)
|
||||||
.setRegistrarId(registrarId);
|
.setRegistrarId(registrarId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -107,7 +107,7 @@ public class BackfillRegistryLocksCommand extends ConfirmingCommand
|
||||||
.setRegistrarId(registryAdminClientId)
|
.setRegistrarId(registryAdminClientId)
|
||||||
.setRepoId(domainBase.getRepoId())
|
.setRepoId(domainBase.getRepoId())
|
||||||
.setDomainName(domainBase.getDomainName())
|
.setDomainName(domainBase.getDomainName())
|
||||||
.setLockCompletionTimestamp(
|
.setLockCompletionTime(
|
||||||
getLockCompletionTimestamp(domainBase, jpaTm().getTransactionTime()))
|
getLockCompletionTimestamp(domainBase, jpaTm().getTransactionTime()))
|
||||||
.setVerificationCode(
|
.setVerificationCode(
|
||||||
stringGenerator.createString(VERIFICATION_CODE_LENGTH))
|
stringGenerator.createString(VERIFICATION_CODE_LENGTH))
|
||||||
|
|
|
@ -191,14 +191,13 @@ public final class RegistryLockGetAction implements JsonGetAction {
|
||||||
DateTime now = jpaTm().getTransactionTime();
|
DateTime now = jpaTm().getTransactionTime();
|
||||||
return new ImmutableMap.Builder<String, Object>()
|
return new ImmutableMap.Builder<String, Object>()
|
||||||
.put(DOMAIN_NAME_PARAM, lock.getDomainName())
|
.put(DOMAIN_NAME_PARAM, lock.getDomainName())
|
||||||
.put(
|
.put(LOCKED_TIME_PARAM, lock.getLockCompletionTime().map(DateTime::toString).orElse(""))
|
||||||
LOCKED_TIME_PARAM, lock.getLockCompletionTimestamp().map(DateTime::toString).orElse(""))
|
|
||||||
.put(LOCKED_BY_PARAM, lock.isSuperuser() ? "admin" : lock.getRegistrarPocId())
|
.put(LOCKED_BY_PARAM, lock.isSuperuser() ? "admin" : lock.getRegistrarPocId())
|
||||||
.put(IS_LOCK_PENDING_PARAM, !lock.getLockCompletionTimestamp().isPresent())
|
.put(IS_LOCK_PENDING_PARAM, !lock.getLockCompletionTime().isPresent())
|
||||||
.put(
|
.put(
|
||||||
IS_UNLOCK_PENDING_PARAM,
|
IS_UNLOCK_PENDING_PARAM,
|
||||||
lock.getUnlockRequestTimestamp().isPresent()
|
lock.getUnlockRequestTime().isPresent()
|
||||||
&& !lock.getUnlockCompletionTimestamp().isPresent()
|
&& !lock.getUnlockCompletionTime().isPresent()
|
||||||
&& !lock.isUnlockRequestExpired(now))
|
&& !lock.isUnlockRequestExpired(now))
|
||||||
.put(USER_CAN_UNLOCK_PARAM, isAdmin || !lock.isSuperuser())
|
.put(USER_CAN_UNLOCK_PARAM, isAdmin || !lock.isSuperuser())
|
||||||
.build();
|
.build();
|
||||||
|
|
|
@ -98,7 +98,6 @@
|
||||||
<class>google.registry.persistence.converter.StringSetConverter</class>
|
<class>google.registry.persistence.converter.StringSetConverter</class>
|
||||||
<class>google.registry.persistence.converter.TldStateTransitionConverter</class>
|
<class>google.registry.persistence.converter.TldStateTransitionConverter</class>
|
||||||
<class>google.registry.persistence.converter.TransferServerApproveEntitySetConverter</class>
|
<class>google.registry.persistence.converter.TransferServerApproveEntitySetConverter</class>
|
||||||
<class>google.registry.persistence.converter.UpdateAutoTimestampConverter</class>
|
|
||||||
<class>google.registry.persistence.converter.ZonedDateTimeConverter</class>
|
<class>google.registry.persistence.converter.ZonedDateTimeConverter</class>
|
||||||
|
|
||||||
<!-- Generated converters for VKey -->
|
<!-- Generated converters for VKey -->
|
||||||
|
|
|
@ -148,9 +148,9 @@ public class AsyncTaskEnqueuerTest {
|
||||||
RegistryLock lock =
|
RegistryLock lock =
|
||||||
saveRegistryLock(
|
saveRegistryLock(
|
||||||
new RegistryLock.Builder()
|
new RegistryLock.Builder()
|
||||||
.setLockCompletionTimestamp(clock.nowUtc())
|
.setLockCompletionTime(clock.nowUtc())
|
||||||
.setUnlockRequestTimestamp(clock.nowUtc())
|
.setUnlockRequestTime(clock.nowUtc())
|
||||||
.setUnlockCompletionTimestamp(clock.nowUtc())
|
.setUnlockCompletionTime(clock.nowUtc())
|
||||||
.isSuperuser(false)
|
.isSuperuser(false)
|
||||||
.setDomainName("example.tld")
|
.setDomainName("example.tld")
|
||||||
.setRepoId("repoId")
|
.setRepoId("repoId")
|
||||||
|
|
|
@ -22,13 +22,16 @@ import com.googlecode.objectify.Key;
|
||||||
import com.googlecode.objectify.annotation.Entity;
|
import com.googlecode.objectify.annotation.Entity;
|
||||||
import com.googlecode.objectify.annotation.Ignore;
|
import com.googlecode.objectify.annotation.Ignore;
|
||||||
import google.registry.model.common.CrossTldSingleton;
|
import google.registry.model.common.CrossTldSingleton;
|
||||||
|
import google.registry.model.ofy.Ofy;
|
||||||
import google.registry.persistence.VKey;
|
import google.registry.persistence.VKey;
|
||||||
import google.registry.schema.replay.EntityTest.EntityForTesting;
|
import google.registry.schema.replay.EntityTest.EntityForTesting;
|
||||||
import google.registry.testing.AppEngineExtension;
|
import google.registry.testing.AppEngineExtension;
|
||||||
import google.registry.testing.DualDatabaseTest;
|
import google.registry.testing.DualDatabaseTest;
|
||||||
import google.registry.testing.FakeClock;
|
import google.registry.testing.FakeClock;
|
||||||
|
import google.registry.testing.InjectExtension;
|
||||||
import google.registry.testing.TestOfyAndSql;
|
import google.registry.testing.TestOfyAndSql;
|
||||||
import org.joda.time.DateTime;
|
import org.joda.time.DateTime;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.extension.RegisterExtension;
|
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||||
|
|
||||||
/** Unit tests for {@link UpdateAutoTimestamp}. */
|
/** Unit tests for {@link UpdateAutoTimestamp}. */
|
||||||
|
@ -46,6 +49,13 @@ public class UpdateAutoTimestampTest {
|
||||||
.withClock(clock)
|
.withClock(clock)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
@RegisterExtension public final InjectExtension inject = new InjectExtension();
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
void beforeEach() {
|
||||||
|
inject.setStaticField(Ofy.class, "clock", clock);
|
||||||
|
}
|
||||||
|
|
||||||
/** Timestamped class. */
|
/** Timestamped class. */
|
||||||
@Entity(name = "UatTestEntity")
|
@Entity(name = "UatTestEntity")
|
||||||
@javax.persistence.Entity
|
@javax.persistence.Entity
|
||||||
|
@ -70,6 +80,7 @@ public class UpdateAutoTimestampTest {
|
||||||
DateTime transactionTime =
|
DateTime transactionTime =
|
||||||
tm().transact(
|
tm().transact(
|
||||||
() -> {
|
() -> {
|
||||||
|
clock.advanceOneMilli();
|
||||||
UpdateAutoTimestampTestObject object = new UpdateAutoTimestampTestObject();
|
UpdateAutoTimestampTestObject object = new UpdateAutoTimestampTestObject();
|
||||||
assertThat(object.updateTime.timestamp).isNull();
|
assertThat(object.updateTime.timestamp).isNull();
|
||||||
tm().insert(object);
|
tm().insert(object);
|
||||||
|
@ -84,6 +95,7 @@ public class UpdateAutoTimestampTest {
|
||||||
DateTime initialTime =
|
DateTime initialTime =
|
||||||
tm().transact(
|
tm().transact(
|
||||||
() -> {
|
() -> {
|
||||||
|
clock.advanceOneMilli();
|
||||||
tm().insert(new UpdateAutoTimestampTestObject());
|
tm().insert(new UpdateAutoTimestampTestObject());
|
||||||
return tm().getTransactionTime();
|
return tm().getTransactionTime();
|
||||||
});
|
});
|
||||||
|
@ -109,6 +121,7 @@ public class UpdateAutoTimestampTest {
|
||||||
DateTime transactionTime =
|
DateTime transactionTime =
|
||||||
tm().transact(
|
tm().transact(
|
||||||
() -> {
|
() -> {
|
||||||
|
clock.advanceOneMilli();
|
||||||
UpdateAutoTimestampTestObject object = new UpdateAutoTimestampTestObject();
|
UpdateAutoTimestampTestObject object = new UpdateAutoTimestampTestObject();
|
||||||
object.updateTime = UpdateAutoTimestamp.create(DateTime.now(UTC).minusDays(1));
|
object.updateTime = UpdateAutoTimestamp.create(DateTime.now(UTC).minusDays(1));
|
||||||
tm().insert(object);
|
tm().insert(object);
|
||||||
|
@ -117,4 +130,17 @@ public class UpdateAutoTimestampTest {
|
||||||
tm().clearSessionCache();
|
tm().clearSessionCache();
|
||||||
assertThat(reload().updateTime.timestamp).isEqualTo(transactionTime);
|
assertThat(reload().updateTime.timestamp).isEqualTo(transactionTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestOfyAndSql
|
||||||
|
void testReadingTwiceDoesNotModify() {
|
||||||
|
DateTime originalTime = DateTime.parse("1999-01-01T00:00:00Z");
|
||||||
|
clock.setTo(originalTime);
|
||||||
|
tm().transact(() -> tm().insert(new UpdateAutoTimestampTestObject()));
|
||||||
|
clock.advanceOneMilli();
|
||||||
|
UpdateAutoTimestampTestObject firstRead = reload();
|
||||||
|
assertThat(firstRead.updateTime.getTimestamp()).isEqualTo(originalTime);
|
||||||
|
clock.advanceOneMilli();
|
||||||
|
UpdateAutoTimestampTestObject secondRead = reload();
|
||||||
|
assertThat(secondRead.updateTime.getTimestamp()).isEqualTo(originalTime);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -129,8 +129,11 @@ public class LegacyHistoryObjectTest extends EntityTestCase {
|
||||||
|
|
||||||
// Next, save that from-Datastore object in SQL and verify we can load it back in
|
// Next, save that from-Datastore object in SQL and verify we can load it back in
|
||||||
jpaTm().transact(() -> jpaTm().insert(legacyDomainHistory));
|
jpaTm().transact(() -> jpaTm().insert(legacyDomainHistory));
|
||||||
|
jpaTm()
|
||||||
|
.transact(
|
||||||
|
() -> {
|
||||||
DomainHistory legacyHistoryFromSql =
|
DomainHistory legacyHistoryFromSql =
|
||||||
jpaTm().transact(() -> jpaTm().loadByKey(legacyDomainHistory.createVKey()));
|
jpaTm().loadByKey(legacyDomainHistory.createVKey());
|
||||||
// Don't compare nsHosts directly because one is null and the other is empty
|
// Don't compare nsHosts directly because one is null and the other is empty
|
||||||
assertAboutImmutableObjects()
|
assertAboutImmutableObjects()
|
||||||
.that(legacyDomainHistory)
|
.that(legacyDomainHistory)
|
||||||
|
@ -145,6 +148,7 @@ public class LegacyHistoryObjectTest extends EntityTestCase {
|
||||||
"gracePeriodHistories");
|
"gracePeriodHistories");
|
||||||
assertThat(nullToEmpty(legacyDomainHistory.getNsHosts()))
|
assertThat(nullToEmpty(legacyDomainHistory.getNsHosts()))
|
||||||
.isEqualTo(nullToEmpty(legacyHistoryFromSql.getNsHosts()));
|
.isEqualTo(nullToEmpty(legacyHistoryFromSql.getNsHosts()));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestSqlOnly
|
@TestSqlOnly
|
||||||
|
|
|
@ -46,7 +46,7 @@ public final class RegistryLockDaoTest extends EntityTestCase {
|
||||||
RegistryLock fromDatabase = getRegistryLockByVerificationCode(lock.getVerificationCode()).get();
|
RegistryLock fromDatabase = getRegistryLockByVerificationCode(lock.getVerificationCode()).get();
|
||||||
assertThat(fromDatabase.getDomainName()).isEqualTo(lock.getDomainName());
|
assertThat(fromDatabase.getDomainName()).isEqualTo(lock.getDomainName());
|
||||||
assertThat(fromDatabase.getVerificationCode()).isEqualTo(lock.getVerificationCode());
|
assertThat(fromDatabase.getVerificationCode()).isEqualTo(lock.getVerificationCode());
|
||||||
assertThat(fromDatabase.getLastUpdateTimestamp()).isEqualTo(fakeClock.nowUtc());
|
assertThat(fromDatabase.getLastUpdateTime()).isEqualTo(fakeClock.nowUtc());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -60,16 +60,15 @@ public final class RegistryLockDaoTest extends EntityTestCase {
|
||||||
RegistryLock updatedLock =
|
RegistryLock updatedLock =
|
||||||
RegistryLockDao.getByVerificationCode(lock.getVerificationCode()).get();
|
RegistryLockDao.getByVerificationCode(lock.getVerificationCode()).get();
|
||||||
RegistryLockDao.save(
|
RegistryLockDao.save(
|
||||||
updatedLock.asBuilder().setLockCompletionTimestamp(fakeClock.nowUtc()).build());
|
updatedLock.asBuilder().setLockCompletionTime(fakeClock.nowUtc()).build());
|
||||||
});
|
});
|
||||||
jpaTm()
|
jpaTm()
|
||||||
.transact(
|
.transact(
|
||||||
() -> {
|
() -> {
|
||||||
RegistryLock fromDatabase =
|
RegistryLock fromDatabase =
|
||||||
RegistryLockDao.getByVerificationCode(lock.getVerificationCode()).get();
|
RegistryLockDao.getByVerificationCode(lock.getVerificationCode()).get();
|
||||||
assertThat(fromDatabase.getLockCompletionTimestamp().get())
|
assertThat(fromDatabase.getLockCompletionTime().get()).isEqualTo(fakeClock.nowUtc());
|
||||||
.isEqualTo(fakeClock.nowUtc());
|
assertThat(fromDatabase.getLastUpdateTime()).isEqualTo(fakeClock.nowUtc());
|
||||||
assertThat(fromDatabase.getLastUpdateTimestamp()).isEqualTo(fakeClock.nowUtc());
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,15 +78,14 @@ public final class RegistryLockDaoTest extends EntityTestCase {
|
||||||
saveRegistryLock(
|
saveRegistryLock(
|
||||||
createLock()
|
createLock()
|
||||||
.asBuilder()
|
.asBuilder()
|
||||||
.setLockCompletionTimestamp(fakeClock.nowUtc())
|
.setLockCompletionTime(fakeClock.nowUtc())
|
||||||
.setUnlockRequestTimestamp(fakeClock.nowUtc())
|
.setUnlockRequestTime(fakeClock.nowUtc())
|
||||||
.setUnlockCompletionTimestamp(fakeClock.nowUtc())
|
.setUnlockCompletionTime(fakeClock.nowUtc())
|
||||||
.setRelockDuration(Duration.standardHours(6))
|
.setRelockDuration(Duration.standardHours(6))
|
||||||
.build());
|
.build());
|
||||||
RegistryLock fromDatabase = getRegistryLockByVerificationCode(lock.getVerificationCode()).get();
|
RegistryLock fromDatabase = getRegistryLockByVerificationCode(lock.getVerificationCode()).get();
|
||||||
assertThat(fromDatabase.getUnlockRequestTimestamp()).isEqualTo(Optional.of(fakeClock.nowUtc()));
|
assertThat(fromDatabase.getUnlockRequestTime()).isEqualTo(Optional.of(fakeClock.nowUtc()));
|
||||||
assertThat(fromDatabase.getUnlockCompletionTimestamp())
|
assertThat(fromDatabase.getUnlockCompletionTime()).isEqualTo(Optional.of(fakeClock.nowUtc()));
|
||||||
.isEqualTo(Optional.of(fakeClock.nowUtc()));
|
|
||||||
assertThat(fromDatabase.isLocked()).isFalse();
|
assertThat(fromDatabase.isLocked()).isFalse();
|
||||||
assertThat(fromDatabase.getRelockDuration().get()).isEqualTo(Duration.standardHours(6));
|
assertThat(fromDatabase.getRelockDuration().get()).isEqualTo(Duration.standardHours(6));
|
||||||
}
|
}
|
||||||
|
@ -96,15 +94,14 @@ public final class RegistryLockDaoTest extends EntityTestCase {
|
||||||
void testUpdateLock_usingSamePrimaryKey() {
|
void testUpdateLock_usingSamePrimaryKey() {
|
||||||
RegistryLock lock = saveRegistryLock(createLock());
|
RegistryLock lock = saveRegistryLock(createLock());
|
||||||
fakeClock.advanceOneMilli();
|
fakeClock.advanceOneMilli();
|
||||||
RegistryLock updatedLock =
|
RegistryLock updatedLock = lock.asBuilder().setLockCompletionTime(fakeClock.nowUtc()).build();
|
||||||
lock.asBuilder().setLockCompletionTimestamp(fakeClock.nowUtc()).build();
|
|
||||||
saveRegistryLock(updatedLock);
|
saveRegistryLock(updatedLock);
|
||||||
jpaTm()
|
jpaTm()
|
||||||
.transact(
|
.transact(
|
||||||
() -> {
|
() -> {
|
||||||
RegistryLock fromDatabase =
|
RegistryLock fromDatabase =
|
||||||
RegistryLockDao.getByVerificationCode(lock.getVerificationCode()).get();
|
RegistryLockDao.getByVerificationCode(lock.getVerificationCode()).get();
|
||||||
assertThat(fromDatabase.getLockCompletionTimestamp())
|
assertThat(fromDatabase.getLockCompletionTime())
|
||||||
.isEqualTo(Optional.of(fakeClock.nowUtc()));
|
.isEqualTo(Optional.of(fakeClock.nowUtc()));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -140,15 +137,15 @@ public final class RegistryLockDaoTest extends EntityTestCase {
|
||||||
createLock()
|
createLock()
|
||||||
.asBuilder()
|
.asBuilder()
|
||||||
.setDomainName("otherexample.test")
|
.setDomainName("otherexample.test")
|
||||||
.setLockCompletionTimestamp(fakeClock.nowUtc())
|
.setLockCompletionTime(fakeClock.nowUtc())
|
||||||
.build();
|
.build();
|
||||||
RegistryLock unlockedLock =
|
RegistryLock unlockedLock =
|
||||||
createLock()
|
createLock()
|
||||||
.asBuilder()
|
.asBuilder()
|
||||||
.setDomainName("unlocked.test")
|
.setDomainName("unlocked.test")
|
||||||
.setLockCompletionTimestamp(fakeClock.nowUtc())
|
.setLockCompletionTime(fakeClock.nowUtc())
|
||||||
.setUnlockRequestTimestamp(fakeClock.nowUtc())
|
.setUnlockRequestTime(fakeClock.nowUtc())
|
||||||
.setUnlockCompletionTimestamp(fakeClock.nowUtc())
|
.setUnlockCompletionTime(fakeClock.nowUtc())
|
||||||
.build();
|
.build();
|
||||||
saveRegistryLock(lock);
|
saveRegistryLock(lock);
|
||||||
saveRegistryLock(secondLock);
|
saveRegistryLock(secondLock);
|
||||||
|
@ -165,7 +162,7 @@ public final class RegistryLockDaoTest extends EntityTestCase {
|
||||||
@Test
|
@Test
|
||||||
void testLoad_byRepoId() {
|
void testLoad_byRepoId() {
|
||||||
RegistryLock completedLock =
|
RegistryLock completedLock =
|
||||||
createLock().asBuilder().setLockCompletionTimestamp(fakeClock.nowUtc()).build();
|
createLock().asBuilder().setLockCompletionTime(fakeClock.nowUtc()).build();
|
||||||
saveRegistryLock(completedLock);
|
saveRegistryLock(completedLock);
|
||||||
|
|
||||||
fakeClock.advanceOneMilli();
|
fakeClock.advanceOneMilli();
|
||||||
|
@ -185,7 +182,7 @@ public final class RegistryLockDaoTest extends EntityTestCase {
|
||||||
@Test
|
@Test
|
||||||
void testLoad_verified_byRepoId() {
|
void testLoad_verified_byRepoId() {
|
||||||
RegistryLock completedLock =
|
RegistryLock completedLock =
|
||||||
createLock().asBuilder().setLockCompletionTimestamp(fakeClock.nowUtc()).build();
|
createLock().asBuilder().setLockCompletionTime(fakeClock.nowUtc()).build();
|
||||||
saveRegistryLock(completedLock);
|
saveRegistryLock(completedLock);
|
||||||
|
|
||||||
fakeClock.advanceOneMilli();
|
fakeClock.advanceOneMilli();
|
||||||
|
@ -210,9 +207,9 @@ public final class RegistryLockDaoTest extends EntityTestCase {
|
||||||
saveRegistryLock(
|
saveRegistryLock(
|
||||||
createLock()
|
createLock()
|
||||||
.asBuilder()
|
.asBuilder()
|
||||||
.setLockCompletionTimestamp(fakeClock.nowUtc())
|
.setLockCompletionTime(fakeClock.nowUtc())
|
||||||
.setUnlockRequestTimestamp(fakeClock.nowUtc())
|
.setUnlockRequestTime(fakeClock.nowUtc())
|
||||||
.setUnlockCompletionTimestamp(fakeClock.nowUtc())
|
.setUnlockCompletionTime(fakeClock.nowUtc())
|
||||||
.build());
|
.build());
|
||||||
|
|
||||||
Optional<RegistryLock> mostRecent = getMostRecentUnlockedRegistryLockByRepoId(lock.getRepoId());
|
Optional<RegistryLock> mostRecent = getMostRecentUnlockedRegistryLockByRepoId(lock.getRepoId());
|
||||||
|
@ -222,7 +219,7 @@ public final class RegistryLockDaoTest extends EntityTestCase {
|
||||||
@Test
|
@Test
|
||||||
void testLoad_verifiedUnlock_empty() {
|
void testLoad_verifiedUnlock_empty() {
|
||||||
RegistryLock completedLock =
|
RegistryLock completedLock =
|
||||||
createLock().asBuilder().setLockCompletionTimestamp(fakeClock.nowUtc()).build();
|
createLock().asBuilder().setLockCompletionTime(fakeClock.nowUtc()).build();
|
||||||
saveRegistryLock(completedLock);
|
saveRegistryLock(completedLock);
|
||||||
assertThat(getMostRecentUnlockedRegistryLockByRepoId(completedLock.getRepoId()).isPresent())
|
assertThat(getMostRecentUnlockedRegistryLockByRepoId(completedLock.getRepoId()).isPresent())
|
||||||
.isFalse();
|
.isFalse();
|
||||||
|
|
|
@ -142,6 +142,7 @@ class EntityCallbacksListenerTest {
|
||||||
assertThat(testEntity.entityEmbedded.entityEmbeddedParentPostLoad).isEqualTo(expectedLoad);
|
assertThat(testEntity.entityEmbedded.entityEmbeddedParentPostLoad).isEqualTo(expectedLoad);
|
||||||
|
|
||||||
assertThat(testEntity.parentPostLoad).isEqualTo(expectedLoad);
|
assertThat(testEntity.parentPostLoad).isEqualTo(expectedLoad);
|
||||||
|
assertThat(testEntity.parentPrePersist).isEqualTo(expectedPersist);
|
||||||
assertThat(testEntity.parentEmbedded.parentEmbeddedPostLoad).isEqualTo(expectedLoad);
|
assertThat(testEntity.parentEmbedded.parentEmbeddedPostLoad).isEqualTo(expectedLoad);
|
||||||
assertThat(testEntity.parentEmbedded.parentEmbeddedNested.parentEmbeddedNestedPostLoad)
|
assertThat(testEntity.parentEmbedded.parentEmbeddedNested.parentEmbeddedNestedPostLoad)
|
||||||
.isEqualTo(expectedLoad);
|
.isEqualTo(expectedLoad);
|
||||||
|
@ -241,6 +242,7 @@ class EntityCallbacksListenerTest {
|
||||||
private static class ParentEntity {
|
private static class ParentEntity {
|
||||||
@Embedded ParentEmbedded parentEmbedded = new ParentEmbedded();
|
@Embedded ParentEmbedded parentEmbedded = new ParentEmbedded();
|
||||||
@Transient int parentPostLoad = 0;
|
@Transient int parentPostLoad = 0;
|
||||||
|
@Transient int parentPrePersist = 0;
|
||||||
|
|
||||||
String parentEntity = "placeholder";
|
String parentEntity = "placeholder";
|
||||||
|
|
||||||
|
@ -248,6 +250,11 @@ class EntityCallbacksListenerTest {
|
||||||
void parentPostLoad() {
|
void parentPostLoad() {
|
||||||
parentPostLoad++;
|
parentPostLoad++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PrePersist
|
||||||
|
void parentPrePersist() {
|
||||||
|
parentPrePersist++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Embeddable
|
@Embeddable
|
||||||
|
|
|
@ -1,92 +0,0 @@
|
||||||
// Copyright 2019 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.model.UpdateAutoTimestamp;
|
|
||||||
import google.registry.persistence.transaction.JpaTestRules;
|
|
||||||
import google.registry.persistence.transaction.JpaTestRules.JpaUnitTestExtension;
|
|
||||||
import google.registry.schema.replay.EntityTest.EntityForTesting;
|
|
||||||
import google.registry.testing.FakeClock;
|
|
||||||
import javax.persistence.Entity;
|
|
||||||
import javax.persistence.Id;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.junit.jupiter.api.extension.RegisterExtension;
|
|
||||||
|
|
||||||
/** Unit tests for {@link UpdateAutoTimestampConverter}. */
|
|
||||||
public class UpdateAutoTimestampConverterTest {
|
|
||||||
|
|
||||||
private final FakeClock fakeClock = new FakeClock();
|
|
||||||
|
|
||||||
@RegisterExtension
|
|
||||||
public final JpaUnitTestExtension jpaExtension =
|
|
||||||
new JpaTestRules.Builder()
|
|
||||||
.withClock(fakeClock)
|
|
||||||
.withEntityClass(TestEntity.class)
|
|
||||||
.buildUnitTestRule();
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testTypeConversion() {
|
|
||||||
TestEntity ent = new TestEntity("myinst", null);
|
|
||||||
|
|
||||||
jpaTm().transact(() -> jpaTm().insert(ent));
|
|
||||||
|
|
||||||
TestEntity result =
|
|
||||||
jpaTm().transact(() -> jpaTm().getEntityManager().find(TestEntity.class, "myinst"));
|
|
||||||
|
|
||||||
assertThat(result.name).isEqualTo("myinst");
|
|
||||||
assertThat(result.uat.getTimestamp()).isEqualTo(fakeClock.nowUtc());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testTimeChangesOnSubsequentTransactions() {
|
|
||||||
TestEntity ent1 = new TestEntity("myinst1", null);
|
|
||||||
|
|
||||||
jpaTm().transact(() -> jpaTm().insert(ent1));
|
|
||||||
|
|
||||||
TestEntity result1 =
|
|
||||||
jpaTm().transact(() -> jpaTm().getEntityManager().find(TestEntity.class, "myinst1"));
|
|
||||||
|
|
||||||
fakeClock.advanceOneMilli();
|
|
||||||
|
|
||||||
TestEntity ent2 = new TestEntity("myinst2", result1.uat);
|
|
||||||
|
|
||||||
jpaTm().transact(() -> jpaTm().insert(ent2));
|
|
||||||
|
|
||||||
TestEntity result2 =
|
|
||||||
jpaTm().transact(() -> jpaTm().getEntityManager().find(TestEntity.class, "myinst2"));
|
|
||||||
|
|
||||||
assertThat(result1.uat.getTimestamp()).isNotEqualTo(result2.uat.getTimestamp());
|
|
||||||
assertThat(result2.uat.getTimestamp()).isEqualTo(fakeClock.nowUtc());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Entity(name = "TestEntity") // Override entity name to avoid the nested class reference.
|
|
||||||
@EntityForTesting
|
|
||||||
public static class TestEntity extends ImmutableObject {
|
|
||||||
|
|
||||||
@Id String name;
|
|
||||||
|
|
||||||
UpdateAutoTimestamp uat;
|
|
||||||
|
|
||||||
public TestEntity() {}
|
|
||||||
|
|
||||||
TestEntity(String name, UpdateAutoTimestamp uat) {
|
|
||||||
this.name = name;
|
|
||||||
this.uat = uat;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -110,7 +110,10 @@ public class ReplayExtension implements BeforeEachCallback, AfterEachCallback {
|
||||||
// have to compare the current value in SQL (which we just mutated) against the value that
|
// have to compare the current value in SQL (which we just mutated) against the value that
|
||||||
// we originally would have persisted (that being the object in the entry).
|
// we originally would have persisted (that being the object in the entry).
|
||||||
VKey<?> vkey = VKey.from(entry.getKey());
|
VKey<?> vkey = VKey.from(entry.getKey());
|
||||||
Optional<?> jpaValue = jpaTm().transact(() -> jpaTm().loadByKeyIfPresent(vkey));
|
jpaTm()
|
||||||
|
.transact(
|
||||||
|
() -> {
|
||||||
|
Optional<?> jpaValue = jpaTm().loadByKeyIfPresent(vkey);
|
||||||
if (entry.getValue().equals(TransactionInfo.Delete.SENTINEL)) {
|
if (entry.getValue().equals(TransactionInfo.Delete.SENTINEL)) {
|
||||||
assertThat(jpaValue.isPresent()).isFalse();
|
assertThat(jpaValue.isPresent()).isFalse();
|
||||||
} else {
|
} else {
|
||||||
|
@ -119,8 +122,10 @@ public class ReplayExtension implements BeforeEachCallback, AfterEachCallback {
|
||||||
assertAboutImmutableObjects()
|
assertAboutImmutableObjects()
|
||||||
.that(immutJpaObject)
|
.that(immutJpaObject)
|
||||||
.isEqualAcrossDatabases(
|
.isEqualAcrossDatabases(
|
||||||
(ImmutableObject) ((DatastoreEntity) entry.getValue()).toSqlEntity().get());
|
(ImmutableObject)
|
||||||
|
((DatastoreEntity) entry.getValue()).toSqlEntity().get());
|
||||||
}
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -104,7 +104,7 @@ public final class DomainLockUtilsTest {
|
||||||
RegistryLock lock =
|
RegistryLock lock =
|
||||||
domainLockUtils.saveNewRegistryLockRequest(DOMAIN_NAME, "TheRegistrar", POC_ID, false);
|
domainLockUtils.saveNewRegistryLockRequest(DOMAIN_NAME, "TheRegistrar", POC_ID, false);
|
||||||
assertNoDomainChanges();
|
assertNoDomainChanges();
|
||||||
assertThat(lock.getLockCompletionTimestamp().isPresent()).isFalse();
|
assertThat(lock.getLockCompletionTime().isPresent()).isFalse();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -113,7 +113,7 @@ public final class DomainLockUtilsTest {
|
||||||
RegistryLock lock =
|
RegistryLock lock =
|
||||||
domainLockUtils.saveNewRegistryUnlockRequest(
|
domainLockUtils.saveNewRegistryUnlockRequest(
|
||||||
DOMAIN_NAME, "TheRegistrar", false, Optional.empty());
|
DOMAIN_NAME, "TheRegistrar", false, Optional.empty());
|
||||||
assertThat(lock.getUnlockCompletionTimestamp().isPresent()).isFalse();
|
assertThat(lock.getUnlockCompletionTime().isPresent()).isFalse();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -122,7 +122,7 @@ public final class DomainLockUtilsTest {
|
||||||
RegistryLock lock =
|
RegistryLock lock =
|
||||||
domainLockUtils.saveNewRegistryUnlockRequest(
|
domainLockUtils.saveNewRegistryUnlockRequest(
|
||||||
DOMAIN_NAME, "TheRegistrar", true, Optional.empty());
|
DOMAIN_NAME, "TheRegistrar", true, Optional.empty());
|
||||||
assertThat(lock.getUnlockCompletionTimestamp().isPresent()).isFalse();
|
assertThat(lock.getUnlockCompletionTime().isPresent()).isFalse();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -285,7 +285,7 @@ public final class DomainLockUtilsTest {
|
||||||
RegistryLock resultLock =
|
RegistryLock resultLock =
|
||||||
domainLockUtils.administrativelyApplyLock(DOMAIN_NAME, "TheRegistrar", POC_ID, true);
|
domainLockUtils.administrativelyApplyLock(DOMAIN_NAME, "TheRegistrar", POC_ID, true);
|
||||||
verifyProperlyLockedDomain(true);
|
verifyProperlyLockedDomain(true);
|
||||||
assertThat(resultLock.getLockCompletionTimestamp()).isEqualTo(Optional.of(clock.nowUtc()));
|
assertThat(resultLock.getLockCompletionTime()).isEqualTo(Optional.of(clock.nowUtc()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -294,7 +294,7 @@ public final class DomainLockUtilsTest {
|
||||||
// what the RegistryLock table says
|
// what the RegistryLock table says
|
||||||
SqlHelper.saveRegistryLock(
|
SqlHelper.saveRegistryLock(
|
||||||
new RegistryLock.Builder()
|
new RegistryLock.Builder()
|
||||||
.setLockCompletionTimestamp(clock.nowUtc())
|
.setLockCompletionTime(clock.nowUtc())
|
||||||
.setDomainName(DOMAIN_NAME)
|
.setDomainName(DOMAIN_NAME)
|
||||||
.setVerificationCode("hi")
|
.setVerificationCode("hi")
|
||||||
.setRegistrarId("TheRegistrar")
|
.setRegistrarId("TheRegistrar")
|
||||||
|
@ -306,7 +306,7 @@ public final class DomainLockUtilsTest {
|
||||||
RegistryLock resultLock =
|
RegistryLock resultLock =
|
||||||
domainLockUtils.administrativelyApplyLock(DOMAIN_NAME, "TheRegistrar", POC_ID, true);
|
domainLockUtils.administrativelyApplyLock(DOMAIN_NAME, "TheRegistrar", POC_ID, true);
|
||||||
verifyProperlyLockedDomain(true);
|
verifyProperlyLockedDomain(true);
|
||||||
assertThat(resultLock.getLockCompletionTimestamp()).isEqualTo(Optional.of(clock.nowUtc()));
|
assertThat(resultLock.getLockCompletionTime()).isEqualTo(Optional.of(clock.nowUtc()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -68,7 +68,7 @@ class BackfillRegistryLocksCommandTest extends CommandTestCase<BackfillRegistryL
|
||||||
|
|
||||||
Optional<RegistryLock> lockOptional = getMostRecentRegistryLockByRepoId(domain.getRepoId());
|
Optional<RegistryLock> lockOptional = getMostRecentRegistryLockByRepoId(domain.getRepoId());
|
||||||
Truth8.assertThat(lockOptional).isPresent();
|
Truth8.assertThat(lockOptional).isPresent();
|
||||||
Truth8.assertThat(lockOptional.get().getLockCompletionTimestamp()).isPresent();
|
Truth8.assertThat(lockOptional.get().getLockCompletionTime()).isPresent();
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestOfyAndSql
|
@TestOfyAndSql
|
||||||
|
@ -111,18 +111,15 @@ class BackfillRegistryLocksCommandTest extends CommandTestCase<BackfillRegistryL
|
||||||
.setRegistrarId("adminreg")
|
.setRegistrarId("adminreg")
|
||||||
.setRepoId(domain.getRepoId())
|
.setRepoId(domain.getRepoId())
|
||||||
.setDomainName(domain.getDomainName())
|
.setDomainName(domain.getDomainName())
|
||||||
.setLockCompletionTimestamp(fakeClock.nowUtc())
|
.setLockCompletionTime(fakeClock.nowUtc())
|
||||||
.setVerificationCode(command.stringGenerator.createString(32))
|
.setVerificationCode(command.stringGenerator.createString(32))
|
||||||
.build());
|
.build());
|
||||||
|
|
||||||
fakeClock.advanceBy(Duration.standardDays(1));
|
fakeClock.advanceBy(Duration.standardDays(1));
|
||||||
runCommandForced("--domain_roids", domain.getRepoId());
|
runCommandForced("--domain_roids", domain.getRepoId());
|
||||||
|
|
||||||
assertThat(
|
assertThat(getMostRecentRegistryLockByRepoId(domain.getRepoId()).get().getLockCompletionTime())
|
||||||
getMostRecentRegistryLockByRepoId(domain.getRepoId())
|
.isEqualTo(previousLock.getLockCompletionTime());
|
||||||
.get()
|
|
||||||
.getLockCompletionTimestamp())
|
|
||||||
.isEqualTo(previousLock.getLockCompletionTimestamp());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestOfyAndSql
|
@TestOfyAndSql
|
||||||
|
@ -147,10 +144,10 @@ class BackfillRegistryLocksCommandTest extends CommandTestCase<BackfillRegistryL
|
||||||
"--domain_roids", String.format("%s,%s", ursDomain.getRepoId(), nonUrsDomain.getRepoId()));
|
"--domain_roids", String.format("%s,%s", ursDomain.getRepoId(), nonUrsDomain.getRepoId()));
|
||||||
|
|
||||||
RegistryLock ursLock = getMostRecentVerifiedRegistryLockByRepoId(ursDomain.getRepoId()).get();
|
RegistryLock ursLock = getMostRecentVerifiedRegistryLockByRepoId(ursDomain.getRepoId()).get();
|
||||||
assertThat(ursLock.getLockCompletionTimestamp()).hasValue(ursTime);
|
assertThat(ursLock.getLockCompletionTime()).hasValue(ursTime);
|
||||||
RegistryLock nonUrsLock =
|
RegistryLock nonUrsLock =
|
||||||
getMostRecentVerifiedRegistryLockByRepoId(nonUrsDomain.getRepoId()).get();
|
getMostRecentVerifiedRegistryLockByRepoId(nonUrsDomain.getRepoId()).get();
|
||||||
assertThat(nonUrsLock.getLockCompletionTimestamp()).hasValue(fakeClock.nowUtc());
|
assertThat(nonUrsLock.getLockCompletionTime()).hasValue(fakeClock.nowUtc());
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestOfyAndSql
|
@TestOfyAndSql
|
||||||
|
|
|
@ -101,8 +101,8 @@ final class RegistryLockGetActionTest {
|
||||||
.setRegistrarId("TheRegistrar")
|
.setRegistrarId("TheRegistrar")
|
||||||
.setVerificationCode("123456789ABCDEFGHJKLMNPQRSTUVWXY")
|
.setVerificationCode("123456789ABCDEFGHJKLMNPQRSTUVWXY")
|
||||||
.setRegistrarPocId("johndoe@theregistrar.com")
|
.setRegistrarPocId("johndoe@theregistrar.com")
|
||||||
.setLockCompletionTimestamp(fakeClock.nowUtc())
|
.setLockCompletionTime(fakeClock.nowUtc())
|
||||||
.setUnlockRequestTimestamp(fakeClock.nowUtc())
|
.setUnlockRequestTime(fakeClock.nowUtc())
|
||||||
.build();
|
.build();
|
||||||
saveRegistryLock(expiredUnlock);
|
saveRegistryLock(expiredUnlock);
|
||||||
fakeClock.advanceBy(Duration.standardDays(1));
|
fakeClock.advanceBy(Duration.standardDays(1));
|
||||||
|
@ -114,7 +114,7 @@ final class RegistryLockGetActionTest {
|
||||||
.setRegistrarId("TheRegistrar")
|
.setRegistrarId("TheRegistrar")
|
||||||
.setVerificationCode("123456789ABCDEFGHJKLMNPQRSTUVWXY")
|
.setVerificationCode("123456789ABCDEFGHJKLMNPQRSTUVWXY")
|
||||||
.setRegistrarPocId("johndoe@theregistrar.com")
|
.setRegistrarPocId("johndoe@theregistrar.com")
|
||||||
.setLockCompletionTimestamp(fakeClock.nowUtc())
|
.setLockCompletionTime(fakeClock.nowUtc())
|
||||||
.build();
|
.build();
|
||||||
fakeClock.advanceOneMilli();
|
fakeClock.advanceOneMilli();
|
||||||
RegistryLock adminLock =
|
RegistryLock adminLock =
|
||||||
|
@ -124,7 +124,7 @@ final class RegistryLockGetActionTest {
|
||||||
.setRegistrarId("TheRegistrar")
|
.setRegistrarId("TheRegistrar")
|
||||||
.setVerificationCode("122222222ABCDEFGHJKLMNPQRSTUVWXY")
|
.setVerificationCode("122222222ABCDEFGHJKLMNPQRSTUVWXY")
|
||||||
.isSuperuser(true)
|
.isSuperuser(true)
|
||||||
.setLockCompletionTimestamp(fakeClock.nowUtc())
|
.setLockCompletionTime(fakeClock.nowUtc())
|
||||||
.build();
|
.build();
|
||||||
RegistryLock incompleteLock =
|
RegistryLock incompleteLock =
|
||||||
new RegistryLock.Builder()
|
new RegistryLock.Builder()
|
||||||
|
@ -142,8 +142,8 @@ final class RegistryLockGetActionTest {
|
||||||
.setRegistrarId("TheRegistrar")
|
.setRegistrarId("TheRegistrar")
|
||||||
.setVerificationCode("123456789ABCDEFGHJKLMNPQRSTUVWXY")
|
.setVerificationCode("123456789ABCDEFGHJKLMNPQRSTUVWXY")
|
||||||
.setRegistrarPocId("johndoe@theregistrar.com")
|
.setRegistrarPocId("johndoe@theregistrar.com")
|
||||||
.setLockCompletionTimestamp(fakeClock.nowUtc())
|
.setLockCompletionTime(fakeClock.nowUtc())
|
||||||
.setUnlockRequestTimestamp(fakeClock.nowUtc())
|
.setUnlockRequestTime(fakeClock.nowUtc())
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
RegistryLock unlockedLock =
|
RegistryLock unlockedLock =
|
||||||
|
@ -153,9 +153,9 @@ final class RegistryLockGetActionTest {
|
||||||
.setRegistrarId("TheRegistrar")
|
.setRegistrarId("TheRegistrar")
|
||||||
.setRegistrarPocId("johndoe@theregistrar.com")
|
.setRegistrarPocId("johndoe@theregistrar.com")
|
||||||
.setVerificationCode("123456789ABCDEFGHJKLMNPQRSTUUUUU")
|
.setVerificationCode("123456789ABCDEFGHJKLMNPQRSTUUUUU")
|
||||||
.setLockCompletionTimestamp(fakeClock.nowUtc())
|
.setLockCompletionTime(fakeClock.nowUtc())
|
||||||
.setUnlockRequestTimestamp(fakeClock.nowUtc())
|
.setUnlockRequestTime(fakeClock.nowUtc())
|
||||||
.setUnlockCompletionTimestamp(fakeClock.nowUtc())
|
.setUnlockCompletionTime(fakeClock.nowUtc())
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
saveRegistryLock(regularLock);
|
saveRegistryLock(regularLock);
|
||||||
|
|
|
@ -123,7 +123,7 @@ final class RegistryLockPostActionTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testSuccess_unlock() throws Exception {
|
void testSuccess_unlock() throws Exception {
|
||||||
saveRegistryLock(createLock().asBuilder().setLockCompletionTimestamp(clock.nowUtc()).build());
|
saveRegistryLock(createLock().asBuilder().setLockCompletionTime(clock.nowUtc()).build());
|
||||||
persistResource(domain.asBuilder().setStatusValues(REGISTRY_LOCK_STATUSES).build());
|
persistResource(domain.asBuilder().setStatusValues(REGISTRY_LOCK_STATUSES).build());
|
||||||
Map<String, ?> response = action.handleJsonRequest(unlockRequest());
|
Map<String, ?> response = action.handleJsonRequest(unlockRequest());
|
||||||
assertSuccess(response, "unlock", "Marla.Singer.RegistryLock@crr.com");
|
assertSuccess(response, "unlock", "Marla.Singer.RegistryLock@crr.com");
|
||||||
|
@ -131,7 +131,7 @@ final class RegistryLockPostActionTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testSuccess_unlock_relockDurationSet() throws Exception {
|
void testSuccess_unlock_relockDurationSet() throws Exception {
|
||||||
saveRegistryLock(createLock().asBuilder().setLockCompletionTimestamp(clock.nowUtc()).build());
|
saveRegistryLock(createLock().asBuilder().setLockCompletionTime(clock.nowUtc()).build());
|
||||||
persistResource(domain.asBuilder().setStatusValues(REGISTRY_LOCK_STATUSES).build());
|
persistResource(domain.asBuilder().setStatusValues(REGISTRY_LOCK_STATUSES).build());
|
||||||
ImmutableMap<String, Object> request =
|
ImmutableMap<String, Object> request =
|
||||||
new ImmutableMap.Builder<String, Object>()
|
new ImmutableMap.Builder<String, Object>()
|
||||||
|
@ -148,11 +148,7 @@ final class RegistryLockPostActionTest {
|
||||||
@Test
|
@Test
|
||||||
void testSuccess_unlock_adminUnlockingAdmin() throws Exception {
|
void testSuccess_unlock_adminUnlockingAdmin() throws Exception {
|
||||||
saveRegistryLock(
|
saveRegistryLock(
|
||||||
createLock()
|
createLock().asBuilder().isSuperuser(true).setLockCompletionTime(clock.nowUtc()).build());
|
||||||
.asBuilder()
|
|
||||||
.isSuperuser(true)
|
|
||||||
.setLockCompletionTimestamp(clock.nowUtc())
|
|
||||||
.build());
|
|
||||||
persistResource(domain.asBuilder().setStatusValues(REGISTRY_LOCK_STATUSES).build());
|
persistResource(domain.asBuilder().setStatusValues(REGISTRY_LOCK_STATUSES).build());
|
||||||
action =
|
action =
|
||||||
createAction(
|
createAction(
|
||||||
|
@ -187,8 +183,8 @@ final class RegistryLockPostActionTest {
|
||||||
saveRegistryLock(
|
saveRegistryLock(
|
||||||
createLock()
|
createLock()
|
||||||
.asBuilder()
|
.asBuilder()
|
||||||
.setLockCompletionTimestamp(clock.nowUtc())
|
.setLockCompletionTime(clock.nowUtc())
|
||||||
.setUnlockRequestTimestamp(clock.nowUtc())
|
.setUnlockRequestTime(clock.nowUtc())
|
||||||
.build());
|
.build());
|
||||||
Map<String, ?> response = action.handleJsonRequest(unlockRequest());
|
Map<String, ?> response = action.handleJsonRequest(unlockRequest());
|
||||||
assertFailureWithMessage(response, "A pending unlock action already exists for example.tld");
|
assertFailureWithMessage(response, "A pending unlock action already exists for example.tld");
|
||||||
|
@ -197,11 +193,7 @@ final class RegistryLockPostActionTest {
|
||||||
@Test
|
@Test
|
||||||
void testFailure_unlock_nonAdminUnlockingAdmin() {
|
void testFailure_unlock_nonAdminUnlockingAdmin() {
|
||||||
saveRegistryLock(
|
saveRegistryLock(
|
||||||
createLock()
|
createLock().asBuilder().isSuperuser(true).setLockCompletionTime(clock.nowUtc()).build());
|
||||||
.asBuilder()
|
|
||||||
.isSuperuser(true)
|
|
||||||
.setLockCompletionTimestamp(clock.nowUtc())
|
|
||||||
.build());
|
|
||||||
persistResource(domain.asBuilder().setStatusValues(REGISTRY_LOCK_STATUSES).build());
|
persistResource(domain.asBuilder().setStatusValues(REGISTRY_LOCK_STATUSES).build());
|
||||||
Map<String, ?> response = action.handleJsonRequest(unlockRequest());
|
Map<String, ?> response = action.handleJsonRequest(unlockRequest());
|
||||||
assertFailureWithMessage(
|
assertFailureWithMessage(
|
||||||
|
@ -366,9 +358,9 @@ final class RegistryLockPostActionTest {
|
||||||
saveRegistryLock(
|
saveRegistryLock(
|
||||||
createLock()
|
createLock()
|
||||||
.asBuilder()
|
.asBuilder()
|
||||||
.setLockCompletionTimestamp(clock.nowUtc().minusMinutes(1))
|
.setLockCompletionTime(clock.nowUtc().minusMinutes(1))
|
||||||
.setUnlockRequestTimestamp(clock.nowUtc().minusMinutes(1))
|
.setUnlockRequestTime(clock.nowUtc().minusMinutes(1))
|
||||||
.setUnlockCompletionTimestamp(clock.nowUtc().minusMinutes(1))
|
.setUnlockCompletionTime(clock.nowUtc().minusMinutes(1))
|
||||||
.build());
|
.build());
|
||||||
|
|
||||||
Map<String, ?> response = action.handleJsonRequest(lockRequest());
|
Map<String, ?> response = action.handleJsonRequest(lockRequest());
|
||||||
|
@ -380,7 +372,7 @@ final class RegistryLockPostActionTest {
|
||||||
RegistryLock previousLock = saveRegistryLock(createLock());
|
RegistryLock previousLock = saveRegistryLock(createLock());
|
||||||
String verificationCode = previousLock.getVerificationCode();
|
String verificationCode = previousLock.getVerificationCode();
|
||||||
previousLock = getRegistryLockByVerificationCode(verificationCode).get();
|
previousLock = getRegistryLockByVerificationCode(verificationCode).get();
|
||||||
clock.setTo(previousLock.getLockRequestTimestamp().plusHours(2));
|
clock.setTo(previousLock.getLockRequestTime().plusHours(2));
|
||||||
Map<String, ?> response = action.handleJsonRequest(lockRequest());
|
Map<String, ?> response = action.handleJsonRequest(lockRequest());
|
||||||
assertSuccess(response, "lock", "Marla.Singer.RegistryLock@crr.com");
|
assertSuccess(response, "lock", "Marla.Singer.RegistryLock@crr.com");
|
||||||
}
|
}
|
||||||
|
|
|
@ -114,8 +114,7 @@ final class RegistryLockVerifyActionTest {
|
||||||
void testSuccess_unlockDomain() {
|
void testSuccess_unlockDomain() {
|
||||||
action = createAction(lockId, false);
|
action = createAction(lockId, false);
|
||||||
domain = persistResource(domain.asBuilder().setStatusValues(REGISTRY_LOCK_STATUSES).build());
|
domain = persistResource(domain.asBuilder().setStatusValues(REGISTRY_LOCK_STATUSES).build());
|
||||||
saveRegistryLock(
|
saveRegistryLock(createLock().asBuilder().setUnlockRequestTime(fakeClock.nowUtc()).build());
|
||||||
createLock().asBuilder().setUnlockRequestTimestamp(fakeClock.nowUtc()).build());
|
|
||||||
action.run();
|
action.run();
|
||||||
assertThat(response.getStatus()).isEqualTo(SC_OK);
|
assertThat(response.getStatus()).isEqualTo(SC_OK);
|
||||||
assertThat(response.getPayload()).contains("Success: unlock has been applied to example.tld");
|
assertThat(response.getPayload()).contains("Success: unlock has been applied to example.tld");
|
||||||
|
@ -151,8 +150,7 @@ final class RegistryLockVerifyActionTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testFailure_alreadyVerified() {
|
void testFailure_alreadyVerified() {
|
||||||
saveRegistryLock(
|
saveRegistryLock(createLock().asBuilder().setLockCompletionTime(fakeClock.nowUtc()).build());
|
||||||
createLock().asBuilder().setLockCompletionTimestamp(fakeClock.nowUtc()).build());
|
|
||||||
action.run();
|
action.run();
|
||||||
assertThat(response.getPayload()).contains("Failed: Domain example.tld is already locked");
|
assertThat(response.getPayload()).contains("Failed: Domain example.tld is already locked");
|
||||||
assertNoDomainChanges();
|
assertNoDomainChanges();
|
||||||
|
@ -182,9 +180,9 @@ final class RegistryLockVerifyActionTest {
|
||||||
saveRegistryLock(
|
saveRegistryLock(
|
||||||
createLock()
|
createLock()
|
||||||
.asBuilder()
|
.asBuilder()
|
||||||
.setLockCompletionTimestamp(fakeClock.nowUtc())
|
.setLockCompletionTime(fakeClock.nowUtc())
|
||||||
.setUnlockRequestTimestamp(fakeClock.nowUtc())
|
.setUnlockRequestTime(fakeClock.nowUtc())
|
||||||
.setUnlockCompletionTimestamp(fakeClock.nowUtc())
|
.setUnlockCompletionTime(fakeClock.nowUtc())
|
||||||
.build());
|
.build());
|
||||||
action.run();
|
action.run();
|
||||||
assertThat(response.getPayload()).contains("Failed: Domain example.tld is already unlocked");
|
assertThat(response.getPayload()).contains("Failed: Domain example.tld is already unlocked");
|
||||||
|
@ -234,8 +232,8 @@ final class RegistryLockVerifyActionTest {
|
||||||
saveRegistryLock(
|
saveRegistryLock(
|
||||||
createLock()
|
createLock()
|
||||||
.asBuilder()
|
.asBuilder()
|
||||||
.setLockCompletionTimestamp(fakeClock.nowUtc())
|
.setLockCompletionTime(fakeClock.nowUtc())
|
||||||
.setUnlockRequestTimestamp(fakeClock.nowUtc())
|
.setUnlockRequestTime(fakeClock.nowUtc())
|
||||||
.build());
|
.build());
|
||||||
action.run();
|
action.run();
|
||||||
assertThat(response.getPayload()).contains("Failed: Domain example.tld is already locked");
|
assertThat(response.getPayload()).contains("Failed: Domain example.tld is already locked");
|
||||||
|
@ -258,7 +256,7 @@ final class RegistryLockVerifyActionTest {
|
||||||
saveRegistryLock(
|
saveRegistryLock(
|
||||||
lock.asBuilder()
|
lock.asBuilder()
|
||||||
.setVerificationCode(unlockVerificationCode)
|
.setVerificationCode(unlockVerificationCode)
|
||||||
.setUnlockRequestTimestamp(fakeClock.nowUtc())
|
.setUnlockRequestTime(fakeClock.nowUtc())
|
||||||
.build());
|
.build());
|
||||||
action = createAction(unlockVerificationCode, false);
|
action = createAction(unlockVerificationCode, false);
|
||||||
action.run();
|
action.run();
|
||||||
|
@ -282,8 +280,7 @@ final class RegistryLockVerifyActionTest {
|
||||||
void testFailure_unlock_unlockAgain() {
|
void testFailure_unlock_unlockAgain() {
|
||||||
action = createAction(lockId, false);
|
action = createAction(lockId, false);
|
||||||
domain = persistResource(domain.asBuilder().setStatusValues(REGISTRY_LOCK_STATUSES).build());
|
domain = persistResource(domain.asBuilder().setStatusValues(REGISTRY_LOCK_STATUSES).build());
|
||||||
saveRegistryLock(
|
saveRegistryLock(createLock().asBuilder().setUnlockRequestTime(fakeClock.nowUtc()).build());
|
||||||
createLock().asBuilder().setUnlockRequestTimestamp(fakeClock.nowUtc()).build());
|
|
||||||
action.run();
|
action.run();
|
||||||
assertThat(response.getStatus()).isEqualTo(SC_OK);
|
assertThat(response.getStatus()).isEqualTo(SC_OK);
|
||||||
assertThat(response.getPayload()).contains("Success: unlock has been applied to example.tld");
|
assertThat(response.getPayload()).contains("Success: unlock has been applied to example.tld");
|
||||||
|
|
|
@ -465,8 +465,8 @@ class RegistrarConsoleScreenshotTest extends WebDriverTestCase {
|
||||||
saveRegistryLock(
|
saveRegistryLock(
|
||||||
createRegistryLock(expiredUnlockRequestDomain)
|
createRegistryLock(expiredUnlockRequestDomain)
|
||||||
.asBuilder()
|
.asBuilder()
|
||||||
.setLockCompletionTimestamp(START_OF_TIME.minusDays(1))
|
.setLockCompletionTime(START_OF_TIME.minusDays(1))
|
||||||
.setUnlockRequestTimestamp(START_OF_TIME.minusDays(1))
|
.setUnlockRequestTime(START_OF_TIME.minusDays(1))
|
||||||
.build());
|
.build());
|
||||||
DomainBase domain = persistActiveDomain("example.tld");
|
DomainBase domain = persistActiveDomain("example.tld");
|
||||||
saveRegistryLock(createRegistryLock(domain).asBuilder().isSuperuser(true).build());
|
saveRegistryLock(createRegistryLock(domain).asBuilder().isSuperuser(true).build());
|
||||||
|
@ -498,8 +498,8 @@ class RegistrarConsoleScreenshotTest extends WebDriverTestCase {
|
||||||
.setRegistrarPocId("Marla.Singer@crr.com")
|
.setRegistrarPocId("Marla.Singer@crr.com")
|
||||||
.setDomainName(pendingUnlockDomain.getDomainName())
|
.setDomainName(pendingUnlockDomain.getDomainName())
|
||||||
.setRepoId(pendingUnlockDomain.getRepoId())
|
.setRepoId(pendingUnlockDomain.getRepoId())
|
||||||
.setLockCompletionTimestamp(START_OF_TIME)
|
.setLockCompletionTime(START_OF_TIME)
|
||||||
.setUnlockRequestTimestamp(START_OF_TIME)
|
.setUnlockRequestTime(START_OF_TIME)
|
||||||
.build());
|
.build());
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
|
@ -568,7 +568,7 @@ class RegistrarConsoleScreenshotTest extends WebDriverTestCase {
|
||||||
.isSuperuser(false)
|
.isSuperuser(false)
|
||||||
.setRegistrarId("TheRegistrar")
|
.setRegistrarId("TheRegistrar")
|
||||||
.setRegistrarPocId("Marla.Singer@crr.com")
|
.setRegistrarPocId("Marla.Singer@crr.com")
|
||||||
.setLockCompletionTimestamp(START_OF_TIME)
|
.setLockCompletionTime(START_OF_TIME)
|
||||||
.setDomainName(domainBase.getDomainName())
|
.setDomainName(domainBase.getDomainName())
|
||||||
.setRepoId(domainBase.getRepoId())
|
.setRepoId(domainBase.getRepoId())
|
||||||
.build();
|
.build();
|
||||||
|
|
|
@ -261,11 +261,11 @@ td.section {
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td class="property_name">generated on</td>
|
<td class="property_name">generated on</td>
|
||||||
<td class="property_value">2021-03-19 12:31:33.396532</td>
|
<td class="property_value">2021-03-24 01:27:00.824998</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td class="property_name">last flyway file</td>
|
<td class="property_name">last flyway file</td>
|
||||||
<td id="lastFlywayFile" class="property_value">V89__host_history_host_deferred.sql</td>
|
<td id="lastFlywayFile" class="property_value">V90__update_timestamp.sql</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
@ -284,7 +284,7 @@ td.section {
|
||||||
generated on
|
generated on
|
||||||
</text>
|
</text>
|
||||||
<text text-anchor="start" x="4027.94" y="-10.8" font-family="Helvetica,sans-Serif" font-size="14.00">
|
<text text-anchor="start" x="4027.94" y="-10.8" font-family="Helvetica,sans-Serif" font-size="14.00">
|
||||||
2021-03-19 12:31:33.396532
|
2021-03-24 01:27:00.824998
|
||||||
</text>
|
</text>
|
||||||
<polygon fill="none" stroke="#888888" points="3940.44,-4 3940.44,-44 4205.44,-44 4205.44,-4 3940.44,-4" /> <!-- allocationtoken_a08ccbef -->
|
<polygon fill="none" stroke="#888888" points="3940.44,-4 3940.44,-44 4205.44,-44 4205.44,-4 3940.44,-4" /> <!-- allocationtoken_a08ccbef -->
|
||||||
<g id="node1" class="node">
|
<g id="node1" class="node">
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -87,3 +87,4 @@ V86__third_poll_message.sql
|
||||||
V87__fix_super_domain_fk.sql
|
V87__fix_super_domain_fk.sql
|
||||||
V88__transfer_billing_cancellation_history_id.sql
|
V88__transfer_billing_cancellation_history_id.sql
|
||||||
V89__host_history_host_deferred.sql
|
V89__host_history_host_deferred.sql
|
||||||
|
V90__update_timestamp.sql
|
||||||
|
|
23
db/src/main/resources/sql/flyway/V90__update_timestamp.sql
Normal file
23
db/src/main/resources/sql/flyway/V90__update_timestamp.sql
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
-- Copyright 2021 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 "Registrar" ALTER COLUMN "last_update_time" SET NOT NULL;
|
||||||
|
ALTER TABLE "RegistryLock" RENAME "last_update_timestamp" TO "last_update_time";
|
||||||
|
ALTER TABLE "RegistryLock" ALTER COLUMN "last_update_time" SET NOT NULL;
|
||||||
|
|
||||||
|
-- While we're at it, rename some registry-lock fields to follow the same naming pattern
|
||||||
|
ALTER TABLE "RegistryLock" RENAME "lock_completion_timestamp" TO "lock_completion_time";
|
||||||
|
ALTER TABLE "RegistryLock" RENAME "lock_request_timestamp" TO "lock_request_time";
|
||||||
|
ALTER TABLE "RegistryLock" RENAME "unlock_completion_timestamp" TO "unlock_completion_time";
|
||||||
|
ALTER TABLE "RegistryLock" RENAME "unlock_request_timestamp" TO "unlock_request_time";
|
|
@ -589,7 +589,7 @@
|
||||||
i18n_address_zip text,
|
i18n_address_zip text,
|
||||||
ip_address_allow_list text[],
|
ip_address_allow_list text[],
|
||||||
last_certificate_update_time timestamptz,
|
last_certificate_update_time timestamptz,
|
||||||
last_update_time timestamptz,
|
last_update_time timestamptz not null,
|
||||||
localized_address_city text,
|
localized_address_city text,
|
||||||
localized_address_country_code text,
|
localized_address_country_code text,
|
||||||
localized_address_state text,
|
localized_address_state text,
|
||||||
|
@ -634,15 +634,15 @@
|
||||||
revision_id bigserial not null,
|
revision_id bigserial not null,
|
||||||
domain_name text not null,
|
domain_name text not null,
|
||||||
is_superuser boolean not null,
|
is_superuser boolean not null,
|
||||||
last_update_timestamp timestamptz,
|
last_update_time timestamptz not null,
|
||||||
lock_completion_timestamp timestamptz,
|
lock_completion_time timestamptz,
|
||||||
lock_request_timestamp timestamptz not null,
|
lock_request_time timestamptz not null,
|
||||||
registrar_id text not null,
|
registrar_id text not null,
|
||||||
registrar_poc_id text,
|
registrar_poc_id text,
|
||||||
relock_duration interval,
|
relock_duration interval,
|
||||||
repo_id text not null,
|
repo_id text not null,
|
||||||
unlock_completion_timestamp timestamptz,
|
unlock_completion_time timestamptz,
|
||||||
unlock_request_timestamp timestamptz,
|
unlock_request_time timestamptz,
|
||||||
verification_code text not null,
|
verification_code text not null,
|
||||||
relock_revision_id int8,
|
relock_revision_id int8,
|
||||||
primary key (revision_id)
|
primary key (revision_id)
|
||||||
|
|
|
@ -780,7 +780,7 @@ CREATE TABLE public."Registrar" (
|
||||||
i18n_address_zip text,
|
i18n_address_zip text,
|
||||||
ip_address_allow_list text[],
|
ip_address_allow_list text[],
|
||||||
last_certificate_update_time timestamp with time zone,
|
last_certificate_update_time timestamp with time zone,
|
||||||
last_update_time timestamp with time zone,
|
last_update_time timestamp with time zone NOT NULL,
|
||||||
localized_address_city text,
|
localized_address_city text,
|
||||||
localized_address_country_code text,
|
localized_address_country_code text,
|
||||||
localized_address_state text,
|
localized_address_state text,
|
||||||
|
@ -831,17 +831,17 @@ CREATE TABLE public."RegistrarPoc" (
|
||||||
|
|
||||||
CREATE TABLE public."RegistryLock" (
|
CREATE TABLE public."RegistryLock" (
|
||||||
revision_id bigint NOT NULL,
|
revision_id bigint NOT NULL,
|
||||||
lock_completion_timestamp timestamp with time zone,
|
lock_completion_time timestamp with time zone,
|
||||||
lock_request_timestamp timestamp with time zone NOT NULL,
|
lock_request_time timestamp with time zone NOT NULL,
|
||||||
domain_name text NOT NULL,
|
domain_name text NOT NULL,
|
||||||
is_superuser boolean NOT NULL,
|
is_superuser boolean NOT NULL,
|
||||||
registrar_id text NOT NULL,
|
registrar_id text NOT NULL,
|
||||||
registrar_poc_id text,
|
registrar_poc_id text,
|
||||||
repo_id text NOT NULL,
|
repo_id text NOT NULL,
|
||||||
verification_code text NOT NULL,
|
verification_code text NOT NULL,
|
||||||
unlock_request_timestamp timestamp with time zone,
|
unlock_request_time timestamp with time zone,
|
||||||
unlock_completion_timestamp timestamp with time zone,
|
unlock_completion_time timestamp with time zone,
|
||||||
last_update_timestamp timestamp with time zone,
|
last_update_time timestamp with time zone NOT NULL,
|
||||||
relock_revision_id bigint,
|
relock_revision_id bigint,
|
||||||
relock_duration interval
|
relock_duration interval
|
||||||
);
|
);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue