diff --git a/common/src/main/java/google/registry/util/Clock.java b/common/src/main/java/google/registry/util/Clock.java
index 78372cba4bc..9943aaa7cec 100644
--- a/common/src/main/java/google/registry/util/Clock.java
+++ b/common/src/main/java/google/registry/util/Clock.java
@@ -15,6 +15,7 @@
package google.registry.util;
import java.io.Serializable;
+import java.time.Instant;
import javax.annotation.concurrent.ThreadSafe;
import org.joda.time.DateTime;
@@ -30,5 +31,9 @@
public interface Clock extends Serializable {
/** Returns current time in UTC timezone. */
+ @Deprecated
DateTime nowUtc();
+
+ /** Returns current Instant (which is always in UTC). */
+ Instant now();
}
diff --git a/common/src/main/java/google/registry/util/DateTimeUtils.java b/common/src/main/java/google/registry/util/DateTimeUtils.java
index b085fbabdc8..025ca3dde81 100644
--- a/common/src/main/java/google/registry/util/DateTimeUtils.java
+++ b/common/src/main/java/google/registry/util/DateTimeUtils.java
@@ -20,6 +20,9 @@
import com.google.common.collect.Lists;
import com.google.common.collect.Ordering;
import java.sql.Date;
+import java.time.Instant;
+import java.time.ZoneOffset;
+import javax.annotation.Nullable;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.joda.time.LocalDate;
@@ -28,7 +31,10 @@
public abstract class DateTimeUtils {
/** The start of the epoch, in a convenient constant. */
- public static final DateTime START_OF_TIME = new DateTime(0, DateTimeZone.UTC);
+ @Deprecated public static final DateTime START_OF_TIME = new DateTime(0, DateTimeZone.UTC);
+
+ /** The start of the UNIX epoch in UTC, in a convenient constant. */
+ public static final Instant START_INSTANT = Instant.ofEpochMilli(0);
/**
* A date in the far future that we can treat as infinity.
@@ -37,19 +43,40 @@ public abstract class DateTimeUtils {
* but Java uses milliseconds, so this is the largest representable date that will survive a
* round-trip through the database.
*/
+ @Deprecated
public static final DateTime END_OF_TIME = new DateTime(Long.MAX_VALUE / 1000, DateTimeZone.UTC);
+ /**
+ * An instant in the far future that we can treat as infinity.
+ *
+ *
This value is (2^63-1)/1000 rounded down. Postgres can store dates as 64 bit microseconds,
+ * but Java uses milliseconds, so this is the largest representable date that will survive a
+ * round-trip through the database.
+ */
+ public static final Instant END_INSTANT = Instant.ofEpochMilli(Long.MAX_VALUE / 1000);
+
/** Returns the earliest of a number of given {@link DateTime} instances. */
public static DateTime earliestOf(DateTime first, DateTime... rest) {
+ return earliestDateTimeOf(Lists.asList(first, rest));
+ }
+
+ /** Returns the earliest of a number of given {@link Instant} instances. */
+ public static Instant earliestOf(Instant first, Instant... rest) {
return earliestOf(Lists.asList(first, rest));
}
/** Returns the earliest element in a {@link DateTime} iterable. */
- public static DateTime earliestOf(Iterable dates) {
+ public static DateTime earliestDateTimeOf(Iterable dates) {
checkArgument(!Iterables.isEmpty(dates));
return Ordering.natural().min(dates);
}
+ /** Returns the earliest element in a {@link Instant} iterable. */
+ public static Instant earliestOf(Iterable instants) {
+ checkArgument(!Iterables.isEmpty(instants));
+ return Ordering.natural().min(instants);
+ }
+
/** Returns the latest of a number of given {@link DateTime} instances. */
public static DateTime latestOf(DateTime first, DateTime... rest) {
return latestOf(Lists.asList(first, rest));
@@ -66,29 +93,63 @@ public static boolean isBeforeOrAt(DateTime timeToCheck, DateTime timeToCompareT
return !timeToCheck.isAfter(timeToCompareTo);
}
+ /** Returns whether the first {@link Instant} is equal to or earlier than the second. */
+ public static boolean isBeforeOrAt(Instant timeToCheck, Instant timeToCompareTo) {
+ return !timeToCheck.isAfter(timeToCompareTo);
+ }
+
/** Returns whether the first {@link DateTime} is equal to or later than the second. */
public static boolean isAtOrAfter(DateTime timeToCheck, DateTime timeToCompareTo) {
return !timeToCheck.isBefore(timeToCompareTo);
}
+ /** Returns whether the first {@link Instant} is equal to or later than the second. */
+ public static boolean isAtOrAfter(Instant timeToCheck, Instant timeToCompareTo) {
+ return !timeToCheck.isBefore(timeToCompareTo);
+ }
+
/**
* Adds years to a date, in the {@code Duration} sense of semantic years. Use this instead of
* {@link DateTime#plusYears} to ensure that we never end up on February 29.
*/
+ @Deprecated
public static DateTime leapSafeAddYears(DateTime now, int years) {
checkArgument(years >= 0);
return years == 0 ? now : now.plusYears(1).plusYears(years - 1);
}
+ /**
+ * Adds years to a date, in the {@code Duration} sense of semantic years. Use this instead of
+ * {@link DateTime#plusYears} to ensure that we never end up on February 29.
+ */
+ public static Instant leapSafeAddYears(Instant now, long years) {
+ checkArgument(years >= 0);
+ return (years == 0)
+ ? now
+ : now.atZone(ZoneOffset.UTC).plusYears(1).plusYears(years - 1).toInstant();
+ }
+
/**
* Subtracts years from a date, in the {@code Duration} sense of semantic years. Use this instead
* of {@link DateTime#minusYears} to ensure that we never end up on February 29.
*/
+ @Deprecated
public static DateTime leapSafeSubtractYears(DateTime now, int years) {
checkArgument(years >= 0);
return years == 0 ? now : now.minusYears(1).minusYears(years - 1);
}
+ /**
+ * Subtracts years from a date, in the {@code Duration} sense of semantic years. Use this instead
+ * of {@link DateTime#minusYears} to ensure that we never end up on February 29.
+ */
+ public static Instant leapSafeSubtractYears(Instant now, long years) {
+ checkArgument(years >= 0);
+ return (years == 0)
+ ? now
+ : now.atZone(ZoneOffset.UTC).minusYears(1).minusYears(years - 1).toInstant();
+ }
+
public static Date toSqlDate(LocalDate localDate) {
return new Date(localDate.toDateTimeAtStartOfDay().getMillis());
}
@@ -96,4 +157,28 @@ public static Date toSqlDate(LocalDate localDate) {
public static LocalDate toLocalDate(Date date) {
return new LocalDate(date.getTime(), DateTimeZone.UTC);
}
+
+ /** Convert a joda {@link DateTime} to a java.time {@link Instant}, null-safe. */
+ @Nullable
+ public static Instant toInstant(@Nullable DateTime dateTime) {
+ return (dateTime == null) ? null : Instant.ofEpochMilli(dateTime.getMillis());
+ }
+
+ /** Convert a java.time {@link Instant} to a joda {@link DateTime}, null-safe. */
+ @Nullable
+ public static DateTime toDateTime(@Nullable Instant instant) {
+ return (instant == null) ? null : new DateTime(instant.toEpochMilli(), DateTimeZone.UTC);
+ }
+
+ public static Instant plusYears(Instant instant, int years) {
+ return instant.atZone(ZoneOffset.UTC).plusYears(years).toInstant();
+ }
+
+ public static Instant plusDays(Instant instant, int days) {
+ return instant.atZone(ZoneOffset.UTC).plusDays(days).toInstant();
+ }
+
+ public static Instant minusDays(Instant instant, int days) {
+ return instant.atZone(ZoneOffset.UTC).minusDays(days).toInstant();
+ }
}
diff --git a/common/src/main/java/google/registry/util/SystemClock.java b/common/src/main/java/google/registry/util/SystemClock.java
index eb553678d45..7e4e7551c1c 100644
--- a/common/src/main/java/google/registry/util/SystemClock.java
+++ b/common/src/main/java/google/registry/util/SystemClock.java
@@ -17,6 +17,7 @@
import static org.joda.time.DateTimeZone.UTC;
import jakarta.inject.Inject;
+import java.time.Instant;
import javax.annotation.concurrent.ThreadSafe;
import org.joda.time.DateTime;
@@ -34,4 +35,13 @@ public SystemClock() {}
public DateTime nowUtc() {
return DateTime.now(UTC);
}
+
+ @Override
+ public Instant now() {
+ // Truncate to milliseconds to match the precision of Joda DateTime and our database schema
+ // (which uses millisecond precision via DateTimeConverter). This prevents subtle comparison
+ // bugs where a high-precision Instant would be considered "after" a truncated database
+ // timestamp.
+ return Instant.now().truncatedTo(java.time.temporal.ChronoUnit.MILLIS);
+ }
}
diff --git a/common/src/testing/java/google/registry/testing/FakeClock.java b/common/src/testing/java/google/registry/testing/FakeClock.java
index 526f943a2ea..656ec7109b9 100644
--- a/common/src/testing/java/google/registry/testing/FakeClock.java
+++ b/common/src/testing/java/google/registry/testing/FakeClock.java
@@ -19,6 +19,7 @@
import static org.joda.time.Duration.millis;
import google.registry.util.Clock;
+import java.time.Instant;
import java.util.concurrent.atomic.AtomicLong;
import javax.annotation.concurrent.ThreadSafe;
import org.joda.time.DateTime;
@@ -54,6 +55,11 @@ public DateTime nowUtc() {
return new DateTime(currentTimeMillis.addAndGet(autoIncrementStepMs), UTC);
}
+ @Override
+ public Instant now() {
+ return Instant.ofEpochMilli(currentTimeMillis.addAndGet(autoIncrementStepMs));
+ }
+
/**
* Sets the increment applied to the clock whenever it is queried. The increment is zero by
* default: the clock is left unchanged when queried.
diff --git a/core/src/main/java/google/registry/batch/BulkDomainTransferAction.java b/core/src/main/java/google/registry/batch/BulkDomainTransferAction.java
index 990428edde9..b3bcc419d3b 100644
--- a/core/src/main/java/google/registry/batch/BulkDomainTransferAction.java
+++ b/core/src/main/java/google/registry/batch/BulkDomainTransferAction.java
@@ -17,6 +17,7 @@
import static com.google.common.net.MediaType.PLAIN_TEXT_UTF_8;
import static google.registry.flows.FlowUtils.marshalWithLenientRetry;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
+import static google.registry.util.DateTimeUtils.END_INSTANT;
import static jakarta.servlet.http.HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
import static jakarta.servlet.http.HttpServletResponse.SC_NO_CONTENT;
import static jakarta.servlet.http.HttpServletResponse.SC_OK;
@@ -39,7 +40,6 @@
import google.registry.request.Response;
import google.registry.request.auth.Auth;
import google.registry.request.lock.LockHandler;
-import google.registry.util.DateTimeUtils;
import jakarta.inject.Inject;
import jakarta.inject.Named;
import java.util.Optional;
@@ -212,7 +212,7 @@ private void runTransferFlowInTransaction(String domainName) {
private boolean shouldSkipDomain(String domainName) {
Optional maybeDomain =
- ForeignKeyUtils.loadResource(Domain.class, domainName, tm().getTransactionTime());
+ ForeignKeyUtils.loadResource(Domain.class, domainName, tm().getTxTime());
if (maybeDomain.isEmpty()) {
logger.atWarning().log("Domain '%s' was already deleted", domainName);
missingDomains++;
@@ -232,7 +232,7 @@ private boolean shouldSkipDomain(String domainName) {
return true;
}
if (domain.getStatusValues().contains(StatusValue.PENDING_DELETE)
- || !domain.getDeletionTime().equals(DateTimeUtils.END_OF_TIME)) {
+ || !domain.getDeletionTime().equals(END_INSTANT)) {
logger.atWarning().log("Domain '%s' is in PENDING_DELETE", domainName);
pendingDelete++;
return true;
diff --git a/core/src/main/java/google/registry/batch/DeleteExpiredDomainsAction.java b/core/src/main/java/google/registry/batch/DeleteExpiredDomainsAction.java
index 5281360342c..a23d5ce17eb 100644
--- a/core/src/main/java/google/registry/batch/DeleteExpiredDomainsAction.java
+++ b/core/src/main/java/google/registry/batch/DeleteExpiredDomainsAction.java
@@ -18,6 +18,7 @@
import static com.google.common.net.MediaType.PLAIN_TEXT_UTF_8;
import static google.registry.flows.FlowUtils.marshalWithLenientRetry;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
+import static google.registry.util.DateTimeUtils.END_INSTANT;
import static google.registry.util.DateTimeUtils.END_OF_TIME;
import static google.registry.util.ResourceUtils.readResourceUtf8;
import static jakarta.servlet.http.HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
@@ -177,7 +178,7 @@ private boolean runDomainDeleteFlow(Domain domain) {
"Failed to delete domain %s because of its autorenew end time: %s.",
transDomain.getDomainName(), transDomain.getAutorenewEndTime());
return Optional.empty();
- } else if (domain.getDeletionTime().isBefore(END_OF_TIME)) {
+ } else if (domain.getDeletionTime().isBefore(END_INSTANT)) {
logger.atSevere().log(
"Failed to delete domain %s because it was already deleted on %s.",
transDomain.getDomainName(), transDomain.getDeletionTime());
diff --git a/core/src/main/java/google/registry/batch/DeleteProberDataAction.java b/core/src/main/java/google/registry/batch/DeleteProberDataAction.java
index c34718b4875..f442f308a42 100644
--- a/core/src/main/java/google/registry/batch/DeleteProberDataAction.java
+++ b/core/src/main/java/google/registry/batch/DeleteProberDataAction.java
@@ -28,7 +28,6 @@
import static google.registry.request.RequestParameters.PARAM_DRY_RUN;
import static google.registry.request.RequestParameters.PARAM_TLDS;
import static google.registry.util.RegistryEnvironment.PRODUCTION;
-import static org.joda.time.DateTimeZone.UTC;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableList;
@@ -44,6 +43,7 @@
import google.registry.request.Action;
import google.registry.request.Parameter;
import google.registry.request.auth.Auth;
+import google.registry.util.Clock;
import google.registry.util.RegistryEnvironment;
import jakarta.inject.Inject;
import jakarta.persistence.TypedQuery;
@@ -111,16 +111,20 @@ public class DeleteProberDataAction implements Runnable {
String registryAdminRegistrarId;
+ private final Clock clock;
+
@Inject
DeleteProberDataAction(
@Parameter(PARAM_DRY_RUN) boolean isDryRun,
@Parameter(PARAM_TLDS) ImmutableSet tlds,
@Parameter(PARAM_BATCH_SIZE) Optional batchSize,
- @Config("registryAdminClientId") String registryAdminRegistrarId) {
+ @Config("registryAdminClientId") String registryAdminRegistrarId,
+ Clock clock) {
this.isDryRun = isDryRun;
this.tlds = tlds;
this.batchSize = batchSize.orElse(DEFAULT_BATCH_SIZE);
this.registryAdminRegistrarId = registryAdminRegistrarId;
+ this.clock = clock;
}
@Override
@@ -145,7 +149,7 @@ public void run() {
AtomicInteger softDeletedDomains = new AtomicInteger();
AtomicInteger hardDeletedDomains = new AtomicInteger();
AtomicReference> domainsBatch = new AtomicReference<>();
- DateTime startTime = DateTime.now(UTC);
+ DateTime startTime = clock.nowUtc();
do {
tm().transact(
TRANSACTION_REPEATABLE_READ,
@@ -164,7 +168,7 @@ public void run() {
hardDeletedDomains.get(), batchSize);
// Automatically kill the job if it is running for over 20 hours
- } while (DateTime.now(UTC).isBefore(startTime.plusHours(20))
+ } while (clock.nowUtc().isBefore(startTime.plusHours(20))
&& domainsBatch.get().size() == batchSize);
logger.atInfo().log(
"%s %d domains.",
diff --git a/core/src/main/java/google/registry/batch/RelockDomainAction.java b/core/src/main/java/google/registry/batch/RelockDomainAction.java
index f9a5ab5bec9..010eef40f93 100644
--- a/core/src/main/java/google/registry/batch/RelockDomainAction.java
+++ b/core/src/main/java/google/registry/batch/RelockDomainAction.java
@@ -188,7 +188,7 @@ private void verifyDomainAndLockState(RegistryLock oldLock, Domain domain) {
"Domain %s has a pending delete.",
domainName);
checkArgument(
- !DateTimeUtils.isAtOrAfter(tm().getTransactionTime(), domain.getDeletionTime()),
+ !DateTimeUtils.isAtOrAfter(tm().getTxTime(), domain.getDeletionTime()),
"Domain %s has been deleted.",
domainName);
checkArgument(
diff --git a/core/src/main/java/google/registry/batch/SendExpiringCertificateNotificationEmailAction.java b/core/src/main/java/google/registry/batch/SendExpiringCertificateNotificationEmailAction.java
index 4ee917951ad..02cd0dc6fb8 100644
--- a/core/src/main/java/google/registry/batch/SendExpiringCertificateNotificationEmailAction.java
+++ b/core/src/main/java/google/registry/batch/SendExpiringCertificateNotificationEmailAction.java
@@ -19,7 +19,6 @@
import static google.registry.util.PreconditionsUtils.checkArgumentNotNull;
import static org.apache.http.HttpStatus.SC_INTERNAL_SERVER_ERROR;
import static org.apache.http.HttpStatus.SC_OK;
-import static org.joda.time.DateTimeZone.UTC;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.ImmutableList;
@@ -37,6 +36,7 @@
import google.registry.request.Action;
import google.registry.request.Response;
import google.registry.request.auth.Auth;
+import google.registry.util.Clock;
import google.registry.util.EmailMessage;
import jakarta.inject.Inject;
import jakarta.mail.internet.AddressException;
@@ -73,6 +73,7 @@ public class SendExpiringCertificateNotificationEmailAction implements Runnable
private final GmailClient gmailClient;
private final String expirationWarningEmailSubjectText;
private final Response response;
+ private final Clock clock;
@Inject
public SendExpiringCertificateNotificationEmailAction(
@@ -80,12 +81,14 @@ public SendExpiringCertificateNotificationEmailAction(
@Config("expirationWarningEmailSubjectText") String expirationWarningEmailSubjectText,
GmailClient gmailClient,
CertificateChecker certificateChecker,
- Response response) {
+ Response response,
+ Clock clock) {
this.certificateChecker = certificateChecker;
this.expirationWarningEmailSubjectText = expirationWarningEmailSubjectText;
this.gmailClient = gmailClient;
this.expirationWarningEmailBodyText = expirationWarningEmailBodyText;
this.response = response;
+ this.clock = clock;
}
@Override
@@ -186,7 +189,7 @@ boolean sendNotificationEmail(
*/
updateLastNotificationSentDate(
registrar,
- DateTime.now(UTC).minusMinutes((int) UPDATE_TIME_OFFSET.getStandardMinutes()),
+ clock.nowUtc().minusMinutes((int) UPDATE_TIME_OFFSET.getStandardMinutes()),
certificateType);
return true;
} catch (Exception e) {
diff --git a/core/src/main/java/google/registry/beam/billing/ExpandBillingRecurrencesPipeline.java b/core/src/main/java/google/registry/beam/billing/ExpandBillingRecurrencesPipeline.java
index 193103c69a9..1bfcc1c487c 100644
--- a/core/src/main/java/google/registry/beam/billing/ExpandBillingRecurrencesPipeline.java
+++ b/core/src/main/java/google/registry/beam/billing/ExpandBillingRecurrencesPipeline.java
@@ -24,6 +24,7 @@
import static google.registry.util.DateTimeUtils.START_OF_TIME;
import static google.registry.util.DateTimeUtils.earliestOf;
import static google.registry.util.DateTimeUtils.latestOf;
+import static google.registry.util.DateTimeUtils.toInstant;
import static org.apache.beam.sdk.values.TypeDescriptors.voids;
import com.google.common.collect.ImmutableMap;
@@ -372,7 +373,7 @@ private void expandOneRecurrence(
// during ARGP).
//
// See: DomainFlowUtils#createCancellingRecords
- domain.getDeletionTime().isBefore(billingTime)
+ domain.getDeletionTime().isBefore(toInstant(billingTime))
? ImmutableSet.of()
: ImmutableSet.of(
DomainTransactionRecord.create(
diff --git a/core/src/main/java/google/registry/bigquery/BigqueryConnection.java b/core/src/main/java/google/registry/bigquery/BigqueryConnection.java
index 93bf6fae9d2..d001645f8a3 100644
--- a/core/src/main/java/google/registry/bigquery/BigqueryConnection.java
+++ b/core/src/main/java/google/registry/bigquery/BigqueryConnection.java
@@ -24,7 +24,6 @@
import static com.google.common.util.concurrent.MoreExecutors.directExecutor;
import static google.registry.bigquery.BigqueryUtils.toJobReferenceString;
import static google.registry.config.RegistryConfig.getProjectId;
-import static org.joda.time.DateTimeZone.UTC;
import com.google.api.client.googleapis.json.GoogleJsonResponseException;
import com.google.api.client.http.AbstractInputStreamContent;
@@ -58,6 +57,7 @@
import google.registry.bigquery.BigqueryUtils.DestinationFormat;
import google.registry.bigquery.BigqueryUtils.TableType;
import google.registry.bigquery.BigqueryUtils.WriteDisposition;
+import google.registry.util.Clock;
import google.registry.util.NonFinalForTesting;
import google.registry.util.Sleeper;
import google.registry.util.SqlTemplate;
@@ -69,7 +69,6 @@
import java.util.Random;
import java.util.concurrent.ExecutorService;
import javax.annotation.Nullable;
-import org.joda.time.DateTime;
import org.joda.time.Duration;
/** Class encapsulating parameters and state for accessing the Bigquery API. */
@@ -94,6 +93,9 @@ public class BigqueryConnection implements AutoCloseable {
/** Bigquery client instance wrapped by this class. */
private final Bigquery bigquery;
+ /** Clock instance for this connection. */
+ private final Clock clock;
+
/** Executor service for bigquery jobs. */
private ListeningExecutorService service;
@@ -109,8 +111,9 @@ public class BigqueryConnection implements AutoCloseable {
/** Duration to wait between polls for job status. */
private Duration pollInterval = Duration.millis(1000);
- BigqueryConnection(Bigquery bigquery) {
+ BigqueryConnection(Bigquery bigquery, Clock clock) {
this.bigquery = bigquery;
+ this.clock = clock;
}
/** Builder for a {@link BigqueryConnection}, since the latter is immutable once created. */
@@ -118,8 +121,8 @@ public static class Builder {
private BigqueryConnection instance;
@Inject
- Builder(Bigquery bigquery) {
- instance = new BigqueryConnection(bigquery);
+ Builder(Bigquery bigquery, Clock clock) {
+ instance = new BigqueryConnection(bigquery, clock);
}
/**
@@ -195,6 +198,11 @@ public static final class Builder {
private final TableReference tableRef = new TableReference();
private TableType type = TableType.TABLE;
private WriteDisposition writeDisposition = WriteDisposition.WRITE_EMPTY;
+ private final Clock clock;
+
+ public Builder(Clock clock) {
+ this.clock = clock;
+ }
public Builder datasetId(String datasetId) {
tableRef.setDatasetId(datasetId);
@@ -217,7 +225,7 @@ public Builder type(TableType type) {
}
public Builder timeToLive(Duration duration) {
- this.table.setExpirationTime(DateTime.now(UTC).plus(duration).getMillis());
+ this.table.setExpirationTime(clock.nowUtc().plus(duration).getMillis());
return this;
}
@@ -302,7 +310,7 @@ public void close() {
/** Returns a partially built DestinationTable with the default dataset and overwrite behavior. */
public DestinationTable.Builder buildDestinationTable(String tableName) {
- return new DestinationTable.Builder()
+ return new DestinationTable.Builder(clock)
.datasetId(datasetId)
.type(TableType.TABLE)
.name(tableName)
@@ -314,7 +322,7 @@ public DestinationTable.Builder buildDestinationTable(String tableName) {
* temporary table dataset, with the default TTL and overwrite behavior.
*/
public DestinationTable.Builder buildTemporaryTable() {
- return new DestinationTable.Builder()
+ return new DestinationTable.Builder(clock)
.datasetId(TEMP_DATASET_NAME)
.type(TableType.TABLE)
.name(getRandomTableName())
diff --git a/core/src/main/java/google/registry/flows/ResourceFlowUtils.java b/core/src/main/java/google/registry/flows/ResourceFlowUtils.java
index 122d5ded3b0..101bafa96f0 100644
--- a/core/src/main/java/google/registry/flows/ResourceFlowUtils.java
+++ b/core/src/main/java/google/registry/flows/ResourceFlowUtils.java
@@ -16,6 +16,7 @@
import static com.google.common.collect.Sets.intersection;
import static google.registry.model.EppResourceUtils.isLinked;
+import static google.registry.util.DateTimeUtils.toInstant;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
@@ -44,6 +45,7 @@
import google.registry.model.host.Host;
import google.registry.model.transfer.TransferStatus;
import google.registry.persistence.VKey;
+import java.time.Instant;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
@@ -89,6 +91,11 @@ public static void verifyTransferInitiator(String registrarId, Domain domain)
public static R loadAndVerifyExistence(
Class clazz, String targetId, DateTime now) throws ResourceDoesNotExistException {
+ return loadAndVerifyExistence(clazz, targetId, toInstant(now));
+ }
+
+ public static R loadAndVerifyExistence(
+ Class clazz, String targetId, Instant now) throws ResourceDoesNotExistException {
return verifyExistence(clazz, targetId, ForeignKeyUtils.loadResource(clazz, targetId, now));
}
@@ -197,8 +204,8 @@ public static void verifyAllStatusesAreClientSettable(Set statusVal
*
* @param domain is the domain already projected at approvalTime
*/
- public static DateTime computeExDateForApprovalTime(
- DomainBase domain, DateTime approvalTime, Period period) {
+ public static Instant computeExDateForApprovalTime(
+ DomainBase domain, Instant approvalTime, Period period) {
boolean inAutoRenew = domain.getGracePeriodStatuses().contains(GracePeriodStatus.AUTO_RENEW);
// inAutoRenew is set to false if the period is zero because a zero-period transfer should not
// subsume an autorenew.
diff --git a/core/src/main/java/google/registry/flows/domain/DomainDeleteFlow.java b/core/src/main/java/google/registry/flows/domain/DomainDeleteFlow.java
index 6414aa93b80..9cb5a7c4b66 100644
--- a/core/src/main/java/google/registry/flows/domain/DomainDeleteFlow.java
+++ b/core/src/main/java/google/registry/flows/domain/DomainDeleteFlow.java
@@ -236,7 +236,7 @@ public EppResponse run() throws EppException {
}
// Cancel any grace periods that were still active, and set the expiration time accordingly.
- DateTime newExpirationTime = existingDomain.getRegistrationExpirationTime();
+ DateTime newExpirationTime = existingDomain.getRegistrationExpirationDateTime();
for (GracePeriod gracePeriod : existingDomain.getGracePeriods()) {
// No cancellation is written if the grace period was not for a billable event.
if (gracePeriod.hasBillingEvent()) {
@@ -289,7 +289,7 @@ public EppResponse run() throws EppException {
flowCustomLogic.beforeResponse(
BeforeResponseParameters.newBuilder()
.setResultCode(
- newDomain.getDeletionTime().isAfter(now)
+ newDomain.getDeletionDateTime().isAfter(now)
? SUCCESS_WITH_ACTION_PENDING
: SUCCESS)
.setResponseExtensions(
diff --git a/core/src/main/java/google/registry/flows/domain/DomainFlowUtils.java b/core/src/main/java/google/registry/flows/domain/DomainFlowUtils.java
index fb6b358dca1..3a2fdd196fc 100644
--- a/core/src/main/java/google/registry/flows/domain/DomainFlowUtils.java
+++ b/core/src/main/java/google/registry/flows/domain/DomainFlowUtils.java
@@ -503,7 +503,7 @@ public static BillingRecurrence.Builder newAutorenewBillingEvent(Domain domain)
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
.setTargetId(domain.getDomainName())
.setRegistrarId(domain.getCurrentSponsorRegistrarId())
- .setEventTime(domain.getRegistrationExpirationTime());
+ .setEventTime(domain.getRegistrationExpirationDateTime());
}
/**
@@ -514,7 +514,7 @@ public static Autorenew.Builder newAutorenewPollMessage(Domain domain) {
return new Autorenew.Builder()
.setTargetId(domain.getDomainName())
.setRegistrarId(domain.getCurrentSponsorRegistrarId())
- .setEventTime(domain.getRegistrationExpirationTime())
+ .setEventTime(domain.getRegistrationExpirationDateTime())
.setMsg("Domain was auto-renewed.");
}
@@ -658,7 +658,7 @@ static void handleFeeRequest(
// process, don't count as expired for the purposes of requiring an added year of renewal on
// restore because they can't be restored in the first place.
boolean isExpired =
- domain.isPresent() && domain.get().getRegistrationExpirationTime().isBefore(now);
+ domain.isPresent() && domain.get().getRegistrationExpirationDateTime().isBefore(now);
fees = pricingLogic.getRestorePrice(tld, domainNameString, now, isExpired).getFees();
}
case TRANSFER -> {
diff --git a/core/src/main/java/google/registry/flows/domain/DomainInfoFlow.java b/core/src/main/java/google/registry/flows/domain/DomainInfoFlow.java
index 15a9b1b48c9..8815d2ca7bd 100644
--- a/core/src/main/java/google/registry/flows/domain/DomainInfoFlow.java
+++ b/core/src/main/java/google/registry/flows/domain/DomainInfoFlow.java
@@ -122,8 +122,8 @@ public EppResponse run() throws EppException {
.setNameservers(
hostsRequest.requestDelegated() ? domain.loadNameserverHostNames() : null)
.setCreationTime(domain.getCreationTime())
- .setLastEppUpdateTime(domain.getLastEppUpdateTime())
- .setRegistrationExpirationTime(domain.getRegistrationExpirationTime())
+ .setLastEppUpdateTime(domain.getLastEppUpdateDateTime())
+ .setRegistrationExpirationTime(domain.getRegistrationExpirationDateTime())
.setLastTransferTime(domain.getLastTransferTime());
// If authInfo is non-null, then the caller is authorized to see the full information since we
diff --git a/core/src/main/java/google/registry/flows/domain/DomainRenewFlow.java b/core/src/main/java/google/registry/flows/domain/DomainRenewFlow.java
index ec7d982ca77..32278bf53d4 100644
--- a/core/src/main/java/google/registry/flows/domain/DomainRenewFlow.java
+++ b/core/src/main/java/google/registry/flows/domain/DomainRenewFlow.java
@@ -191,7 +191,7 @@ public EppResponse run() throws EppException {
existingDomain = maybeApplyBulkPricingRemovalToken(existingDomain, allocationToken);
DateTime newExpirationTime =
- leapSafeAddYears(existingDomain.getRegistrationExpirationTime(), years); // Uncapped
+ leapSafeAddYears(existingDomain.getRegistrationExpirationDateTime(), years); // Uncapped
validateRegistrationPeriod(now, newExpirationTime);
Optional feeRenew =
eppInput.getSingleExtension(FeeRenewCommandExtension.class);
@@ -328,8 +328,9 @@ private void verifyRenewAllowed(
// We only allow __REMOVE_BULK_PRICING__ token on bulk pricing domains for now
verifyBulkTokenAllowedOnDomain(existingDomain, allocationToken);
// If the date they specify doesn't match the expiration, fail. (This is an idempotence check).
- if (!command.getCurrentExpirationDate().equals(
- existingDomain.getRegistrationExpirationTime().toLocalDate())) {
+ if (!command
+ .getCurrentExpirationDate()
+ .equals(existingDomain.getRegistrationExpirationDateTime().toLocalDate())) {
throw new IncorrectCurrentExpirationDateException();
}
}
diff --git a/core/src/main/java/google/registry/flows/domain/DomainRestoreRequestFlow.java b/core/src/main/java/google/registry/flows/domain/DomainRestoreRequestFlow.java
index 29fc413d351..3ec154e7f8b 100644
--- a/core/src/main/java/google/registry/flows/domain/DomainRestoreRequestFlow.java
+++ b/core/src/main/java/google/registry/flows/domain/DomainRestoreRequestFlow.java
@@ -138,7 +138,7 @@ public EppResponse run() throws EppException {
Update command = (Update) resourceCommand;
DateTime now = tm().getTransactionTime();
Domain existingDomain = loadAndVerifyExistence(Domain.class, targetId, now);
- boolean isExpired = existingDomain.getRegistrationExpirationTime().isBefore(now);
+ boolean isExpired = existingDomain.getRegistrationExpirationDateTime().isBefore(now);
FeesAndCredits feesAndCredits =
pricingLogic.getRestorePrice(Tld.get(existingDomain.getTld()), targetId, now, isExpired);
Optional feeUpdate =
@@ -149,7 +149,7 @@ public EppResponse run() throws EppException {
ImmutableSet.Builder entitiesToInsert = new ImmutableSet.Builder<>();
DateTime newExpirationTime =
- existingDomain.getRegistrationExpirationTime().plusYears(isExpired ? 1 : 0);
+ existingDomain.getRegistrationExpirationDateTime().plusYears(isExpired ? 1 : 0);
// Restore the expiration time on the deleted domain, except if that's already passed, then add
// a year and bill for it immediately, with no grace period.
if (isExpired) {
diff --git a/core/src/main/java/google/registry/flows/domain/DomainTransferApproveFlow.java b/core/src/main/java/google/registry/flows/domain/DomainTransferApproveFlow.java
index cea6f656825..7b7eb47b328 100644
--- a/core/src/main/java/google/registry/flows/domain/DomainTransferApproveFlow.java
+++ b/core/src/main/java/google/registry/flows/domain/DomainTransferApproveFlow.java
@@ -33,6 +33,8 @@
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.util.CollectionUtils.union;
import static google.registry.util.DateTimeUtils.END_OF_TIME;
+import static google.registry.util.DateTimeUtils.toDateTime;
+import static google.registry.util.DateTimeUtils.toInstant;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
@@ -193,7 +195,9 @@ public EppResponse run() throws EppException {
updateAutorenewRecurrenceEndTime(
existingDomain, existingBillingRecurrence, now, domainHistoryId);
DateTime newExpirationTime =
- computeExDateForApprovalTime(existingDomain, now, transferData.getTransferPeriod());
+ toDateTime(
+ computeExDateForApprovalTime(
+ existingDomain, toInstant(now), transferData.getTransferPeriod()));
// Create a new autorenew event starting at the expiration time.
BillingRecurrence autorenewEvent =
new BillingRecurrence.Builder()
@@ -268,8 +272,11 @@ public EppResponse run() throws EppException {
// been implicitly server approved.
tm().delete(existingDomain.getTransferData().getServerApproveEntities());
return responseBuilder
- .setResData(createTransferResponse(
- targetId, newDomain.getTransferData(), newDomain.getRegistrationExpirationTime()))
+ .setResData(
+ createTransferResponse(
+ targetId,
+ newDomain.getTransferData(),
+ newDomain.getRegistrationExpirationDateTime()))
.build();
}
diff --git a/core/src/main/java/google/registry/flows/domain/DomainTransferQueryFlow.java b/core/src/main/java/google/registry/flows/domain/DomainTransferQueryFlow.java
index b562422b6b5..3e002f60c13 100644
--- a/core/src/main/java/google/registry/flows/domain/DomainTransferQueryFlow.java
+++ b/core/src/main/java/google/registry/flows/domain/DomainTransferQueryFlow.java
@@ -15,15 +15,17 @@
package google.registry.flows.domain;
import static google.registry.flows.FlowUtils.validateRegistrarIsLoggedIn;
+import static google.registry.flows.ResourceFlowUtils.computeExDateForApprovalTime;
import static google.registry.flows.ResourceFlowUtils.loadAndVerifyExistence;
import static google.registry.flows.ResourceFlowUtils.verifyOptionalAuthInfo;
import static google.registry.flows.domain.DomainTransferUtils.createTransferResponse;
+import static google.registry.util.DateTimeUtils.toDateTime;
+import static google.registry.util.DateTimeUtils.toInstant;
import google.registry.flows.EppException;
import google.registry.flows.ExtensionManager;
import google.registry.flows.FlowModule.RegistrarId;
import google.registry.flows.FlowModule.TargetId;
-import google.registry.flows.ResourceFlowUtils;
import google.registry.flows.TransactionalFlow;
import google.registry.flows.annotations.ReportingSpec;
import google.registry.flows.exceptions.NoTransferHistoryToQueryException;
@@ -88,11 +90,12 @@ public EppResponse run() throws EppException {
}
DateTime newExpirationTime = null;
if (transferData.getTransferStatus().isApproved()) {
- newExpirationTime = transferData.getTransferredRegistrationExpirationTime();
+ newExpirationTime = transferData.getTransferredRegistrationExpirationDateTime();
} else if (transferData.getTransferStatus().equals(TransferStatus.PENDING)) {
newExpirationTime =
- ResourceFlowUtils.computeExDateForApprovalTime(
- domain, now, domain.getTransferData().getTransferPeriod());
+ toDateTime(
+ computeExDateForApprovalTime(
+ domain, toInstant(now), domain.getTransferData().getTransferPeriod()));
}
return responseBuilder
.setResData(createTransferResponse(targetId, transferData, newExpirationTime))
diff --git a/core/src/main/java/google/registry/flows/domain/DomainTransferRejectFlow.java b/core/src/main/java/google/registry/flows/domain/DomainTransferRejectFlow.java
index 351ee5e18fd..39b25d8d551 100644
--- a/core/src/main/java/google/registry/flows/domain/DomainTransferRejectFlow.java
+++ b/core/src/main/java/google/registry/flows/domain/DomainTransferRejectFlow.java
@@ -32,6 +32,7 @@
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.util.CollectionUtils.union;
import static google.registry.util.DateTimeUtils.END_OF_TIME;
+import static google.registry.util.DateTimeUtils.toDateTime;
import com.google.common.collect.ImmutableSet;
import google.registry.flows.EppException;
@@ -53,6 +54,7 @@
import google.registry.model.tld.Tld;
import google.registry.model.transfer.TransferStatus;
import jakarta.inject.Inject;
+import java.time.Instant;
import java.util.Optional;
import org.joda.time.DateTime;
@@ -92,7 +94,7 @@ public EppResponse run() throws EppException {
extensionManager.register(MetadataExtension.class);
validateRegistrarIsLoggedIn(registrarId);
extensionManager.validate();
- DateTime now = tm().getTransactionTime();
+ Instant now = tm().getTxTime();
Domain existingDomain = loadAndVerifyExistence(Domain.class, targetId, now);
Tld tld = Tld.get(existingDomain.getTld());
HistoryEntryId domainHistoryId = createHistoryEntryId(existingDomain);
@@ -107,13 +109,14 @@ public EppResponse run() throws EppException {
checkAllowedAccessToTld(registrarId, existingDomain.getTld());
}
Domain newDomain =
- denyPendingTransfer(existingDomain, TransferStatus.CLIENT_REJECTED, now, registrarId);
- DomainHistory domainHistory = buildDomainHistory(newDomain, tld, now);
+ denyPendingTransfer(
+ existingDomain, TransferStatus.CLIENT_REJECTED, toDateTime(now), registrarId);
+ DomainHistory domainHistory = buildDomainHistory(newDomain, tld, toDateTime(now));
tm().update(newDomain);
tm().insertAll(
domainHistory,
createGainingTransferPollMessage(
- targetId, newDomain.getTransferData(), null, now, domainHistoryId));
+ targetId, newDomain.getTransferData(), null, toDateTime(now), domainHistoryId));
// Reopen the autorenew event and poll message that we closed for the implicit transfer. This
// may end up recreating the poll message if it was deleted upon the transfer request.
BillingRecurrence existingBillingRecurrence =
diff --git a/core/src/main/java/google/registry/flows/domain/DomainTransferRequestFlow.java b/core/src/main/java/google/registry/flows/domain/DomainTransferRequestFlow.java
index db7ce17bfe5..ad711a9b722 100644
--- a/core/src/main/java/google/registry/flows/domain/DomainTransferRequestFlow.java
+++ b/core/src/main/java/google/registry/flows/domain/DomainTransferRequestFlow.java
@@ -35,6 +35,8 @@
import static google.registry.model.eppoutput.Result.Code.SUCCESS_WITH_ACTION_PENDING;
import static google.registry.model.reporting.HistoryEntry.Type.DOMAIN_TRANSFER_REQUEST;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
+import static google.registry.util.DateTimeUtils.toDateTime;
+import static google.registry.util.DateTimeUtils.toInstant;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
@@ -80,6 +82,7 @@
import google.registry.model.transfer.TransferResponse.DomainTransferResponse;
import google.registry.model.transfer.TransferStatus;
import jakarta.inject.Inject;
+import java.time.Instant;
import java.util.Optional;
import org.joda.time.DateTime;
@@ -230,7 +233,9 @@ public EppResponse run() throws EppException {
Domain domainAtTransferTime = existingDomain.cloneProjectedAtTime(automaticTransferTime);
// The new expiration time if there is a server approval.
DateTime serverApproveNewExpirationTime =
- computeExDateForApprovalTime(domainAtTransferTime, automaticTransferTime, period);
+ toDateTime(
+ computeExDateForApprovalTime(
+ domainAtTransferTime, toInstant(automaticTransferTime), period));
// Create speculative entities in anticipation of an automatic server approval.
ImmutableSet serverApproveEntities =
createTransferServerApproveEntities(
@@ -287,7 +292,7 @@ public EppResponse run() throws EppException {
tm().insertAll(domainHistory, requestPollMessage);
return responseBuilder
.setResultFromCode(SUCCESS_WITH_ACTION_PENDING)
- .setResData(createResponse(period, existingDomain, newDomain, now))
+ .setResData(createResponse(period, existingDomain, newDomain, toInstant(now)))
.setExtensions(createResponseExtensions(feesAndCredits, feeTransfer))
.build();
}
@@ -375,14 +380,14 @@ private DomainHistory buildDomainHistory(Domain newDomain, Tld tld, DateTime now
}
private DomainTransferResponse createResponse(
- Period period, Domain existingDomain, Domain newDomain, DateTime now) {
+ Period period, Domain existingDomain, Domain newDomain, Instant now) {
// If the registration were approved this instant, this is what the new expiration would be,
// because we cap at 10 years from the moment of approval. This is different from the server
// approval new expiration time, which is capped at 10 years from the server approve time.
- DateTime approveNowExtendedRegistrationTime =
+ Instant approveNowExtendedRegistrationTime =
computeExDateForApprovalTime(existingDomain, now, period);
return createTransferResponse(
- targetId, newDomain.getTransferData(), approveNowExtendedRegistrationTime);
+ targetId, newDomain.getTransferData(), toDateTime(approveNowExtendedRegistrationTime));
}
private static ImmutableList createResponseExtensions(
diff --git a/core/src/main/java/google/registry/flows/domain/DomainTransferUtils.java b/core/src/main/java/google/registry/flows/domain/DomainTransferUtils.java
index 60000b224d5..f9c0ab16372 100644
--- a/core/src/main/java/google/registry/flows/domain/DomainTransferUtils.java
+++ b/core/src/main/java/google/registry/flows/domain/DomainTransferUtils.java
@@ -184,7 +184,7 @@ public static PollMessage createGainingTransferPollMessage(
HistoryEntryId domainHistoryId) {
return new PollMessage.OneTime.Builder()
.setRegistrarId(transferData.getGainingRegistrarId())
- .setEventTime(transferData.getPendingTransferExpirationTime())
+ .setEventTime(transferData.getPendingTransferExpirationDateTime())
.setMsg(transferData.getTransferStatus().getMessage())
.setResponseData(
ImmutableList.of(
@@ -206,7 +206,7 @@ public static PollMessage createLosingTransferPollMessage(
HistoryEntryId domainHistoryId) {
return new PollMessage.OneTime.Builder()
.setRegistrarId(transferData.getLosingRegistrarId())
- .setEventTime(transferData.getPendingTransferExpirationTime())
+ .setEventTime(transferData.getPendingTransferExpirationDateTime())
.setMsg(transferData.getTransferStatus().getMessage())
.setResponseData(
ImmutableList.of(
@@ -224,7 +224,7 @@ static DomainTransferResponse createTransferResponse(
.setDomainName(targetId)
.setGainingRegistrarId(transferData.getGainingRegistrarId())
.setLosingRegistrarId(transferData.getLosingRegistrarId())
- .setPendingTransferExpirationTime(transferData.getPendingTransferExpirationTime())
+ .setPendingTransferExpirationTime(transferData.getPendingTransferExpirationDateTime())
.setTransferRequestTime(transferData.getTransferRequestTime())
.setTransferStatus(transferData.getTransferStatus())
.setExtendedRegistrationExpirationTime(extendedRegistrationExpirationTime)
diff --git a/core/src/main/java/google/registry/flows/domain/DomainUpdateFlow.java b/core/src/main/java/google/registry/flows/domain/DomainUpdateFlow.java
index 16f89e57b82..752c194ebbf 100644
--- a/core/src/main/java/google/registry/flows/domain/DomainUpdateFlow.java
+++ b/core/src/main/java/google/registry/flows/domain/DomainUpdateFlow.java
@@ -281,7 +281,7 @@ private Domain performUpdate(Update command, Domain domain, DateTime now) throws
if (superuserExt.get().getAutorenews().isPresent()) {
boolean autorenews = superuserExt.get().getAutorenews().get();
domainBuilder.setAutorenewEndTime(
- Optional.ofNullable(autorenews ? null : domain.getRegistrationExpirationTime()));
+ Optional.ofNullable(autorenews ? null : domain.getRegistrationExpirationDateTime()));
}
}
return domainBuilder.build();
diff --git a/core/src/main/java/google/registry/flows/host/HostInfoFlow.java b/core/src/main/java/google/registry/flows/host/HostInfoFlow.java
index af5a5b25851..4647ade8963 100644
--- a/core/src/main/java/google/registry/flows/host/HostInfoFlow.java
+++ b/core/src/main/java/google/registry/flows/host/HostInfoFlow.java
@@ -99,7 +99,7 @@ public EppResponse run() throws EppException {
.setCreationRegistrarId(host.getCreationRegistrarId())
.setCreationTime(host.getCreationTime())
.setLastEppUpdateRegistrarId(host.getLastEppUpdateRegistrarId())
- .setLastEppUpdateTime(host.getLastEppUpdateTime())
+ .setLastEppUpdateTime(host.getLastEppUpdateDateTime())
.build())
.build();
}
diff --git a/core/src/main/java/google/registry/model/EppResource.java b/core/src/main/java/google/registry/model/EppResource.java
index ee5c376ef63..f8007038f2d 100644
--- a/core/src/main/java/google/registry/model/EppResource.java
+++ b/core/src/main/java/google/registry/model/EppResource.java
@@ -25,6 +25,7 @@
import static google.registry.util.CollectionUtils.nullToEmpty;
import static google.registry.util.CollectionUtils.nullToEmptyImmutableCopy;
import static google.registry.util.DateTimeUtils.END_OF_TIME;
+import static google.registry.util.DateTimeUtils.toInstant;
import com.github.benmanes.caffeine.cache.CacheLoader;
import com.github.benmanes.caffeine.cache.LoadingCache;
@@ -45,6 +46,7 @@
import jakarta.persistence.MappedSuperclass;
import jakarta.persistence.Transient;
import java.time.Duration;
+import java.time.Instant;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
@@ -163,10 +165,15 @@ public String getCreationRegistrarId() {
return creationRegistrarId;
}
- public DateTime getLastEppUpdateTime() {
+ @Deprecated
+ public DateTime getLastEppUpdateDateTime() {
return lastEppUpdateTime;
}
+ public Instant getLastEppUpdateTime() {
+ return toInstant(lastEppUpdateTime);
+ }
+
public String getLastEppUpdateRegistrarId() {
return lastEppUpdateRegistrarId;
}
@@ -185,13 +192,22 @@ public final ImmutableSet getStatusValues() {
return nullToEmptyImmutableCopy(statuses);
}
- public DateTime getDeletionTime() {
+ @Deprecated
+ public DateTime getDeletionDateTime() {
return deletionTime;
}
+ public Instant getDeletionTime() {
+ return toInstant(deletionTime);
+ }
+
/** Return a clone of the resource with timed status values modified using the given time. */
+ @Deprecated
public abstract EppResource cloneProjectedAtTime(DateTime now);
+ /** Return a clone of the resource with timed status values modified using the given time. */
+ public abstract EppResource cloneProjectedAtInstant(Instant now);
+
/** Get the foreign key string for this resource. */
public abstract String getForeignKey();
diff --git a/core/src/main/java/google/registry/model/EppResourceUtils.java b/core/src/main/java/google/registry/model/EppResourceUtils.java
index 4af8c6ccf5c..c64591ce426 100644
--- a/core/src/main/java/google/registry/model/EppResourceUtils.java
+++ b/core/src/main/java/google/registry/model/EppResourceUtils.java
@@ -34,6 +34,7 @@
import google.registry.model.transfer.TransferStatus;
import google.registry.persistence.VKey;
import jakarta.persistence.Query;
+import java.time.Instant;
import java.util.Comparator;
import java.util.function.Function;
import javax.annotation.Nullable;
@@ -83,7 +84,7 @@ public static Function transformAtTime(final DateT
* exclusive, which happily maps to the behavior of Interval.
*/
private static Interval getLifetime(EppResource resource) {
- return new Interval(resource.getCreationTime(), resource.getDeletionTime());
+ return new Interval(resource.getCreationTime(), resource.getDeletionDateTime());
}
public static boolean isActive(EppResource resource, DateTime time) {
@@ -108,7 +109,7 @@ public static void setAutomaticTransferSuccessProperties(
builder
.removeStatusValue(StatusValue.PENDING_TRANSFER)
.setTransferData(transferDataBuilder.build())
- .setLastTransferTime(transferData.getPendingTransferExpirationTime())
+ .setLastTransferTime(transferData.getPendingTransferExpirationDateTime())
.setPersistedCurrentSponsorRegistrarId(transferData.getGainingRegistrarId());
}
@@ -120,10 +121,10 @@ public static void setAutomaticTransferSuccessProperties(
*
*/
public static void projectResourceOntoBuilderAtTime(
- DomainBase domain, DomainBase.Builder, ?> builder, DateTime now) {
+ DomainBase domain, DomainBase.Builder, ?> builder, Instant now) {
DomainTransferData transferData = domain.getTransferData();
// If there's a pending transfer that has expired, process it.
- DateTime expirationTime = transferData.getPendingTransferExpirationTime();
+ Instant expirationTime = transferData.getPendingTransferExpirationTime();
if (TransferStatus.PENDING.equals(transferData.getTransferStatus())
&& isBeforeOrAt(expirationTime, now)) {
setAutomaticTransferSuccessProperties(builder, transferData);
diff --git a/core/src/main/java/google/registry/model/ForeignKeyUtils.java b/core/src/main/java/google/registry/model/ForeignKeyUtils.java
index 9a0b08006e0..ba1ab670b79 100644
--- a/core/src/main/java/google/registry/model/ForeignKeyUtils.java
+++ b/core/src/main/java/google/registry/model/ForeignKeyUtils.java
@@ -35,6 +35,7 @@
import google.registry.persistence.transaction.JpaTransactionManager;
import google.registry.util.NonFinalForTesting;
import java.time.Duration;
+import java.time.Instant;
import java.util.Collection;
import java.util.Map;
import java.util.Map.Entry;
@@ -81,6 +82,7 @@ public static Optional> loadKey(
* Returns null if no resource with this foreign key was ever created or if the most recently
* created resource was deleted before time "now".
*/
+ @Deprecated
public static Optional loadResource(
Class clazz, String foreignKey, DateTime now) {
// Note: no need to project to "now" because loadResources already does
@@ -88,6 +90,19 @@ public static Optional loadResource(
loadResources(clazz, ImmutableList.of(foreignKey), now).get(foreignKey));
}
+ /**
+ * Loads an {@link EppResource} from the database by foreign key.
+ *
+ * Returns null if no resource with this foreign key was ever created or if the most recently
+ * created resource was deleted before time "now".
+ */
+ public static Optional loadResource(
+ Class clazz, String foreignKey, Instant now) {
+ // Note: no need to project to "now" because loadResources already does
+ return Optional.ofNullable(
+ loadResources(clazz, ImmutableList.of(foreignKey), now).get(foreignKey));
+ }
+
/**
* Load a map of {@link String} foreign keys to {@link VKey}s to {@link EppResource} that are
* active at or after the specified moment in time.
@@ -110,13 +125,29 @@ public static ImmutableMap> loadKeys(
* or has been soft-deleted.
*/
@SuppressWarnings("unchecked")
+ @Deprecated
public static ImmutableMap loadResources(
Class clazz, Collection foreignKeys, DateTime now) {
return loadMostRecentResourceObjects(clazz, foreignKeys, false).entrySet().stream()
- .filter(e -> now.isBefore(e.getValue().getDeletionTime()))
+ .filter(e -> now.isBefore(e.getValue().getDeletionDateTime()))
.collect(toImmutableMap(Entry::getKey, e -> (E) e.getValue().cloneProjectedAtTime(now)));
}
+ /**
+ * Load a map of {@link String} foreign keys to the {@link EppResource} that are active at or
+ * after the specified moment in time.
+ *
+ * The returned map will omit any foreign keys for which the {@link EppResource} doesn't exist
+ * or has been soft-deleted.
+ */
+ @SuppressWarnings("unchecked")
+ public static ImmutableMap loadResources(
+ Class clazz, Collection foreignKeys, Instant now) {
+ return loadMostRecentResourceObjects(clazz, foreignKeys, false).entrySet().stream()
+ .filter(e -> now.isBefore(e.getValue().getDeletionTime()))
+ .collect(toImmutableMap(Entry::getKey, e -> (E) e.getValue().cloneProjectedAtInstant(now)));
+ }
+
/**
* Helper method to load {@link VKey}s to all the most recent {@link EppResource}s for the given
* foreign keys, regardless of whether they have been soft-deleted.
@@ -397,7 +428,7 @@ public static Optional loadResourceByCache(
return (Optional)
foreignKeyToResourceCache
.get(VKey.create(clazz, foreignKey))
- .filter(e -> now.isBefore(e.getDeletionTime()))
+ .filter(e -> now.isBefore(e.getDeletionDateTime()))
.map(e -> e.cloneProjectedAtTime(now));
}
}
diff --git a/core/src/main/java/google/registry/model/ResourceTransferUtils.java b/core/src/main/java/google/registry/model/ResourceTransferUtils.java
index c6a70026622..7d4bc12c628 100644
--- a/core/src/main/java/google/registry/model/ResourceTransferUtils.java
+++ b/core/src/main/java/google/registry/model/ResourceTransferUtils.java
@@ -50,11 +50,11 @@ public static TransferResponse createTransferResponse(
.setDomainName(domain.getForeignKey())
.setExtendedRegistrationExpirationTime(
ADD_EXDATE_STATUSES.contains(transferData.getTransferStatus())
- ? transferData.getTransferredRegistrationExpirationTime()
+ ? transferData.getTransferredRegistrationExpirationDateTime()
: null)
.setGainingRegistrarId(transferData.getGainingRegistrarId())
.setLosingRegistrarId(transferData.getLosingRegistrarId())
- .setPendingTransferExpirationTime(transferData.getPendingTransferExpirationTime())
+ .setPendingTransferExpirationTime(transferData.getPendingTransferExpirationDateTime())
.setTransferRequestTime(transferData.getTransferRequestTime())
.setTransferStatus(transferData.getTransferStatus())
.build();
diff --git a/core/src/main/java/google/registry/model/billing/BillingCancellation.java b/core/src/main/java/google/registry/model/billing/BillingCancellation.java
index 1adc3a8f163..045e87b956a 100644
--- a/core/src/main/java/google/registry/model/billing/BillingCancellation.java
+++ b/core/src/main/java/google/registry/model/billing/BillingCancellation.java
@@ -104,7 +104,7 @@ public static google.registry.model.billing.BillingCancellation forGracePeriod(
.setRegistrarId(gracePeriod.getRegistrarId())
.setEventTime(eventTime)
// The charge being cancelled will take place at the grace period's expiration time.
- .setBillingTime(gracePeriod.getExpirationTime())
+ .setBillingTime(gracePeriod.getExpirationDateTime())
.setDomainHistoryId(domainHistoryId);
// Set the grace period's billing event using the appropriate Cancellation builder method.
if (gracePeriod.getBillingEvent() != null) {
diff --git a/core/src/main/java/google/registry/model/domain/Domain.java b/core/src/main/java/google/registry/model/domain/Domain.java
index 9a9715243a7..cff00f4db31 100644
--- a/core/src/main/java/google/registry/model/domain/Domain.java
+++ b/core/src/main/java/google/registry/model/domain/Domain.java
@@ -14,6 +14,8 @@
package google.registry.model.domain;
+import static google.registry.util.DateTimeUtils.toInstant;
+
import google.registry.model.EppResource;
import google.registry.model.EppResource.ForeignKeyedEppResource;
import google.registry.model.annotations.ExternalMessagingName;
@@ -37,6 +39,7 @@
import jakarta.persistence.JoinTable;
import jakarta.persistence.OneToMany;
import jakarta.persistence.Table;
+import java.time.Instant;
import java.util.Set;
import org.hibernate.Hibernate;
import org.joda.time.DateTime;
@@ -153,6 +156,11 @@ public VKey createVKey() {
@Override
public Domain cloneProjectedAtTime(final DateTime now) {
+ return cloneDomainProjectedAtTime(this, toInstant(now));
+ }
+
+ @Override
+ public Domain cloneProjectedAtInstant(final Instant now) {
return cloneDomainProjectedAtTime(this, now);
}
diff --git a/core/src/main/java/google/registry/model/domain/DomainBase.java b/core/src/main/java/google/registry/model/domain/DomainBase.java
index 573f5d213ce..1f051b567ee 100644
--- a/core/src/main/java/google/registry/model/domain/DomainBase.java
+++ b/core/src/main/java/google/registry/model/domain/DomainBase.java
@@ -32,9 +32,14 @@
import static google.registry.util.DateTimeUtils.earliestOf;
import static google.registry.util.DateTimeUtils.isBeforeOrAt;
import static google.registry.util.DateTimeUtils.leapSafeAddYears;
+import static google.registry.util.DateTimeUtils.plusYears;
+import static google.registry.util.DateTimeUtils.toDateTime;
+import static google.registry.util.DateTimeUtils.toInstant;
import static google.registry.util.DomainNameUtils.canonicalizeHostname;
import static google.registry.util.DomainNameUtils.getTldFromDomainName;
import static google.registry.util.PreconditionsUtils.checkArgumentNotNull;
+import static java.time.ZoneOffset.UTC;
+import static java.time.temporal.ChronoUnit.YEARS;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSortedSet;
@@ -79,13 +84,13 @@
import jakarta.persistence.Id;
import jakarta.persistence.MappedSuperclass;
import jakarta.persistence.Transient;
+import java.time.Instant;
import java.util.HashSet;
import java.util.Optional;
import java.util.Set;
import javax.annotation.Nullable;
import org.hibernate.collection.spi.PersistentSet;
import org.joda.time.DateTime;
-import org.joda.time.Interval;
/**
* A persistable domain resource including mutable and non-mutable fields.
@@ -285,10 +290,15 @@ public ImmutableSet getSubordinateHosts() {
return nullToEmptyImmutableCopy(subordinateHosts);
}
- public DateTime getRegistrationExpirationTime() {
+ @Deprecated
+ public DateTime getRegistrationExpirationDateTime() {
return registrationExpirationTime;
}
+ public Instant getRegistrationExpirationTime() {
+ return toInstant(registrationExpirationTime);
+ }
+
public VKey getDeletePollMessage() {
return deletePollMessage;
}
@@ -436,6 +446,11 @@ public ImmutableSet getGracePeriodsOfType(GracePeriodStatus gracePe
@Override
public DomainBase cloneProjectedAtTime(final DateTime now) {
+ return cloneDomainProjectedAtTime(this, toInstant(now));
+ }
+
+ @Override
+ public DomainBase cloneProjectedAtInstant(final Instant now) {
return cloneDomainProjectedAtTime(this, now);
}
@@ -444,9 +459,9 @@ public DomainBase cloneProjectedAtTime(final DateTime now) {
* parallels the logic in {@code DomainTransferApproveFlow} which handles explicit client
* approvals.
*/
- static T cloneDomainProjectedAtTime(T domain, DateTime now) {
+ static T cloneDomainProjectedAtTime(T domain, Instant now) {
DomainTransferData transferData = domain.getTransferData();
- DateTime transferExpirationTime = transferData.getPendingTransferExpirationTime();
+ Instant transferExpirationTime = transferData.getPendingTransferExpirationTime();
// If there's a pending transfer that has expired, handle it.
if (TransferStatus.PENDING.equals(transferData.getTransferStatus())
@@ -459,7 +474,7 @@ && isBeforeOrAt(transferExpirationTime, now)) {
T domainAtTransferTime =
cloneDomainProjectedAtTime(domain, transferExpirationTime.minusMillis(1));
- DateTime expirationDate = transferData.getTransferredRegistrationExpirationTime();
+ Instant expirationDate = transferData.getTransferredRegistrationExpirationTime();
if (expirationDate == null) {
// Extend the registration by the correct number of years from the expiration time
// that was current on the domain right before the transfer, capped at 10 years from
@@ -478,7 +493,7 @@ && isBeforeOrAt(transferExpirationTime, now)) {
Builder builder =
domainAtTransferTime
.asBuilder()
- .setRegistrationExpirationTime(expirationDate)
+ .setRegistrationExpirationTime(toDateTime(expirationDate))
// Set the speculatively-written new autorenew events as the domain's autorenew
// events.
.setAutorenewBillingEvent(transferData.getServerApproveAutorenewEvent())
@@ -492,8 +507,8 @@ && isBeforeOrAt(transferExpirationTime, now)) {
GracePeriod.create(
GracePeriodStatus.TRANSFER,
domain.getRepoId(),
- transferExpirationTime.plus(
- Tld.get(domain.getTld()).getTransferGracePeriodLength()),
+ toDateTime(transferExpirationTime)
+ .plus(Tld.get(domain.getTld()).getTransferGracePeriodLength()),
transferData.getGainingRegistrarId(),
transferData.getServerApproveBillingEvent())));
} else {
@@ -503,32 +518,33 @@ && isBeforeOrAt(transferExpirationTime, now)) {
// Set all remaining transfer properties.
setAutomaticTransferSuccessProperties(builder, transferData);
builder
- .setLastEppUpdateTime(transferExpirationTime)
+ .setLastEppUpdateTime(toDateTime(transferExpirationTime))
.setLastEppUpdateRegistrarId(transferData.getGainingRegistrarId());
// Finish projecting to now.
- return (T) builder.build().cloneProjectedAtTime(now);
+ return (T) builder.build().cloneProjectedAtInstant(now);
}
- Optional newLastEppUpdateTime = Optional.empty();
+ Optional newLastEppUpdateTime = Optional.empty();
// There is no transfer. Do any necessary autorenews for active domains.
Builder builder = domain.asBuilder();
if (isBeforeOrAt(domain.getRegistrationExpirationTime(), now)
- && END_OF_TIME.equals(domain.getDeletionTime())) {
+ && END_OF_TIME.equals(domain.getDeletionDateTime())) {
// Autorenew by the number of years between the old expiration time and now.
- DateTime lastAutorenewTime =
+ Instant lastAutorenewTime =
leapSafeAddYears(
domain.getRegistrationExpirationTime(),
- new Interval(domain.getRegistrationExpirationTime(), now).toPeriod().getYears());
- DateTime newExpirationTime = lastAutorenewTime.plusYears(1);
+ YEARS.between(domain.getRegistrationExpirationTime().atZone(UTC), now.atZone(UTC)));
+ Instant newExpirationTime = plusYears(lastAutorenewTime, 1);
builder
- .setRegistrationExpirationTime(newExpirationTime)
+ .setRegistrationExpirationTime(toDateTime(newExpirationTime))
.addGracePeriod(
GracePeriod.createForRecurrence(
GracePeriodStatus.AUTO_RENEW,
domain.getRepoId(),
- lastAutorenewTime.plus(Tld.get(domain.getTld()).getAutoRenewGracePeriodLength()),
+ toDateTime(lastAutorenewTime)
+ .plus(Tld.get(domain.getTld()).getAutoRenewGracePeriodLength()),
domain.getCurrentSponsorRegistrarId(),
domain.getAutorenewBillingEvent()));
newLastEppUpdateTime = Optional.of(lastAutorenewTime);
@@ -551,10 +567,10 @@ && isBeforeOrAt(transferExpirationTime, now)) {
// id, so we have to do the comparison instead of having one variable just storing the most
// recent time.
if (newLastEppUpdateTime.isPresent()) {
- if (domain.getLastEppUpdateTime() == null
+ if (domain.getLastEppUpdateDateTime() == null
|| newLastEppUpdateTime.get().isAfter(domain.getLastEppUpdateTime())) {
builder
- .setLastEppUpdateTime(newLastEppUpdateTime.get())
+ .setLastEppUpdateTime(toDateTime(newLastEppUpdateTime.get()))
.setLastEppUpdateRegistrarId(domain.getCurrentSponsorRegistrarId());
}
}
@@ -567,8 +583,8 @@ && isBeforeOrAt(transferExpirationTime, now)) {
}
/** Return what the expiration time would be if the given number of years were added to it. */
- public static DateTime extendRegistrationWithCap(
- DateTime now, DateTime currentExpirationTime, @Nullable Integer extendedRegistrationYears) {
+ public static Instant extendRegistrationWithCap(
+ Instant now, Instant currentExpirationTime, @Nullable Integer extendedRegistrationYears) {
// We must cap registration at the max years (aka 10), even if that truncates the last year.
return earliestOf(
leapSafeAddYears(
@@ -826,16 +842,16 @@ public B copyFrom(DomainBase domainBase) {
.setDomainName(domainBase.getDomainName())
.setDeletePollMessage(domainBase.getDeletePollMessage())
.setDsData(domainBase.getDsData())
- .setDeletionTime(domainBase.getDeletionTime())
+ .setDeletionTime(domainBase.getDeletionDateTime())
.setGracePeriods(domainBase.getGracePeriods())
.setIdnTableName(domainBase.getIdnTableName())
.setLastTransferTime(domainBase.getLastTransferTime())
.setLaunchNotice(domainBase.getLaunchNotice())
.setLastEppUpdateRegistrarId(domainBase.getLastEppUpdateRegistrarId())
- .setLastEppUpdateTime(domainBase.getLastEppUpdateTime())
+ .setLastEppUpdateTime(domainBase.getLastEppUpdateDateTime())
.setNameservers(domainBase.getNameservers())
.setPersistedCurrentSponsorRegistrarId(domainBase.getPersistedCurrentSponsorRegistrarId())
- .setRegistrationExpirationTime(domainBase.getRegistrationExpirationTime())
+ .setRegistrationExpirationTime(domainBase.getRegistrationExpirationDateTime())
.setRepoId(domainBase.getRepoId())
.setSmdId(domainBase.getSmdId())
.setSubordinateHosts(domainBase.getSubordinateHosts())
diff --git a/core/src/main/java/google/registry/model/domain/GracePeriodBase.java b/core/src/main/java/google/registry/model/domain/GracePeriodBase.java
index a53abe45790..cca7742ed57 100644
--- a/core/src/main/java/google/registry/model/domain/GracePeriodBase.java
+++ b/core/src/main/java/google/registry/model/domain/GracePeriodBase.java
@@ -14,6 +14,8 @@
package google.registry.model.domain;
+import static google.registry.util.DateTimeUtils.toInstant;
+
import google.registry.model.ImmutableObject;
import google.registry.model.UnsafeSerializable;
import google.registry.model.billing.BillingEvent;
@@ -30,6 +32,7 @@
import jakarta.persistence.Enumerated;
import jakarta.persistence.MappedSuperclass;
import jakarta.persistence.Transient;
+import java.time.Instant;
import org.joda.time.DateTime;
/** Base class containing common fields and methods for {@link GracePeriod}. */
@@ -90,10 +93,15 @@ public String getDomainRepoId() {
return domainRepoId;
}
- public DateTime getExpirationTime() {
+ @Deprecated
+ public DateTime getExpirationDateTime() {
return expirationTime;
}
+ public Instant getExpirationTime() {
+ return toInstant(expirationTime);
+ }
+
public String getRegistrarId() {
return clientId;
}
diff --git a/core/src/main/java/google/registry/model/host/HostBase.java b/core/src/main/java/google/registry/model/host/HostBase.java
index 8b70e49fc41..66480452b89 100644
--- a/core/src/main/java/google/registry/model/host/HostBase.java
+++ b/core/src/main/java/google/registry/model/host/HostBase.java
@@ -33,6 +33,7 @@
import jakarta.persistence.Convert;
import jakarta.persistence.MappedSuperclass;
import java.net.InetAddress;
+import java.time.Instant;
import java.util.Optional;
import java.util.Set;
import javax.annotation.Nullable;
@@ -132,6 +133,11 @@ public HostBase cloneProjectedAtTime(DateTime now) {
return this;
}
+ @Override
+ public EppResource cloneProjectedAtInstant(Instant now) {
+ return this;
+ }
+
@Override
public Builder extends HostBase, ?> asBuilder() {
return new Builder<>(clone(this));
@@ -232,13 +238,13 @@ public B setLastTransferTime(DateTime lastTransferTime) {
public B copyFrom(HostBase hostBase) {
return setCreationRegistrarId(hostBase.getCreationRegistrarId())
.setCreationTime(hostBase.getCreationTime())
- .setDeletionTime(hostBase.getDeletionTime())
+ .setDeletionTime(hostBase.getDeletionDateTime())
.setHostName(hostBase.getHostName())
.setInetAddresses(hostBase.getInetAddresses())
.setLastTransferTime(hostBase.getLastTransferTime())
.setLastSuperordinateChange(hostBase.getLastSuperordinateChange())
.setLastEppUpdateRegistrarId(hostBase.getLastEppUpdateRegistrarId())
- .setLastEppUpdateTime(hostBase.getLastEppUpdateTime())
+ .setLastEppUpdateTime(hostBase.getLastEppUpdateDateTime())
.setPersistedCurrentSponsorRegistrarId(hostBase.getPersistedCurrentSponsorRegistrarId())
.setRepoId(hostBase.getRepoId())
.setSuperordinateDomain(hostBase.getSuperordinateDomain())
diff --git a/core/src/main/java/google/registry/model/poll/PollMessage.java b/core/src/main/java/google/registry/model/poll/PollMessage.java
index 2e73951e3f3..16172266164 100644
--- a/core/src/main/java/google/registry/model/poll/PollMessage.java
+++ b/core/src/main/java/google/registry/model/poll/PollMessage.java
@@ -437,7 +437,7 @@ void postLoad() {
.setTransferStatus(transferResponse.getTransferStatus())
.setTransferRequestTime(transferResponse.getTransferRequestTime())
.setPendingTransferExpirationTime(
- transferResponse.getPendingTransferExpirationTime())
+ transferResponse.getPendingTransferExpirationDateTime())
.setExtendedRegistrationExpirationTime(extendedRegistrationExpirationTime)
.build();
}
diff --git a/core/src/main/java/google/registry/model/tld/label/PremiumListDao.java b/core/src/main/java/google/registry/model/tld/label/PremiumListDao.java
index 531eb833650..77e7a2bfb75 100644
--- a/core/src/main/java/google/registry/model/tld/label/PremiumListDao.java
+++ b/core/src/main/java/google/registry/model/tld/label/PremiumListDao.java
@@ -129,7 +129,11 @@ public static Optional getPremiumPrice(String premiumListName, String lab
public static PremiumList save(String name, CurrencyUnit currencyUnit, List inputData) {
checkArgument(!inputData.isEmpty(), "New premium list data cannot be empty");
- return save(PremiumListUtils.parseToPremiumList(name, currencyUnit, inputData));
+ return tm().transact(
+ () ->
+ save(
+ PremiumListUtils.parseToPremiumList(
+ name, currencyUnit, inputData, tm().getTransactionTime())));
}
/** Saves the given premium list (and its premium list entries) to Cloud SQL. */
diff --git a/core/src/main/java/google/registry/model/tld/label/PremiumListUtils.java b/core/src/main/java/google/registry/model/tld/label/PremiumListUtils.java
index d25f9d61dc3..463be206d5f 100644
--- a/core/src/main/java/google/registry/model/tld/label/PremiumListUtils.java
+++ b/core/src/main/java/google/registry/model/tld/label/PremiumListUtils.java
@@ -14,8 +14,6 @@
package google.registry.model.tld.label;
-import static org.joda.time.DateTimeZone.UTC;
-
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
import google.registry.model.tld.label.PremiumList.PremiumEntry;
@@ -29,12 +27,12 @@
public class PremiumListUtils {
public static PremiumList parseToPremiumList(
- String name, CurrencyUnit currencyUnit, List inputData) {
+ String name, CurrencyUnit currencyUnit, List inputData, DateTime creationTime) {
PremiumList partialPremiumList =
new PremiumList.Builder()
.setName(name)
.setCurrency(currencyUnit)
- .setCreationTimestamp(DateTime.now(UTC))
+ .setCreationTimestamp(creationTime)
.build();
ImmutableMap prices = partialPremiumList.parse(inputData);
Map priceAmounts = Maps.transformValues(prices, PremiumEntry::getValue);
diff --git a/core/src/main/java/google/registry/model/tld/label/ReservedList.java b/core/src/main/java/google/registry/model/tld/label/ReservedList.java
index 4020254303e..2f2a0caa750 100644
--- a/core/src/main/java/google/registry/model/tld/label/ReservedList.java
+++ b/core/src/main/java/google/registry/model/tld/label/ReservedList.java
@@ -24,10 +24,10 @@
import static google.registry.persistence.transaction.QueryComposer.Comparator.EQ;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.util.CollectionUtils.nullToEmpty;
-import static org.joda.time.DateTimeZone.UTC;
import com.github.benmanes.caffeine.cache.LoadingCache;
import com.google.common.base.Splitter;
+import com.google.common.base.Stopwatch;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.util.concurrent.UncheckedExecutionException;
@@ -47,7 +47,6 @@
import java.util.Map;
import java.util.Optional;
import javax.annotation.Nullable;
-import org.joda.time.DateTime;
/**
* A list of reserved domain labels that are blocked from being registered for various reasons.
@@ -234,7 +233,7 @@ public static ImmutableSet getReservationTypes(String label, St
*/
private static ImmutableSet getReservedListEntries(
String label, String tldStr) {
- DateTime startTime = DateTime.now(UTC);
+ Stopwatch stopwatch = Stopwatch.createStarted();
Tld tld = Tld.get(checkNotNull(tldStr, "tld must not be null"));
ImmutableSet.Builder entriesBuilder = new ImmutableSet.Builder<>();
ImmutableSet.Builder metricMatchesBuilder =
@@ -253,7 +252,7 @@ private static ImmutableSet getReservedListEntries(
DomainLabelMetrics.recordReservedListCheckOutcome(
tldStr,
metricMatchesBuilder.build(),
- DateTime.now(UTC).getMillis() - startTime.getMillis());
+ stopwatch.elapsed().toMillis());
return entries;
}
diff --git a/core/src/main/java/google/registry/model/transfer/BaseTransferObject.java b/core/src/main/java/google/registry/model/transfer/BaseTransferObject.java
index 9c55b52a1a9..e1a0a04c1bf 100644
--- a/core/src/main/java/google/registry/model/transfer/BaseTransferObject.java
+++ b/core/src/main/java/google/registry/model/transfer/BaseTransferObject.java
@@ -14,6 +14,8 @@
package google.registry.model.transfer;
+import static google.registry.util.DateTimeUtils.toInstant;
+
import google.registry.model.Buildable.GenericBuilder;
import google.registry.model.ImmutableObject;
import google.registry.model.UnsafeSerializable;
@@ -23,6 +25,7 @@
import jakarta.persistence.MappedSuperclass;
import jakarta.xml.bind.annotation.XmlElement;
import jakarta.xml.bind.annotation.XmlTransient;
+import java.time.Instant;
import org.joda.time.DateTime;
/** Fields common to {@link DomainTransferData} and {@link TransferResponse}. */
@@ -73,10 +76,15 @@ public String getLosingRegistrarId() {
return losingClientId;
}
- public DateTime getPendingTransferExpirationTime() {
+ @Deprecated
+ public DateTime getPendingTransferExpirationDateTime() {
return pendingTransferExpirationTime;
}
+ public Instant getPendingTransferExpirationTime() {
+ return toInstant(pendingTransferExpirationTime);
+ }
+
/** Base class for builders of {@link BaseTransferObject} subclasses. */
public abstract static class Builder>
extends GenericBuilder {
diff --git a/core/src/main/java/google/registry/model/transfer/DomainTransferData.java b/core/src/main/java/google/registry/model/transfer/DomainTransferData.java
index 7ecb17e2698..a56c3889d54 100644
--- a/core/src/main/java/google/registry/model/transfer/DomainTransferData.java
+++ b/core/src/main/java/google/registry/model/transfer/DomainTransferData.java
@@ -18,6 +18,7 @@
import static com.google.common.collect.ImmutableList.toImmutableList;
import static google.registry.util.CollectionUtils.isNullOrEmpty;
import static google.registry.util.CollectionUtils.nullToEmpty;
+import static google.registry.util.DateTimeUtils.toInstant;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
@@ -41,6 +42,7 @@
import jakarta.persistence.Convert;
import jakarta.persistence.Embeddable;
import jakarta.persistence.Embedded;
+import java.time.Instant;
import java.util.Set;
import javax.annotation.Nullable;
import org.joda.time.DateTime;
@@ -168,10 +170,16 @@ public Trid getTransferRequestTrid() {
}
@Nullable
- public DateTime getTransferredRegistrationExpirationTime() {
+ @Deprecated
+ public DateTime getTransferredRegistrationExpirationDateTime() {
return transferredRegistrationExpirationTime;
}
+ @Nullable
+ public Instant getTransferredRegistrationExpirationTime() {
+ return toInstant(transferredRegistrationExpirationTime);
+ }
+
@Nullable
public VKey getServerApproveBillingEvent() {
return serverApproveBillingEvent;
diff --git a/core/src/main/java/google/registry/persistence/transaction/JpaTransactionManagerImpl.java b/core/src/main/java/google/registry/persistence/transaction/JpaTransactionManagerImpl.java
index f1633b7c189..4502a7d39e7 100644
--- a/core/src/main/java/google/registry/persistence/transaction/JpaTransactionManagerImpl.java
+++ b/core/src/main/java/google/registry/persistence/transaction/JpaTransactionManagerImpl.java
@@ -21,6 +21,7 @@
import static com.google.common.collect.ImmutableSet.toImmutableSet;
import static google.registry.config.RegistryConfig.getHibernateAllowNestedTransactions;
import static google.registry.persistence.transaction.DatabaseException.throwIfSqlException;
+import static google.registry.util.DateTimeUtils.toDateTime;
import static google.registry.util.PreconditionsUtils.checkArgumentNotNull;
import static java.util.AbstractMap.SimpleEntry;
import static java.util.stream.Collectors.joining;
@@ -61,6 +62,7 @@
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
+import java.time.Instant;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
@@ -340,6 +342,11 @@ public TransactionIsolationLevel getCurrentTransactionIsolationLevel() {
@Override
public DateTime getTransactionTime() {
+ return toDateTime(getTxTime());
+ }
+
+ @Override
+ public Instant getTxTime() {
assertInTransaction();
TransactionInfo txnInfo = transactionInfo.get();
if (txnInfo.transactionTime == null) {
@@ -746,7 +753,7 @@ private T detach(@Nullable T entity) {
private static class TransactionInfo {
EntityManager entityManager;
boolean inTransaction = false;
- DateTime transactionTime;
+ Instant transactionTime;
Supplier idProvider;
// The set of entity objects that have been either persisted (via insert()) or merged (via
@@ -759,7 +766,7 @@ private static class TransactionInfo {
private void start(Clock clock, Supplier idProvider) {
checkArgumentNotNull(clock);
inTransaction = true;
- transactionTime = clock.nowUtc();
+ transactionTime = clock.now();
this.idProvider = idProvider;
}
diff --git a/core/src/main/java/google/registry/persistence/transaction/TransactionManager.java b/core/src/main/java/google/registry/persistence/transaction/TransactionManager.java
index 8cd63befe80..aa49bb9b784 100644
--- a/core/src/main/java/google/registry/persistence/transaction/TransactionManager.java
+++ b/core/src/main/java/google/registry/persistence/transaction/TransactionManager.java
@@ -20,6 +20,7 @@
import google.registry.model.ImmutableObject;
import google.registry.persistence.PersistenceModule.TransactionIsolationLevel;
import google.registry.persistence.VKey;
+import java.time.Instant;
import java.util.NoSuchElementException;
import java.util.Optional;
import java.util.concurrent.Callable;
@@ -129,8 +130,12 @@ public interface TransactionManager {
void reTransact(ThrowingRunnable work);
/** Returns the time associated with the start of this particular transaction attempt. */
+ @Deprecated
DateTime getTransactionTime();
+ /** Returns the Instant associated with the start of this particular transaction attempt. */
+ Instant getTxTime();
+
/** Persists a new entity in the database, throws exception if the entity already exists. */
void insert(Object entity);
diff --git a/core/src/main/java/google/registry/rdap/RdapActionBase.java b/core/src/main/java/google/registry/rdap/RdapActionBase.java
index 2b23be75044..94804bf0a17 100644
--- a/core/src/main/java/google/registry/rdap/RdapActionBase.java
+++ b/core/src/main/java/google/registry/rdap/RdapActionBase.java
@@ -17,6 +17,7 @@
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.net.HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN;
import static google.registry.request.Actions.getPathForAction;
+import static google.registry.util.DateTimeUtils.toInstant;
import static google.registry.util.DomainNameUtils.canonicalizeHostname;
import static jakarta.servlet.http.HttpServletResponse.SC_BAD_REQUEST;
import static jakarta.servlet.http.HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
@@ -241,7 +242,7 @@ DeletedItemHandling getDeletedItemHandling() {
* is authorized to do so.
*/
boolean isAuthorized(EppResource eppResource) {
- return getRequestTime().isBefore(eppResource.getDeletionTime())
+ return toInstant(getRequestTime()).isBefore(eppResource.getDeletionTime())
|| (shouldIncludeDeleted()
&& rdapAuthorization.isAuthorizedForRegistrar(
eppResource.getPersistedCurrentSponsorRegistrarId()));
diff --git a/core/src/main/java/google/registry/rdap/RdapJsonFormatter.java b/core/src/main/java/google/registry/rdap/RdapJsonFormatter.java
index 131c22f2f54..30047c3bda6 100644
--- a/core/src/main/java/google/registry/rdap/RdapJsonFormatter.java
+++ b/core/src/main/java/google/registry/rdap/RdapJsonFormatter.java
@@ -317,7 +317,7 @@ RdapDomain createRdapDomain(Domain domain, OutputDataType outputDataType) {
.build(),
Event.builder()
.setEventAction(EventAction.EXPIRATION)
- .setEventDate(domain.getRegistrationExpirationTime())
+ .setEventDate(domain.getRegistrationExpirationDateTime())
.build(),
// RDAP response profile section 1.5:
// The topmost object in the RDAP response MUST contain an event of "eventAction" type
@@ -358,7 +358,7 @@ RdapDomain createRdapDomain(Domain domain, OutputDataType outputDataType) {
makeStatusValueList(
allStatusValues,
false, // isRedacted
- domain.getDeletionTime().isBefore(getRequestTime()));
+ domain.getDeletionDateTime().isBefore(getRequestTime()));
builder.statusBuilder().addAll(status);
if (status.isEmpty()) {
logger.atWarning().log(
@@ -438,7 +438,7 @@ && replicaTm()
makeStatusValueList(
statuses.build(),
false, // isRedacted
- host.getDeletionTime().isBefore(getRequestTime())));
+ host.getDeletionDateTime().isBefore(getRequestTime())));
}
// For query responses - we MUST have all the ip addresses: RDAP Response Profile 4.2.
@@ -752,7 +752,9 @@ private ImmutableList makeOptionalEvents(EppResource resource) {
ImmutableList.Builder eventsBuilder = new ImmutableList.Builder<>();
DateTime creationTime = resource.getCreationTime();
DateTime lastChangeTime =
- resource.getLastEppUpdateTime() == null ? creationTime : resource.getLastEppUpdateTime();
+ resource.getLastEppUpdateDateTime() == null
+ ? creationTime
+ : resource.getLastEppUpdateDateTime();
// The order of the elements is stable - it's the order in which the enum elements are defined
// in EventAction
for (EventAction rdapEventAction : EventAction.values()) {
diff --git a/core/src/main/java/google/registry/rde/DomainToXjcConverter.java b/core/src/main/java/google/registry/rde/DomainToXjcConverter.java
index fe671a28def..89f4be1a01d 100644
--- a/core/src/main/java/google/registry/rde/DomainToXjcConverter.java
+++ b/core/src/main/java/google/registry/rde/DomainToXjcConverter.java
@@ -94,13 +94,13 @@ static XjcRdeDomain convertDomain(Domain model, RdeMode mode) {
// identifying the end (expiration) of the domain name object's
// registration period. This element MUST be present if the domain
// name has been allocated.
- bean.setExDate(model.getRegistrationExpirationTime());
+ bean.setExDate(model.getRegistrationExpirationDateTime());
// o An OPTIONAL element that contains the date and time of
// the most recent domain-name-object modification. This element
// MUST NOT be present if the domain name object has never been
// modified.
- bean.setUpDate(model.getLastEppUpdateTime());
+ bean.setUpDate(model.getLastEppUpdateDateTime());
// o An OPTIONAL element that contains the identifier of the
// registrar that last updated the domain name object. This element
@@ -228,8 +228,8 @@ private static XjcRdeDomainTransferDataType convertTransferData(DomainTransferDa
bean.setReRr(RdeUtils.makeXjcRdeRrType(model.getGainingRegistrarId()));
bean.setAcRr(RdeUtils.makeXjcRdeRrType(model.getLosingRegistrarId()));
bean.setReDate(model.getTransferRequestTime());
- bean.setAcDate(model.getPendingTransferExpirationTime());
- bean.setExDate(model.getTransferredRegistrationExpirationTime());
+ bean.setAcDate(model.getPendingTransferExpirationDateTime());
+ bean.setExDate(model.getTransferredRegistrationExpirationDateTime());
return bean;
}
diff --git a/core/src/main/java/google/registry/rde/HostToXjcConverter.java b/core/src/main/java/google/registry/rde/HostToXjcConverter.java
index 3f75703ee55..f822871aa2c 100644
--- a/core/src/main/java/google/registry/rde/HostToXjcConverter.java
+++ b/core/src/main/java/google/registry/rde/HostToXjcConverter.java
@@ -70,7 +70,7 @@ private static XjcRdeHost convertHostCommon(
bean.setName(model.getHostName());
bean.setRoid(model.getRepoId());
bean.setCrDate(model.getCreationTime());
- bean.setUpDate(model.getLastEppUpdateTime());
+ bean.setUpDate(model.getLastEppUpdateDateTime());
bean.setCrRr(RdeAdapter.convertRr(model.getCreationRegistrarId(), null));
bean.setUpRr(RdeAdapter.convertRr(model.getLastEppUpdateRegistrarId(), null));
bean.setCrRr(RdeAdapter.convertRr(model.getCreationRegistrarId(), null));
diff --git a/core/src/main/java/google/registry/tools/CreateAnchorTenantCommand.java b/core/src/main/java/google/registry/tools/CreateAnchorTenantCommand.java
index 4e392cb162c..c48da2a8c05 100644
--- a/core/src/main/java/google/registry/tools/CreateAnchorTenantCommand.java
+++ b/core/src/main/java/google/registry/tools/CreateAnchorTenantCommand.java
@@ -19,18 +19,17 @@
import static google.registry.model.tld.Tlds.findTldForNameOrThrow;
import static google.registry.pricing.PricingEngineProxy.getDomainCreateCost;
import static google.registry.util.StringGenerator.DEFAULT_PASSWORD_LENGTH;
-import static org.joda.time.DateTimeZone.UTC;
import com.beust.jcommander.Parameter;
import com.beust.jcommander.Parameters;
import com.google.common.net.InternetDomainName;
import com.google.template.soy.data.SoyMapData;
import google.registry.tools.soy.CreateAnchorTenantSoyInfo;
+import google.registry.util.Clock;
import google.registry.util.StringGenerator;
import jakarta.inject.Inject;
import jakarta.inject.Named;
import org.joda.money.Money;
-import org.joda.time.DateTime;
/** A command to create a new anchor tenant domain. */
@Parameters(separators = " =", commandDescription = "Provision a domain for an anchor tenant.")
@@ -76,6 +75,8 @@ final class CreateAnchorTenantCommand extends MutatingEppToolCommand {
@Named("base64StringGenerator")
StringGenerator passwordGenerator;
+ @Inject Clock clock;
+
@Override
protected void initMutatingEppToolCommand() {
checkArgument(superuser, "This command must be run as a superuser.");
@@ -86,7 +87,7 @@ protected void initMutatingEppToolCommand() {
Money cost = null;
if (fee) {
- cost = getDomainCreateCost(domainName, DateTime.now(UTC), DEFAULT_ANCHOR_TENANT_PERIOD_YEARS);
+ cost = getDomainCreateCost(domainName, clock.nowUtc(), DEFAULT_ANCHOR_TENANT_PERIOD_YEARS);
}
setSoyTemplate(CreateAnchorTenantSoyInfo.getInstance(),
diff --git a/core/src/main/java/google/registry/tools/CreateDomainCommand.java b/core/src/main/java/google/registry/tools/CreateDomainCommand.java
index 101e5017727..a9f32807d21 100644
--- a/core/src/main/java/google/registry/tools/CreateDomainCommand.java
+++ b/core/src/main/java/google/registry/tools/CreateDomainCommand.java
@@ -17,18 +17,17 @@
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Strings.isNullOrEmpty;
import static google.registry.pricing.PricingEngineProxy.getPricesForDomainName;
-import static org.joda.time.DateTimeZone.UTC;
import com.beust.jcommander.Parameter;
import com.beust.jcommander.Parameters;
import com.google.template.soy.data.SoyMapData;
import google.registry.model.pricing.PremiumPricingEngine.DomainPrices;
import google.registry.tools.soy.DomainCreateSoyInfo;
+import google.registry.util.Clock;
import google.registry.util.StringGenerator;
import jakarta.inject.Inject;
import jakarta.inject.Named;
import org.joda.money.Money;
-import org.joda.time.DateTime;
/** A command to create a new domain via EPP. */
@Parameters(separators = " =", commandDescription = "Create a new domain via EPP.")
@@ -53,6 +52,8 @@ final class CreateDomainCommand extends CreateOrUpdateDomainCommand {
@Named("base64StringGenerator")
StringGenerator passwordGenerator;
+ @Inject Clock clock;
+
private static final int PASSWORD_LENGTH = 16;
@Override
@@ -64,7 +65,7 @@ protected void initMutatingEppToolCommand() {
for (String domain : domains) {
String currency = null;
String cost = null;
- DomainPrices prices = getPricesForDomainName(domain, DateTime.now(UTC));
+ DomainPrices prices = getPricesForDomainName(domain, clock.nowUtc());
// Check if the domain is premium and set the fee on the create command if so.
if (prices.isPremium()) {
diff --git a/core/src/main/java/google/registry/tools/CreateOrUpdateRegistrarCommand.java b/core/src/main/java/google/registry/tools/CreateOrUpdateRegistrarCommand.java
index 469cd2c027f..f8a4f619d7d 100644
--- a/core/src/main/java/google/registry/tools/CreateOrUpdateRegistrarCommand.java
+++ b/core/src/main/java/google/registry/tools/CreateOrUpdateRegistrarCommand.java
@@ -21,7 +21,6 @@
import static com.google.common.collect.ImmutableSet.toImmutableSet;
import static google.registry.util.RegistrarUtils.normalizeRegistrarName;
import static java.nio.charset.StandardCharsets.US_ASCII;
-import static org.joda.time.DateTimeZone.UTC;
import com.beust.jcommander.Parameter;
import com.google.common.base.Ascii;
@@ -37,6 +36,7 @@
import google.registry.tools.params.PathParameter.InputFile;
import google.registry.tools.params.StringListParameter;
import google.registry.util.CidrAddressBlock;
+import google.registry.util.Clock;
import jakarta.inject.Inject;
import java.nio.file.Files;
import java.nio.file.Path;
@@ -56,6 +56,8 @@ abstract class CreateOrUpdateRegistrarCommand extends MutatingCommand {
@Inject CertificateChecker certificateChecker;
+ @Inject Clock clock;
+
@Parameter(description = "Client identifier of the registrar account", required = true)
List mainParameters;
@@ -272,7 +274,7 @@ protected void initRegistrarCommand() {}
@Override
protected final void init() throws Exception {
initRegistrarCommand();
- DateTime now = DateTime.now(UTC);
+ DateTime now = clock.nowUtc();
for (String clientId : mainParameters) {
Registrar oldRegistrar = getOldRegistrar(clientId);
Registrar.Builder builder =
diff --git a/core/src/main/java/google/registry/tools/CreateReservedListCommand.java b/core/src/main/java/google/registry/tools/CreateReservedListCommand.java
index 7cbe44c3572..878e8ebf8dc 100644
--- a/core/src/main/java/google/registry/tools/CreateReservedListCommand.java
+++ b/core/src/main/java/google/registry/tools/CreateReservedListCommand.java
@@ -18,7 +18,6 @@
import static google.registry.model.tld.Tlds.assertTldExists;
import static google.registry.util.ListNamingUtils.convertFilePathToName;
import static java.nio.charset.StandardCharsets.UTF_8;
-import static org.joda.time.DateTimeZone.UTC;
import com.beust.jcommander.Parameter;
import com.beust.jcommander.Parameters;
@@ -26,6 +25,8 @@
import com.google.common.base.Splitter;
import com.google.common.base.Strings;
import google.registry.model.tld.label.ReservedList;
+import google.registry.util.Clock;
+import jakarta.inject.Inject;
import java.nio.file.Files;
import java.util.List;
import org.joda.time.DateTime;
@@ -34,6 +35,8 @@
@Parameters(separators = " =", commandDescription = "Create a ReservedList.")
final class CreateReservedListCommand extends CreateOrUpdateReservedListCommand {
+ @Inject Clock clock;
+
@VisibleForTesting
static final String INVALID_FORMAT_ERROR_MESSAGE =
"The name must be in the format {tld|common}_list-name "
@@ -51,7 +54,7 @@ protected String prompt() throws Exception {
if (!override) {
validateListName(name);
}
- DateTime now = DateTime.now(UTC);
+ DateTime now = clock.nowUtc();
List allLines = Files.readAllLines(input, UTF_8);
reservedList =
new ReservedList.Builder()
diff --git a/core/src/main/java/google/registry/tools/GenerateDnsReportCommand.java b/core/src/main/java/google/registry/tools/GenerateDnsReportCommand.java
index f4aad1d544a..88e0a367901 100644
--- a/core/src/main/java/google/registry/tools/GenerateDnsReportCommand.java
+++ b/core/src/main/java/google/registry/tools/GenerateDnsReportCommand.java
@@ -81,7 +81,7 @@ String generate() {
.list());
for (Domain domain : domains) {
// Skip deleted domains and domains that don't get published to DNS.
- if (isBeforeOrAt(domain.getDeletionTime(), now) || !domain.shouldPublishToDns()) {
+ if (isBeforeOrAt(domain.getDeletionDateTime(), now) || !domain.shouldPublishToDns()) {
continue;
}
write(domain);
@@ -90,7 +90,7 @@ String generate() {
Iterable nameservers = tm().transact(() -> tm().loadAllOf(Host.class));
for (Host nameserver : nameservers) {
// Skip deleted hosts and external hosts.
- if (isBeforeOrAt(nameserver.getDeletionTime(), now)
+ if (isBeforeOrAt(nameserver.getDeletionDateTime(), now)
|| nameserver.getInetAddresses().isEmpty()) {
continue;
}
diff --git a/core/src/main/java/google/registry/tools/GenerateZoneFilesCommand.java b/core/src/main/java/google/registry/tools/GenerateZoneFilesCommand.java
index b08ca56f482..6fd1fb55f49 100644
--- a/core/src/main/java/google/registry/tools/GenerateZoneFilesCommand.java
+++ b/core/src/main/java/google/registry/tools/GenerateZoneFilesCommand.java
@@ -15,7 +15,6 @@
package google.registry.tools;
import static google.registry.model.tld.Tlds.assertTldsExist;
-import static org.joda.time.DateTimeZone.UTC;
import static org.joda.time.Duration.standardMinutes;
import com.beust.jcommander.Parameter;
@@ -23,6 +22,8 @@
import com.google.common.collect.ImmutableMap;
import google.registry.tools.params.DateParameter;
import google.registry.tools.server.GenerateZoneFilesAction;
+import google.registry.util.Clock;
+import jakarta.inject.Inject;
import java.io.IOException;
import java.util.List;
import java.util.Map;
@@ -43,7 +44,9 @@ final class GenerateZoneFilesCommand implements CommandWithConnection {
description = "The date to generate the file for (defaults to today, or yesterday if run "
+ "before 00:02).",
validateWith = DateParameter.class)
- private DateTime exportDate = DateTime.now(UTC).minus(standardMinutes(2)).withTimeAtStartOfDay();
+ private DateTime exportDate;
+
+ @Inject Clock clock;
private ServiceConnection connection;
@@ -54,6 +57,9 @@ public void setConnection(ServiceConnection connection) {
@Override
public void run() throws IOException {
+ if (exportDate == null) {
+ exportDate = clock.nowUtc().minus(standardMinutes(2)).withTimeAtStartOfDay();
+ }
assertTldsExist(mainParameters);
ImmutableMap params = ImmutableMap.of(
"tlds", mainParameters,
diff --git a/core/src/main/java/google/registry/tools/GetHistoryEntriesCommand.java b/core/src/main/java/google/registry/tools/GetHistoryEntriesCommand.java
index 394cbc702df..9c2938d0573 100644
--- a/core/src/main/java/google/registry/tools/GetHistoryEntriesCommand.java
+++ b/core/src/main/java/google/registry/tools/GetHistoryEntriesCommand.java
@@ -17,7 +17,6 @@
import static com.google.common.base.Preconditions.checkArgument;
import static google.registry.util.DateTimeUtils.END_OF_TIME;
import static google.registry.util.DateTimeUtils.START_OF_TIME;
-import static org.joda.time.DateTimeZone.UTC;
import com.beust.jcommander.Parameter;
import com.beust.jcommander.Parameters;
@@ -26,7 +25,9 @@
import google.registry.model.reporting.HistoryEntryDao;
import google.registry.persistence.VKey;
import google.registry.tools.CommandUtilities.ResourceType;
+import google.registry.util.Clock;
import google.registry.xml.XmlTransformer;
+import jakarta.inject.Inject;
import org.joda.time.DateTime;
/** Command to show history entries. */
@@ -35,6 +36,8 @@
commandDescription = "Show history entries that occurred in a given time range")
final class GetHistoryEntriesCommand implements Command {
+ @Inject Clock clock;
+
@Parameter(
names = {"-a", "--after"},
description = "Only show history entries that occurred at or after this time")
@@ -58,7 +61,7 @@ public void run() {
checkArgument(
type != null && uniqueId != null,
"If either of 'type' or 'id' are set then both must be");
- VKey extends EppResource> parentKey = type.getKey(uniqueId, DateTime.now(UTC));
+ VKey extends EppResource> parentKey = type.getKey(uniqueId, clock.nowUtc());
historyEntries = HistoryEntryDao.loadHistoryObjectsForResource(parentKey, after, before);
} else {
historyEntries = HistoryEntryDao.loadAllHistoryObjects(after, before);
diff --git a/core/src/main/java/google/registry/tools/RenewDomainCommand.java b/core/src/main/java/google/registry/tools/RenewDomainCommand.java
index 81f26263454..838db13ce5d 100644
--- a/core/src/main/java/google/registry/tools/RenewDomainCommand.java
+++ b/core/src/main/java/google/registry/tools/RenewDomainCommand.java
@@ -81,7 +81,7 @@ protected void initMutatingEppToolCommand()
SoyMapData soyMapData =
new SoyMapData(
"domainName", domain.getDomainName(),
- "expirationDate", domain.getRegistrationExpirationTime().toString(DATE_FORMATTER),
+ "expirationDate", domain.getRegistrationExpirationDateTime().toString(DATE_FORMATTER),
"period", String.valueOf(period));
if (requestedByRegistrar != null) {
diff --git a/core/src/main/java/google/registry/tools/UniformRapidSuspensionCommand.java b/core/src/main/java/google/registry/tools/UniformRapidSuspensionCommand.java
index 1f3368ef2c4..77290a85292 100644
--- a/core/src/main/java/google/registry/tools/UniformRapidSuspensionCommand.java
+++ b/core/src/main/java/google/registry/tools/UniformRapidSuspensionCommand.java
@@ -163,7 +163,7 @@ protected void initMutatingEppToolCommand()
domain.getDomainName(),
"expirationDate",
domain
- .getRegistrationExpirationTime()
+ .getRegistrationExpirationDateTime()
.toString(DateTimeFormat.forPattern("YYYY-MM-dd")),
// period is the number of years to renew the registration for
"period",
diff --git a/core/src/main/java/google/registry/tools/UnrenewDomainCommand.java b/core/src/main/java/google/registry/tools/UnrenewDomainCommand.java
index 29613a8ecaa..06866ebca3e 100644
--- a/core/src/main/java/google/registry/tools/UnrenewDomainCommand.java
+++ b/core/src/main/java/google/registry/tools/UnrenewDomainCommand.java
@@ -99,8 +99,9 @@ protected void init() throws UnsupportedEncodingException {
domainsWithDisallowedStatusesBuilder.putAll(
domainName, Sets.intersection(domain.get().getStatusValues(), DISALLOWED_STATUSES));
if (isBeforeOrAt(
- leapSafeSubtractYears(domain.get().getRegistrationExpirationTime(), period), now)) {
- domainsExpiringTooSoonBuilder.put(domainName, domain.get().getRegistrationExpirationTime());
+ leapSafeSubtractYears(domain.get().getRegistrationExpirationDateTime(), period), now)) {
+ domainsExpiringTooSoonBuilder.put(
+ domainName, domain.get().getRegistrationExpirationDateTime());
}
}
@@ -143,7 +144,7 @@ protected String prompt() {
DateTime now = clock.nowUtc();
for (String domainName : mainParameters) {
Domain domain = ForeignKeyUtils.loadResource(Domain.class, domainName, now).get();
- DateTime previousTime = domain.getRegistrationExpirationTime();
+ DateTime previousTime = domain.getRegistrationExpirationDateTime();
DateTime newTime = leapSafeSubtractYears(previousTime, period);
resultBuilder.append(
String.format(
@@ -179,12 +180,12 @@ private void unrenewDomain(String domainName) {
"Domain %s has prohibited status values",
domainName);
checkState(
- leapSafeSubtractYears(domain.getRegistrationExpirationTime(), period).isAfter(now),
+ leapSafeSubtractYears(domain.getRegistrationExpirationDateTime(), period).isAfter(now),
"Domain %s expires too soon",
domainName);
DateTime newExpirationTime =
- leapSafeSubtractYears(domain.getRegistrationExpirationTime(), period);
+ leapSafeSubtractYears(domain.getRegistrationExpirationDateTime(), period);
DomainHistory domainHistory =
new DomainHistory.Builder()
.setDomain(domain)
diff --git a/core/src/main/java/google/registry/tools/UpdatePremiumListCommand.java b/core/src/main/java/google/registry/tools/UpdatePremiumListCommand.java
index 4e8d7ed3169..8c04977164c 100644
--- a/core/src/main/java/google/registry/tools/UpdatePremiumListCommand.java
+++ b/core/src/main/java/google/registry/tools/UpdatePremiumListCommand.java
@@ -24,12 +24,16 @@
import google.registry.model.tld.label.PremiumList;
import google.registry.model.tld.label.PremiumListDao;
import google.registry.model.tld.label.PremiumListUtils;
+import google.registry.util.Clock;
+import jakarta.inject.Inject;
import java.nio.file.Files;
/** Command to safely update {@link PremiumList} in Database for a given TLD. */
@Parameters(separators = " =", commandDescription = "Update a PremiumList in Database.")
class UpdatePremiumListCommand extends CreateOrUpdatePremiumListCommand {
+ @Inject Clock clock;
+
@Parameter(
names = {"-d", "--dry_run"},
description = "Does not execute the entity mutation")
@@ -62,7 +66,8 @@ protected String prompt() throws Exception {
inputData = Files.readAllLines(inputFile, UTF_8);
checkArgument(!inputData.isEmpty(), "New premium list data cannot be empty");
currency = existingList.getCurrency();
- PremiumList updatedPremiumList = PremiumListUtils.parseToPremiumList(name, currency, inputData);
+ PremiumList updatedPremiumList =
+ PremiumListUtils.parseToPremiumList(name, currency, inputData, clock.nowUtc());
if (!existingList
.getLabelsToPrices()
.entrySet()
diff --git a/core/src/main/java/google/registry/tools/UpdateRecurrenceCommand.java b/core/src/main/java/google/registry/tools/UpdateRecurrenceCommand.java
index 87120148275..73a300ae885 100644
--- a/core/src/main/java/google/registry/tools/UpdateRecurrenceCommand.java
+++ b/core/src/main/java/google/registry/tools/UpdateRecurrenceCommand.java
@@ -16,7 +16,9 @@
import static com.google.common.base.Preconditions.checkArgument;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
+import static google.registry.util.DateTimeUtils.END_INSTANT;
import static google.registry.util.DateTimeUtils.END_OF_TIME;
+import static google.registry.util.DateTimeUtils.toDateTime;
import com.beust.jcommander.Parameter;
import com.beust.jcommander.Parameters;
@@ -31,6 +33,7 @@
import google.registry.model.reporting.HistoryEntry;
import google.registry.model.reporting.HistoryEntry.HistoryEntryId;
import google.registry.model.transfer.TransferStatus;
+import java.time.Instant;
import java.util.List;
import java.util.Optional;
import javax.annotation.Nullable;
@@ -161,7 +164,7 @@ private ImmutableList internalExecute() {
private ImmutableMap loadDomainsAndRecurrences() {
ImmutableMap.Builder result = new ImmutableMap.Builder<>();
- DateTime now = tm().getTransactionTime();
+ Instant now = tm().getTxTime();
for (String domainName : mainParameters) {
Domain domain =
ForeignKeyUtils.loadResource(Domain.class, domainName, now)
@@ -171,7 +174,7 @@ private ImmutableMap loadDomainsAndRecurrences() {
String.format(
"Domain %s does not exist or has been deleted", domainName)));
checkArgument(
- domain.getDeletionTime().equals(END_OF_TIME),
+ domain.getDeletionTime().equals(END_INSTANT),
"Domain %s has already had a deletion time set",
domainName);
checkArgument(
@@ -184,7 +187,7 @@ private ImmutableMap loadDomainsAndRecurrences() {
domainAutorenewEndTime.ifPresent(
endTime ->
checkArgument(
- endTime.isAfter(now),
+ endTime.isAfter(toDateTime(now)),
"Domain %s autorenew ended prior to now at %s",
domainName,
endTime));
diff --git a/core/src/main/java/google/registry/ui/server/console/ConsoleDumDownloadAction.java b/core/src/main/java/google/registry/ui/server/console/ConsoleDumDownloadAction.java
index e056d116ad0..c609a7d023b 100644
--- a/core/src/main/java/google/registry/ui/server/console/ConsoleDumDownloadAction.java
+++ b/core/src/main/java/google/registry/ui/server/console/ConsoleDumDownloadAction.java
@@ -16,7 +16,6 @@
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.request.Action.Method.GET;
-import static org.joda.time.DateTimeZone.UTC;
import com.google.common.collect.ImmutableList;
import com.google.common.flogger.FluentLogger;
@@ -35,7 +34,6 @@
import java.io.IOException;
import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVPrinter;
-import org.joda.time.DateTime;
@Action(
service = Service.CONSOLE,
@@ -86,7 +84,7 @@ protected void getHandler(User user) {
.setHeader("Cache-Control", "max-age=86400"); // 86400 seconds = 1 day
consoleApiParams
.response()
- .setDateHeader("Expires", DateTime.now(UTC).withTimeAtStartOfDay().plusDays(1));
+ .setDateHeader("Expires", clock.nowUtc().withTimeAtStartOfDay().plusDays(1));
try (var writer = consoleApiParams.response().getWriter()) {
CSVPrinter csvPrinter = new CSVPrinter(writer, CSVFormat.DEFAULT);
diff --git a/core/src/test/java/google/registry/batch/DeleteExpiredDomainsActionTest.java b/core/src/test/java/google/registry/batch/DeleteExpiredDomainsActionTest.java
index 6fe8694964c..0315dedd67f 100644
--- a/core/src/test/java/google/registry/batch/DeleteExpiredDomainsActionTest.java
+++ b/core/src/test/java/google/registry/batch/DeleteExpiredDomainsActionTest.java
@@ -24,6 +24,7 @@
import static google.registry.testing.DatabaseHelper.persistActiveDomain;
import static google.registry.testing.DatabaseHelper.persistResource;
import static google.registry.util.DateTimeUtils.END_OF_TIME;
+import static google.registry.util.DateTimeUtils.plusDays;
import com.google.common.collect.ImmutableSet;
import google.registry.flows.DaggerEppTestComponent;
@@ -117,7 +118,7 @@ void test_deletesOnlyExpiredDomain() {
assertThat(loadByEntity(notYetExpiredDomain)).isEqualTo(notYetExpiredDomain);
Domain reloadedExpiredDomain = loadByEntity(pendingExpirationDomain);
assertThat(reloadedExpiredDomain.getStatusValues()).contains(PENDING_DELETE);
- assertThat(reloadedExpiredDomain.getDeletionTime()).isEqualTo(clock.nowUtc().plusDays(35));
+ assertThat(reloadedExpiredDomain.getDeletionTime()).isEqualTo(plusDays(clock.now(), 35));
}
@Test
diff --git a/core/src/test/java/google/registry/batch/DeleteProberDataActionTest.java b/core/src/test/java/google/registry/batch/DeleteProberDataActionTest.java
index 9c11baa01d4..7304c07adbc 100644
--- a/core/src/test/java/google/registry/batch/DeleteProberDataActionTest.java
+++ b/core/src/test/java/google/registry/batch/DeleteProberDataActionTest.java
@@ -26,7 +26,7 @@
import static google.registry.testing.DatabaseHelper.persistDeletedDomain;
import static google.registry.testing.DatabaseHelper.persistDomainAsDeleted;
import static google.registry.testing.DatabaseHelper.persistResource;
-import static google.registry.util.DateTimeUtils.END_OF_TIME;
+import static google.registry.util.DateTimeUtils.END_INSTANT;
import static org.joda.time.DateTimeZone.UTC;
import static org.junit.jupiter.api.Assertions.assertThrows;
@@ -45,8 +45,10 @@
import google.registry.persistence.transaction.JpaTestExtensions;
import google.registry.persistence.transaction.JpaTestExtensions.JpaIntegrationTestExtension;
import google.registry.testing.DatabaseHelper;
+import google.registry.testing.FakeClock;
import google.registry.testing.SystemPropertyExtension;
import google.registry.util.RegistryEnvironment;
+import java.time.Instant;
import java.util.Optional;
import java.util.Set;
import org.joda.money.Money;
@@ -61,9 +63,11 @@ class DeleteProberDataActionTest {
private static final DateTime DELETION_TIME = DateTime.parse("2010-01-01T00:00:00.000Z");
+ private final FakeClock clock = new FakeClock(DateTime.now(UTC));
+
@RegisterExtension
final JpaIntegrationTestExtension jpa =
- new JpaTestExtensions.Builder().buildIntegrationTestExtension();
+ new JpaTestExtensions.Builder().withClock(clock).buildIntegrationTestExtension();
@RegisterExtension
final SystemPropertyExtension systemPropertyExtension = new SystemPropertyExtension();
@@ -93,7 +97,9 @@ void beforeEach() {
}
private void resetAction() {
- action = new DeleteProberDataAction(false, ImmutableSet.of(), Optional.empty(), "TheRegistrar");
+ action =
+ new DeleteProberDataAction(
+ false, ImmutableSet.of(), Optional.empty(), "TheRegistrar", clock);
}
@AfterEach
@@ -123,7 +129,8 @@ void test_deletesAllInBatches() throws Exception {
Set oaEntities = persistLotsOfDomains("oa-canary.test");
// Create action with batch size of 3
DeleteProberDataAction batchedAction =
- new DeleteProberDataAction(false, ImmutableSet.of(), Optional.of(3), "TheRegistrar");
+ new DeleteProberDataAction(
+ false, ImmutableSet.of(), Optional.of(3), "TheRegistrar", clock);
batchedAction.run();
assertAllAbsent(ibEntities);
assertAllAbsent(oaEntities);
@@ -201,7 +208,7 @@ void testSuccess_activeDomain_isSoftDeleted() throws Exception {
.setCreationTimeForTest(DateTime.now(UTC).minusYears(1))
.build());
action.run();
- DateTime timeAfterDeletion = DateTime.now(UTC);
+ Instant timeAfterDeletion = Instant.now();
assertThat(ForeignKeyUtils.loadResource(Domain.class, "blah.ib-any.test", timeAfterDeletion))
.isEmpty();
assertThat(loadByEntity(domain).getDeletionTime()).isLessThan(timeAfterDeletion);
@@ -217,7 +224,7 @@ void testSuccess_activeDomain_doubleMapSoftDeletes() throws Exception {
.setCreationTimeForTest(DateTime.now(UTC).minusYears(1))
.build());
action.run();
- DateTime timeAfterDeletion = DateTime.now(UTC);
+ Instant timeAfterDeletion = Instant.now();
resetAction();
action.run();
assertThat(ForeignKeyUtils.loadResource(Domain.class, "blah.ib-any.test", timeAfterDeletion))
@@ -237,7 +244,7 @@ void test_recentlyCreatedDomain_isntDeletedYet() throws Exception {
Optional domain =
ForeignKeyUtils.loadResource(Domain.class, "blah.ib-any.test", DateTime.now(UTC));
assertThat(domain).isPresent();
- assertThat(domain.get().getDeletionTime()).isEqualTo(END_OF_TIME);
+ assertThat(domain.get().getDeletionTime()).isEqualTo(END_INSTANT);
}
@Test
@@ -250,7 +257,7 @@ void testDryRun_doesntSoftDeleteData() throws Exception {
.build());
action.isDryRun = true;
action.run();
- assertThat(loadByEntity(domain).getDeletionTime()).isEqualTo(END_OF_TIME);
+ assertThat(loadByEntity(domain).getDeletionTime()).isEqualTo(END_INSTANT);
}
@Test
diff --git a/core/src/test/java/google/registry/batch/SendExpiringCertificateNotificationEmailActionTest.java b/core/src/test/java/google/registry/batch/SendExpiringCertificateNotificationEmailActionTest.java
index d944a3e0953..42ac0ff4a6a 100644
--- a/core/src/test/java/google/registry/batch/SendExpiringCertificateNotificationEmailActionTest.java
+++ b/core/src/test/java/google/registry/batch/SendExpiringCertificateNotificationEmailActionTest.java
@@ -97,7 +97,8 @@ void beforeEach() throws Exception {
EXPIRATION_WARNING_EMAIL_SUBJECT_TEXT,
sendEmailService,
certificateChecker,
- response);
+ response,
+ clock);
sampleRegistrar =
persistResource(createRegistrar("clientId", "sampleRegistrar", null, null).build());
diff --git a/core/src/test/java/google/registry/beam/resave/ResaveAllEppResourcesPipelineTest.java b/core/src/test/java/google/registry/beam/resave/ResaveAllEppResourcesPipelineTest.java
index c87216be024..b9d8f59a547 100644
--- a/core/src/test/java/google/registry/beam/resave/ResaveAllEppResourcesPipelineTest.java
+++ b/core/src/test/java/google/registry/beam/resave/ResaveAllEppResourcesPipelineTest.java
@@ -25,6 +25,8 @@
import static google.registry.testing.DatabaseHelper.persistDomainWithDependentResources;
import static google.registry.testing.DatabaseHelper.persistDomainWithPendingTransfer;
import static google.registry.testing.DatabaseHelper.persistNewRegistrars;
+import static google.registry.util.DateTimeUtils.plusYears;
+import static google.registry.util.DateTimeUtils.toInstant;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
@@ -113,11 +115,12 @@ void testPipeline_autorenewedDomain() {
DateTime now = fakeClock.nowUtc();
Domain domain =
persistDomainWithDependentResources("domain", "tld", now, now, now.plusYears(1));
- assertThat(domain.getRegistrationExpirationTime()).isEqualTo(now.plusYears(1));
+ assertThat(domain.getRegistrationExpirationTime()).isEqualTo(plusYears(toInstant(now), 1));
fakeClock.advanceBy(Duration.standardDays(500));
runPipeline();
Domain postPipeline = loadByEntity(domain);
- assertThat(postPipeline.getRegistrationExpirationTime()).isEqualTo(now.plusYears(2));
+ assertThat(postPipeline.getRegistrationExpirationTime())
+ .isEqualTo(plusYears(toInstant(now), 2));
}
@Test
diff --git a/core/src/test/java/google/registry/flows/EppLifecycleDomainTest.java b/core/src/test/java/google/registry/flows/EppLifecycleDomainTest.java
index fb45f347354..3d3540ab885 100644
--- a/core/src/test/java/google/registry/flows/EppLifecycleDomainTest.java
+++ b/core/src/test/java/google/registry/flows/EppLifecycleDomainTest.java
@@ -488,7 +488,7 @@ void testDomainDeletion_outsideAddGracePeriod_showsRedemptionPeriod() throws Exc
// Make sure that in the future, the domain expiration is unchanged after deletion
Domain clonedDomain = domain.cloneProjectedAtTime(deleteTime.plusYears(5));
- assertThat(clonedDomain.getRegistrationExpirationTime()).isEqualTo(createTime.plusYears(2));
+ assertThat(clonedDomain.getRegistrationExpirationDateTime()).isEqualTo(createTime.plusYears(2));
}
@Test
diff --git a/core/src/test/java/google/registry/flows/FlowTestCase.java b/core/src/test/java/google/registry/flows/FlowTestCase.java
index ba2b31f61af..4daf414b2d1 100644
--- a/core/src/test/java/google/registry/flows/FlowTestCase.java
+++ b/core/src/test/java/google/registry/flows/FlowTestCase.java
@@ -182,7 +182,7 @@ private static ImmutableMap canonicalizeGracePeriods(
GracePeriod.create(
entry.getKey().getType(),
entry.getKey().getDomainRepoId(),
- entry.getKey().getExpirationTime(),
+ entry.getKey().getExpirationDateTime(),
entry.getKey().getRegistrarId(),
null,
1L),
diff --git a/core/src/test/java/google/registry/flows/domain/DomainCreateFlowTest.java b/core/src/test/java/google/registry/flows/domain/DomainCreateFlowTest.java
index f1ae4f4855f..6c402def637 100644
--- a/core/src/test/java/google/registry/flows/domain/DomainCreateFlowTest.java
+++ b/core/src/test/java/google/registry/flows/domain/DomainCreateFlowTest.java
@@ -361,7 +361,7 @@ private void assertSuccessfulCreate(
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
.setTargetId(getUniqueIdFromCommand())
.setRegistrarId("TheRegistrar")
- .setEventTime(domain.getRegistrationExpirationTime())
+ .setEventTime(domain.getRegistrationExpirationDateTime())
.setRecurrenceEndTime(END_OF_TIME)
.setDomainHistory(historyEntry)
.setRenewalPriceBehavior(expectedRenewalPriceBehavior)
@@ -397,7 +397,7 @@ private void assertSuccessfulCreate(
new PollMessage.Autorenew.Builder()
.setTargetId(domain.getDomainName())
.setRegistrarId("TheRegistrar")
- .setEventTime(domain.getRegistrationExpirationTime())
+ .setEventTime(domain.getRegistrationExpirationDateTime())
.setMsg("Domain was auto-renewed.")
.setHistoryEntry(historyEntry)
.build());
@@ -1720,7 +1720,7 @@ private void assertPollMessagesWithCollisionOneTime(Domain domain) {
new PollMessage.Autorenew.Builder()
.setTargetId(domain.getDomainName())
.setRegistrarId("TheRegistrar")
- .setEventTime(domain.getRegistrationExpirationTime())
+ .setEventTime(domain.getRegistrationExpirationDateTime())
.setMsg("Domain was auto-renewed.")
.setHistoryEntry(historyEntry)
.build(),
@@ -1853,7 +1853,7 @@ void testSuccess_customLogicIsCalled_andSavesExtraEntity() throws Exception {
new PollMessage.Autorenew.Builder()
.setTargetId(domain.getDomainName())
.setRegistrarId("TheRegistrar")
- .setEventTime(domain.getRegistrationExpirationTime())
+ .setEventTime(domain.getRegistrationExpirationDateTime())
.setMsg("Domain was auto-renewed.")
.setHistoryEntry(historyEntry)
.build(),
diff --git a/core/src/test/java/google/registry/flows/domain/DomainDeleteFlowTest.java b/core/src/test/java/google/registry/flows/domain/DomainDeleteFlowTest.java
index 223293b1f5f..9b3b2060b58 100644
--- a/core/src/test/java/google/registry/flows/domain/DomainDeleteFlowTest.java
+++ b/core/src/test/java/google/registry/flows/domain/DomainDeleteFlowTest.java
@@ -376,7 +376,7 @@ void testSuccess_updatedEppUpdateTimeAfterPendingRedemption() throws Exception {
runFlowAssertResponse(loadFile("domain_delete_response_pending.xml"));
Domain domain = reloadResourceByForeignKey();
- DateTime redemptionEndTime = domain.getLastEppUpdateTime().plusDays(3);
+ DateTime redemptionEndTime = domain.getLastEppUpdateDateTime().plusDays(3);
Domain domainAtRedemptionTime = domain.cloneProjectedAtTime(redemptionEndTime);
assertAboutDomains()
.that(domainAtRedemptionTime)
@@ -418,7 +418,7 @@ private void doSuccessfulTest_noAddGracePeriod(
null));
// We should see exactly one poll message, which is for the autorenew 1 month in the future.
assertPollMessages(createAutorenewPollMessage("TheRegistrar").build());
- DateTime expectedExpirationTime = domain.getRegistrationExpirationTime().minusYears(2);
+ DateTime expectedExpirationTime = domain.getRegistrationExpirationDateTime().minusYears(2);
clock.advanceOneMilli();
runFlowAssertResponse(loadFile(responseFilename, substitutions));
Domain resource = reloadResourceByForeignKey();
@@ -462,7 +462,7 @@ private void assertDeletionPollMessageFor(Domain domain, String expectedMessage)
// There should be a future poll message at the deletion time. The previous autorenew poll
// message should now be deleted.
assertAboutDomains().that(domain).hasDeletePollMessage();
- DateTime deletionTime = domain.getDeletionTime();
+ DateTime deletionTime = domain.getDeletionDateTime();
assertThat(getPollMessages("TheRegistrar", deletionTime.minusMinutes(1))).isEmpty();
assertThat(getPollMessages("TheRegistrar", deletionTime)).hasSize(1);
assertThat(domain.getDeletePollMessage())
@@ -496,7 +496,7 @@ void testSuccess_autorenewPollMessageIsNotDeleted() throws Exception {
runFlowAssertResponse(loadFile("domain_delete_response_pending.xml"));
// There should now be two poll messages; one for the delete of the domain (in the future), and
// another for the unacked autorenew messages.
- DateTime deletionTime = reloadResourceByForeignKey().getDeletionTime();
+ DateTime deletionTime = reloadResourceByForeignKey().getDeletionDateTime();
assertThat(getPollMessages("TheRegistrar", deletionTime.minusMinutes(1))).hasSize(1);
assertThat(getPollMessages("TheRegistrar", deletionTime)).hasSize(2);
}
@@ -613,7 +613,7 @@ void testSuccess_pendingTransfer() throws Exception {
.isEqualTo(Trid.create("transferClient-trid", "transferServer-trid"));
assertThat(panData.getActionResult()).isFalse();
// There should be a future poll message to the losing registrar at the deletion time.
- DateTime deletionTime = domain.getDeletionTime();
+ DateTime deletionTime = domain.getDeletionDateTime();
assertThat(getPollMessages("TheRegistrar", deletionTime.minusMinutes(1))).isEmpty();
assertThat(getPollMessages("TheRegistrar", deletionTime)).hasSize(1);
assertOnlyBillingEventIsClosedAutorenew("TheRegistrar");
diff --git a/core/src/test/java/google/registry/flows/domain/DomainRenewFlowTest.java b/core/src/test/java/google/registry/flows/domain/DomainRenewFlowTest.java
index 6694e221d74..cdbb9e478fd 100644
--- a/core/src/test/java/google/registry/flows/domain/DomainRenewFlowTest.java
+++ b/core/src/test/java/google/registry/flows/domain/DomainRenewFlowTest.java
@@ -247,7 +247,7 @@ private void doSuccessfulTest(
@Nullable Money renewalPrice)
throws Exception {
assertMutatingFlow(true);
- DateTime currentExpiration = reloadResourceByForeignKey().getRegistrationExpirationTime();
+ DateTime currentExpiration = reloadResourceByForeignKey().getRegistrationExpirationDateTime();
DateTime newExpiration = currentExpiration.plusYears(renewalYears);
runFlowAssertResponse(
CommitMode.LIVE, userPrivileges, loadFile(responseFilename, substitutions));
@@ -303,7 +303,7 @@ private void doSuccessfulTest(
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
.setTargetId(getUniqueIdFromCommand())
.setRegistrarId("TheRegistrar")
- .setEventTime(domain.getRegistrationExpirationTime())
+ .setEventTime(domain.getRegistrationExpirationDateTime())
.setRecurrenceEndTime(END_OF_TIME)
.setDomainHistory(historyEntryDomainRenew)
.build());
@@ -313,7 +313,7 @@ private void doSuccessfulTest(
new PollMessage.Autorenew.Builder()
.setTargetId(getUniqueIdFromCommand())
.setRegistrarId("TheRegistrar")
- .setEventTime(domain.getRegistrationExpirationTime())
+ .setEventTime(domain.getRegistrationExpirationDateTime())
.setAutorenewEndTime(END_OF_TIME)
.setMsg("Domain was auto-renewed.")
.setHistoryEntry(historyEntryDomainRenew)
@@ -817,7 +817,7 @@ void testSuccess_autorenewPollMessageIsNotDeleted() throws Exception {
new PollMessage.Autorenew.Builder()
.setTargetId(getUniqueIdFromCommand())
.setRegistrarId("TheRegistrar")
- .setEventTime(reloadResourceByForeignKey().getRegistrationExpirationTime())
+ .setEventTime(reloadResourceByForeignKey().getRegistrationExpirationDateTime())
.setAutorenewEndTime(END_OF_TIME)
.setMsg("Domain was auto-renewed.")
.setHistoryEntry(historyEntryDomainRenew)
diff --git a/core/src/test/java/google/registry/flows/domain/DomainRestoreRequestFlowTest.java b/core/src/test/java/google/registry/flows/domain/DomainRestoreRequestFlowTest.java
index 69c28ee896a..35eeb139945 100644
--- a/core/src/test/java/google/registry/flows/domain/DomainRestoreRequestFlowTest.java
+++ b/core/src/test/java/google/registry/flows/domain/DomainRestoreRequestFlowTest.java
@@ -201,7 +201,7 @@ void testSuccess_expiryStillInFuture_notExtended() throws Exception {
new PollMessage.Autorenew.Builder()
.setTargetId("example.tld")
.setRegistrarId("TheRegistrar")
- .setEventTime(domain.getRegistrationExpirationTime())
+ .setEventTime(domain.getRegistrationExpirationDateTime())
.setAutorenewEndTime(END_OF_TIME)
.setMsg("Domain was auto-renewed.")
.setHistoryEntry(historyEntryDomainRestore)
@@ -269,7 +269,7 @@ void testSuccess_expiryInPast_extendedByOneYear() throws Exception {
new PollMessage.Autorenew.Builder()
.setTargetId("example.tld")
.setRegistrarId("TheRegistrar")
- .setEventTime(domain.getRegistrationExpirationTime())
+ .setEventTime(domain.getRegistrationExpirationDateTime())
.setAutorenewEndTime(END_OF_TIME)
.setMsg("Domain was auto-renewed.")
.setHistoryEntry(historyEntryDomainRestore)
diff --git a/core/src/test/java/google/registry/flows/domain/DomainTransferApproveFlowTest.java b/core/src/test/java/google/registry/flows/domain/DomainTransferApproveFlowTest.java
index aafa9387236..30a9339e3a2 100644
--- a/core/src/test/java/google/registry/flows/domain/DomainTransferApproveFlowTest.java
+++ b/core/src/test/java/google/registry/flows/domain/DomainTransferApproveFlowTest.java
@@ -148,7 +148,8 @@ private void assertTransferApproved(Domain domain, DomainTransferData oldTransfe
.copyConstantFieldsToBuilder()
.setTransferStatus(TransferStatus.CLIENT_APPROVED)
.setPendingTransferExpirationTime(clock.nowUtc())
- .setTransferredRegistrationExpirationTime(domain.getRegistrationExpirationTime())
+ .setTransferredRegistrationExpirationTime(
+ domain.getRegistrationExpirationDateTime())
.build());
}
@@ -216,7 +217,7 @@ private void runSuccessfulFlowWithAssertions(
// should be one at the current time to the gaining registrar, as well as one at the domain's
// autorenew time.
assertThat(getPollMessages(domain, "NewRegistrar", clock.nowUtc().plusMonths(1))).hasSize(1);
- assertThat(getPollMessages(domain, "NewRegistrar", domain.getRegistrationExpirationTime()))
+ assertThat(getPollMessages(domain, "NewRegistrar", domain.getRegistrationExpirationDateTime()))
.hasSize(2);
PollMessage gainingTransferPollMessage =
@@ -225,11 +226,11 @@ private void runSuccessfulFlowWithAssertions(
getOnlyPollMessage(
domain,
"NewRegistrar",
- domain.getRegistrationExpirationTime(),
+ domain.getRegistrationExpirationDateTime(),
PollMessage.Autorenew.class);
assertThat(gainingTransferPollMessage.getEventTime()).isEqualTo(clock.nowUtc());
assertThat(gainingAutorenewPollMessage.getEventTime())
- .isEqualTo(domain.getRegistrationExpirationTime());
+ .isEqualTo(domain.getRegistrationExpirationDateTime());
DomainTransferResponse transferResponse =
gainingTransferPollMessage
.getResponseData()
@@ -239,7 +240,7 @@ private void runSuccessfulFlowWithAssertions(
.collect(onlyElement());
assertThat(transferResponse.getTransferStatus()).isEqualTo(TransferStatus.CLIENT_APPROVED);
assertThat(transferResponse.getExtendedRegistrationExpirationTime())
- .isEqualTo(domain.getRegistrationExpirationTime());
+ .isEqualTo(domain.getRegistrationExpirationDateTime());
PendingActionNotificationResponse panData =
gainingTransferPollMessage
.getResponseData()
@@ -294,9 +295,9 @@ private void assertHistoryEntriesContainBillingEventsAndGracePeriods(
.build(),
getGainingClientAutorenewEvent()
.asBuilder()
- .setEventTime(domain.getRegistrationExpirationTime())
+ .setEventTime(domain.getRegistrationExpirationDateTime())
.setRecurrenceLastExpansion(
- domain.getRegistrationExpirationTime().minusYears(1))
+ domain.getRegistrationExpirationDateTime().minusYears(1))
.setDomainHistory(historyEntryTransferApproved)
.build()))
.toArray(BillingBase[]::new));
@@ -332,9 +333,9 @@ private void assertHistoryEntriesDoNotContainTransferBillingEventsOrGracePeriods
.build(),
getGainingClientAutorenewEvent()
.asBuilder()
- .setEventTime(domain.getRegistrationExpirationTime())
+ .setEventTime(domain.getRegistrationExpirationDateTime())
.setRecurrenceLastExpansion(
- domain.getRegistrationExpirationTime().minusYears(1))
+ domain.getRegistrationExpirationDateTime().minusYears(1))
.setDomainHistory(historyEntryTransferApproved)
.build()))
.toArray(BillingBase[]::new));
@@ -349,7 +350,7 @@ private void doSuccessfulTest(String tld, String commandFilename, String expecte
tld,
commandFilename,
expectedXmlFilename,
- domain.getRegistrationExpirationTime().plusYears(1),
+ domain.getRegistrationExpirationDateTime().plusYears(1),
1);
}
@@ -821,7 +822,7 @@ void testSuccess_superuserExtension_transferPeriodZero() throws Exception {
"tld",
"domain_transfer_approve.xml",
"domain_transfer_approve_response_zero_period.xml",
- domain.getRegistrationExpirationTime());
+ domain.getRegistrationExpirationDateTime());
assertHistoryEntriesDoNotContainTransferBillingEventsOrGracePeriods();
}
@@ -854,7 +855,7 @@ void testSuccess_superuserExtension_transferPeriodZero_autorenewGraceActive() th
"tld",
"domain_transfer_approve.xml",
"domain_transfer_approve_response_zero_period_autorenew_grace.xml",
- domain.getRegistrationExpirationTime());
+ domain.getRegistrationExpirationDateTime());
assertHistoryEntriesDoNotContainTransferBillingEventsOrGracePeriods();
}
diff --git a/core/src/test/java/google/registry/flows/domain/DomainTransferCancelFlowTest.java b/core/src/test/java/google/registry/flows/domain/DomainTransferCancelFlowTest.java
index c7b62116bb8..ea5ff9e16c3 100644
--- a/core/src/test/java/google/registry/flows/domain/DomainTransferCancelFlowTest.java
+++ b/core/src/test/java/google/registry/flows/domain/DomainTransferCancelFlowTest.java
@@ -114,7 +114,7 @@ private void doSuccessfulTest(String commandFilename) throws Exception {
// Setup done; run the test.
assertMutatingFlow(true);
- DateTime originalExpirationTime = domain.getRegistrationExpirationTime();
+ DateTime originalExpirationTime = domain.getRegistrationExpirationDateTime();
ImmutableSet originalGracePeriods = domain.getGracePeriods();
DomainTransferData originalTransferData = domain.getTransferData();
runFlowAssertResponse(loadFile("domain_transfer_cancel_response.xml"));
diff --git a/core/src/test/java/google/registry/flows/domain/DomainTransferQueryFlowTest.java b/core/src/test/java/google/registry/flows/domain/DomainTransferQueryFlowTest.java
index 523120f4ade..b96a4f41223 100644
--- a/core/src/test/java/google/registry/flows/domain/DomainTransferQueryFlowTest.java
+++ b/core/src/test/java/google/registry/flows/domain/DomainTransferQueryFlowTest.java
@@ -143,7 +143,8 @@ void testSuccess_tenYears() throws Exception {
persistResource(
domain
.asBuilder()
- .setRegistrationExpirationTime(domain.getRegistrationExpirationTime().plusYears(9))
+ .setRegistrationExpirationTime(
+ domain.getRegistrationExpirationDateTime().plusYears(9))
.build());
doSuccessfulTest("domain_transfer_query.xml", "domain_transfer_query_response_10_years.xml", 1);
}
@@ -233,7 +234,7 @@ void testSuccess_serverApproved_afterAutorenews() throws Exception {
// Set the clock to just past the extended registration time. We'd expect the domain to have
// auto-renewed once, but the transfer query response should be the same.
clock.setTo(EXTENDED_REGISTRATION_EXPIRATION_TIME.plusMillis(1));
- assertThat(domain.cloneProjectedAtTime(clock.nowUtc()).getRegistrationExpirationTime())
+ assertThat(domain.cloneProjectedAtTime(clock.nowUtc()).getRegistrationExpirationDateTime())
.isEqualTo(EXTENDED_REGISTRATION_EXPIRATION_TIME.plusYears(1));
doSuccessfulTest(
"domain_transfer_query.xml", "domain_transfer_query_response_server_approved.xml", 2);
diff --git a/core/src/test/java/google/registry/flows/domain/DomainTransferRejectFlowTest.java b/core/src/test/java/google/registry/flows/domain/DomainTransferRejectFlowTest.java
index f26b460d497..e3bac621677 100644
--- a/core/src/test/java/google/registry/flows/domain/DomainTransferRejectFlowTest.java
+++ b/core/src/test/java/google/registry/flows/domain/DomainTransferRejectFlowTest.java
@@ -88,7 +88,7 @@ private void doSuccessfulTest(String commandFilename, String expectedXmlFilename
assertThat(getPollMessages("TheRegistrar", clock.nowUtc().plusMonths(1))).hasSize(1);
// Setup done; run the test.
assertMutatingFlow(true);
- DateTime originalExpirationTime = domain.getRegistrationExpirationTime();
+ DateTime originalExpirationTime = domain.getRegistrationExpirationDateTime();
ImmutableSet originalGracePeriods = domain.getGracePeriods();
DomainTransferData originalTransferData = domain.getTransferData();
runFlowAssertResponse(loadFile(expectedXmlFilename));
diff --git a/core/src/test/java/google/registry/flows/domain/DomainTransferRequestFlowTest.java b/core/src/test/java/google/registry/flows/domain/DomainTransferRequestFlowTest.java
index 70ad4517e37..7afa97cd697 100644
--- a/core/src/test/java/google/registry/flows/domain/DomainTransferRequestFlowTest.java
+++ b/core/src/test/java/google/registry/flows/domain/DomainTransferRequestFlowTest.java
@@ -244,7 +244,8 @@ private void assertTransferApproved(
.setTransferPeriod(expectedPeriod)
.setTransferStatus(TransferStatus.SERVER_APPROVED)
.setPendingTransferExpirationTime(automaticTransferTime)
- .setTransferredRegistrationExpirationTime(domain.getRegistrationExpirationTime())
+ .setTransferredRegistrationExpirationTime(
+ domain.getRegistrationExpirationDateTime())
// Server-approve entity fields should all be nulled out.
.build());
}
@@ -542,7 +543,7 @@ private void doSuccessfulTest(
doSuccessfulTest(
commandFilename,
expectedXmlFilename,
- domain.getRegistrationExpirationTime().plusYears(1),
+ domain.getRegistrationExpirationDateTime().plusYears(1),
substitutions,
Optional.empty());
}
@@ -551,7 +552,9 @@ private void doSuccessfulTest(String commandFilename, String expectedXmlFilename
throws Exception {
clock.advanceOneMilli();
doSuccessfulTest(
- commandFilename, expectedXmlFilename, domain.getRegistrationExpirationTime().plusYears(1));
+ commandFilename,
+ expectedXmlFilename,
+ domain.getRegistrationExpirationDateTime().plusYears(1));
}
private void doSuccessfulSuperuserExtensionTest(
@@ -812,7 +815,7 @@ void testSuccess_superuserExtension_zeroPeriod_nonZeroAutomaticTransferLength()
doSuccessfulSuperuserExtensionTest(
"domain_transfer_request_superuser_extension.xml",
"domain_transfer_request_response_su_ext_zero_period_nonzero_transfer_length.xml",
- domain.getRegistrationExpirationTime().plusYears(0),
+ domain.getRegistrationExpirationDateTime().plusYears(0),
ImmutableMap.of("PERIOD", "0", "AUTOMATIC_TRANSFER_LENGTH", "5"),
Optional.empty(),
Period.create(0, Unit.YEARS),
@@ -826,7 +829,7 @@ void testSuccess_superuserExtension_zeroPeriod_zeroAutomaticTransferLength() thr
doSuccessfulSuperuserExtensionTest(
"domain_transfer_request_superuser_extension.xml",
"domain_transfer_request_response_su_ext_zero_period_zero_transfer_length.xml",
- domain.getRegistrationExpirationTime().plusYears(0),
+ domain.getRegistrationExpirationDateTime().plusYears(0),
ImmutableMap.of("PERIOD", "0", "AUTOMATIC_TRANSFER_LENGTH", "0"),
Optional.empty(),
Period.create(0, Unit.YEARS),
@@ -841,7 +844,7 @@ void testSuccess_superuserExtension_nonZeroPeriod_nonZeroAutomaticTransferLength
doSuccessfulSuperuserExtensionTest(
"domain_transfer_request_superuser_extension.xml",
"domain_transfer_request_response_su_ext_one_year_period_nonzero_transfer_length.xml",
- domain.getRegistrationExpirationTime().plusYears(1),
+ domain.getRegistrationExpirationDateTime().plusYears(1),
ImmutableMap.of("PERIOD", "1", "AUTOMATIC_TRANSFER_LENGTH", "5"),
Optional.empty(),
Period.create(1, Unit.YEARS),
@@ -873,7 +876,7 @@ void testSuccess_superuserExtension_zeroPeriod_autorenewGraceActive() throws Exc
doSuccessfulSuperuserExtensionTest(
"domain_transfer_request_superuser_extension.xml",
"domain_transfer_request_response_su_ext_zero_period_autorenew_grace.xml",
- domain.getRegistrationExpirationTime(),
+ domain.getRegistrationExpirationDateTime(),
ImmutableMap.of("PERIOD", "0", "AUTOMATIC_TRANSFER_LENGTH", "0"),
Optional.empty(),
Period.create(0, Unit.YEARS),
@@ -922,7 +925,7 @@ void testSuccess_superuserExtension_clientTransferProhibited() throws Exception
doSuccessfulSuperuserExtensionTest(
"domain_transfer_request_superuser_extension.xml",
"domain_transfer_request_response_su_ext_zero_period_zero_transfer_length.xml",
- domain.getRegistrationExpirationTime().plusYears(0),
+ domain.getRegistrationExpirationDateTime().plusYears(0),
ImmutableMap.of("PERIOD", "0", "AUTOMATIC_TRANSFER_LENGTH", "0"),
Optional.empty(),
Period.create(0, Unit.YEARS),
@@ -939,7 +942,7 @@ void testSuccess_superuserExtension_serverTransferProhibited() throws Exception
doSuccessfulSuperuserExtensionTest(
"domain_transfer_request_superuser_extension.xml",
"domain_transfer_request_response_su_ext_zero_period_zero_transfer_length.xml",
- domain.getRegistrationExpirationTime().plusYears(0),
+ domain.getRegistrationExpirationDateTime().plusYears(0),
ImmutableMap.of("PERIOD", "0", "AUTOMATIC_TRANSFER_LENGTH", "0"),
Optional.empty(),
Period.create(0, Unit.YEARS),
@@ -977,7 +980,7 @@ void testSuccess_customLogicFee_std_v1() throws Exception {
doSuccessfulTest(
"domain_transfer_request_separate_fees.xml",
"domain_transfer_request_response_fees.xml",
- domain.getRegistrationExpirationTime().plusYears(1),
+ domain.getRegistrationExpirationDateTime().plusYears(1),
new ImmutableMap.Builder()
.put("DOMAIN", "expensive-domain.foo")
.put("YEARS", "1")
@@ -1409,7 +1412,7 @@ void testSuccess_bulkPricingName_zeroPeriod() throws Exception {
doSuccessfulSuperuserExtensionTest(
"domain_transfer_request_superuser_extension.xml",
"domain_transfer_request_response_su_ext_zero_period_zero_transfer_length.xml",
- domain.getRegistrationExpirationTime().plusYears(0),
+ domain.getRegistrationExpirationDateTime().plusYears(0),
ImmutableMap.of("PERIOD", "0", "AUTOMATIC_TRANSFER_LENGTH", "0"),
Optional.empty(),
Period.create(0, Unit.YEARS),
@@ -2024,7 +2027,7 @@ void testSuccess_customLogicFee_v06() throws Exception {
doSuccessfulTest(
"domain_transfer_request_separate_fees.xml",
"domain_transfer_request_response_fees.xml",
- domain.getRegistrationExpirationTime().plusYears(1),
+ domain.getRegistrationExpirationDateTime().plusYears(1),
new ImmutableMap.Builder()
.put("DOMAIN", "expensive-domain.foo")
.put("YEARS", "1")
diff --git a/core/src/test/java/google/registry/flows/host/HostUpdateFlowTest.java b/core/src/test/java/google/registry/flows/host/HostUpdateFlowTest.java
index 084cd41924b..2103b06d441 100644
--- a/core/src/test/java/google/registry/flows/host/HostUpdateFlowTest.java
+++ b/core/src/test/java/google/registry/flows/host/HostUpdateFlowTest.java
@@ -256,7 +256,7 @@ void testSuccess_nameUnchanged_superordinateDomainWasTransferred() throws Except
.and()
.hasPersistedCurrentSponsorRegistrarId("NewRegistrar")
.and()
- .hasLastTransferTime(domain.getTransferData().getPendingTransferExpirationTime())
+ .hasLastTransferTime(domain.getTransferData().getPendingTransferExpirationDateTime())
.and()
.hasOnlyOneHistoryEntryWhich()
.hasType(HistoryEntry.Type.HOST_UPDATE);
diff --git a/core/src/test/java/google/registry/model/domain/DomainTest.java b/core/src/test/java/google/registry/model/domain/DomainTest.java
index e6e81d9a1df..ad04eb1d088 100644
--- a/core/src/test/java/google/registry/model/domain/DomainTest.java
+++ b/core/src/test/java/google/registry/model/domain/DomainTest.java
@@ -31,6 +31,10 @@
import static google.registry.testing.SqlHelper.saveRegistrar;
import static google.registry.util.DateTimeUtils.END_OF_TIME;
import static google.registry.util.DateTimeUtils.START_OF_TIME;
+import static google.registry.util.DateTimeUtils.minusDays;
+import static google.registry.util.DateTimeUtils.plusDays;
+import static google.registry.util.DateTimeUtils.plusYears;
+import static google.registry.util.DateTimeUtils.toDateTime;
import static org.joda.money.CurrencyUnit.USD;
import static org.joda.time.DateTimeZone.UTC;
import static org.junit.jupiter.api.Assertions.assertThrows;
@@ -67,6 +71,8 @@
import google.registry.persistence.transaction.JpaTestExtensions.JpaIntegrationWithCoverageExtension;
import google.registry.testing.DatabaseHelper;
import google.registry.testing.FakeClock;
+import java.time.Instant;
+import java.time.ZoneOffset;
import java.util.Optional;
import org.joda.money.Money;
import org.joda.time.DateTime;
@@ -386,7 +392,7 @@ private void assertTransferred(
.isEqualTo(TransferStatus.SERVER_APPROVED);
assertThat(domain.getCurrentSponsorRegistrarId()).isEqualTo("TheRegistrar");
assertThat(domain.getLastTransferTime()).isEqualTo(fakeClock.nowUtc().plusDays(1));
- assertThat(domain.getRegistrationExpirationTime()).isEqualTo(newExpirationTime);
+ assertThat(domain.getRegistrationExpirationDateTime()).isEqualTo(newExpirationTime);
assertThat(domain.getAutorenewBillingEvent()).isEqualTo(newAutorenewEvent);
}
@@ -479,56 +485,57 @@ void testExpiredTransfer_autoRenewBeforeTransfer() {
}
private void setupPendingTransferDomain(
- DateTime oldExpirationTime, DateTime transferRequestTime, DateTime transferSuccessTime) {
+ Instant oldExpirationTime, Instant transferRequestTime, Instant transferSuccessTime) {
domain =
domain
.asBuilder()
- .setRegistrationExpirationTime(oldExpirationTime)
+ .setRegistrationExpirationTime(toDateTime(oldExpirationTime))
.setTransferData(
domain
.getTransferData()
.asBuilder()
.setTransferStatus(TransferStatus.PENDING)
- .setTransferRequestTime(transferRequestTime)
- .setPendingTransferExpirationTime(transferSuccessTime)
+ .setTransferRequestTime(toDateTime(transferRequestTime))
+ .setPendingTransferExpirationTime(toDateTime(transferSuccessTime))
.build())
- .setLastEppUpdateTime(transferRequestTime)
+ .setLastEppUpdateTime(toDateTime(transferRequestTime))
.setLastEppUpdateRegistrarId(domain.getTransferData().getGainingRegistrarId())
.build();
}
@Test
void testEppLastUpdateTimeAndClientId_autoRenewBeforeTransferSuccess() {
- DateTime now = fakeClock.nowUtc();
- DateTime transferRequestDateTime = now.plusDays(1);
- DateTime autorenewDateTime = now.plusDays(3);
- DateTime transferSuccessDateTime = now.plusDays(5);
+ Instant now = fakeClock.now();
+ Instant transferRequestDateTime = plusDays(now, 1);
+ Instant autorenewDateTime = plusDays(now, 3);
+ Instant transferSuccessDateTime = plusDays(now, 5);
setupPendingTransferDomain(autorenewDateTime, transferRequestDateTime, transferSuccessDateTime);
- Domain beforeAutoRenew = domain.cloneProjectedAtTime(autorenewDateTime.minusDays(1));
+ Domain beforeAutoRenew = domain.cloneProjectedAtInstant(minusDays(autorenewDateTime, 1));
assertThat(beforeAutoRenew.getLastEppUpdateTime()).isEqualTo(transferRequestDateTime);
assertThat(beforeAutoRenew.getLastEppUpdateRegistrarId()).isEqualTo("TheRegistrar");
// If autorenew happens before transfer succeeds(before transfer grace period starts as well),
// lastEppUpdateRegistrarId should still be the current sponsor client id
- Domain afterAutoRenew = domain.cloneProjectedAtTime(autorenewDateTime.plusDays(1));
+ Domain afterAutoRenew = domain.cloneProjectedAtInstant(plusDays(autorenewDateTime, 1));
assertThat(afterAutoRenew.getLastEppUpdateTime()).isEqualTo(autorenewDateTime);
assertThat(afterAutoRenew.getLastEppUpdateRegistrarId()).isEqualTo("NewRegistrar");
}
@Test
void testEppLastUpdateTimeAndClientId_autoRenewAfterTransferSuccess() {
- DateTime now = fakeClock.nowUtc();
- DateTime transferRequestDateTime = now.plusDays(1);
- DateTime autorenewDateTime = now.plusDays(3);
- DateTime transferSuccessDateTime = now.plusDays(5);
+ Instant now = fakeClock.now();
+ Instant transferRequestDateTime = plusDays(now, 1);
+ Instant autorenewDateTime = plusDays(now, 3);
+ Instant transferSuccessDateTime = plusDays(now, 5);
setupPendingTransferDomain(autorenewDateTime, transferRequestDateTime, transferSuccessDateTime);
- Domain beforeAutoRenew = domain.cloneProjectedAtTime(autorenewDateTime.minusDays(1));
+ Domain beforeAutoRenew = domain.cloneProjectedAtInstant(minusDays(autorenewDateTime, 1));
assertThat(beforeAutoRenew.getLastEppUpdateTime()).isEqualTo(transferRequestDateTime);
assertThat(beforeAutoRenew.getLastEppUpdateRegistrarId()).isEqualTo("TheRegistrar");
- Domain afterTransferSuccess = domain.cloneProjectedAtTime(transferSuccessDateTime.plusDays(1));
+ Domain afterTransferSuccess =
+ domain.cloneProjectedAtInstant(plusDays(transferSuccessDateTime, 1));
assertThat(afterTransferSuccess.getLastEppUpdateTime()).isEqualTo(transferSuccessDateTime);
assertThat(afterTransferSuccess.getLastEppUpdateRegistrarId()).isEqualTo("TheRegistrar");
}
@@ -552,11 +559,11 @@ void testEppLastUpdateTimeAndClientId_isSetCorrectlyWithNullPreviousValue() {
setupUnmodifiedDomain(autorenewDateTime);
Domain beforeAutoRenew = domain.cloneProjectedAtTime(autorenewDateTime.minusDays(1));
- assertThat(beforeAutoRenew.getLastEppUpdateTime()).isEqualTo(null);
+ assertThat(beforeAutoRenew.getLastEppUpdateDateTime()).isEqualTo(null);
assertThat(beforeAutoRenew.getLastEppUpdateRegistrarId()).isEqualTo(null);
Domain afterAutoRenew = domain.cloneProjectedAtTime(autorenewDateTime.plusDays(1));
- assertThat(afterAutoRenew.getLastEppUpdateTime()).isEqualTo(autorenewDateTime);
+ assertThat(afterAutoRenew.getLastEppUpdateDateTime()).isEqualTo(autorenewDateTime);
assertThat(afterAutoRenew.getLastEppUpdateRegistrarId()).isEqualTo("NewRegistrar");
}
@@ -633,9 +640,9 @@ void testGracePeriodsByType() {
@Test
void testRenewalsHappenAtExpiration() {
- Domain renewed = domain.cloneProjectedAtTime(domain.getRegistrationExpirationTime());
+ Domain renewed = domain.cloneProjectedAtInstant(domain.getRegistrationExpirationTime());
assertThat(renewed.getRegistrationExpirationTime())
- .isEqualTo(domain.getRegistrationExpirationTime().plusYears(1));
+ .isEqualTo(plusYears(domain.getRegistrationExpirationTime(), 1));
assertThat(renewed.getLastEppUpdateTime()).isEqualTo(domain.getRegistrationExpirationTime());
assertThat(getOnlyElement(renewed.getGracePeriods()).getType())
.isEqualTo(GracePeriodStatus.AUTO_RENEW);
@@ -656,15 +663,16 @@ void testRenewalsDontHappenOnFebruary29() {
.setRegistrationExpirationTime(DateTime.parse("2004-02-29T22:00:00.0Z"))
.build();
Domain renewed =
- domain.cloneProjectedAtTime(domain.getRegistrationExpirationTime().plusYears(4));
- assertThat(renewed.getRegistrationExpirationTime().getDayOfMonth()).isEqualTo(28);
+ domain.cloneProjectedAtInstant(plusYears(domain.getRegistrationExpirationTime(), 4));
+ assertThat(renewed.getRegistrationExpirationTime().atZone(ZoneOffset.UTC).getDayOfMonth())
+ .isEqualTo(28);
}
@Test
void testMultipleAutoRenews() {
// Change the registry so that renewal costs change every year to make sure we are using the
// autorenew time as the lookup time for the cost.
- DateTime oldExpirationTime = domain.getRegistrationExpirationTime();
+ DateTime oldExpirationTime = domain.getRegistrationExpirationDateTime();
persistResource(
Tld.get("com")
.asBuilder()
@@ -680,9 +688,10 @@ void testMultipleAutoRenews() {
.build())
.build());
Domain renewedThreeTimes = domain.cloneProjectedAtTime(oldExpirationTime.plusYears(2));
- assertThat(renewedThreeTimes.getRegistrationExpirationTime())
+ assertThat(renewedThreeTimes.getRegistrationExpirationDateTime())
.isEqualTo(oldExpirationTime.plusYears(3));
- assertThat(renewedThreeTimes.getLastEppUpdateTime()).isEqualTo(oldExpirationTime.plusYears(2));
+ assertThat(renewedThreeTimes.getLastEppUpdateDateTime())
+ .isEqualTo(oldExpirationTime.plusYears(2));
assertThat(renewedThreeTimes.getGracePeriods())
.containsExactly(
GracePeriod.createForRecurrence(
@@ -730,7 +739,7 @@ void testClone_doNotExtendExpirationOnDeletedDomain() {
.setDeletionTime(now.minusDays(10))
.setStatusValues(ImmutableSet.of(StatusValue.PENDING_DELETE, StatusValue.INACTIVE))
.build());
- assertThat(domain.cloneProjectedAtTime(now).getRegistrationExpirationTime())
+ assertThat(domain.cloneProjectedAtTime(now).getRegistrationExpirationDateTime())
.isEqualTo(now.minusDays(1));
}
@@ -746,7 +755,7 @@ void testClone_doNotExtendExpirationOnFutureDeletedDomain() {
.setDeletionTime(now.plusDays(20))
.setStatusValues(ImmutableSet.of(StatusValue.PENDING_DELETE, StatusValue.INACTIVE))
.build());
- assertThat(domain.cloneProjectedAtTime(now).getRegistrationExpirationTime())
+ assertThat(domain.cloneProjectedAtTime(now).getRegistrationExpirationDateTime())
.isEqualTo(now.plusDays(1));
}
@@ -773,7 +782,7 @@ void testClone_extendsExpirationForExpiredTransferredDomain() {
.setTransferData(transferData)
.build());
- assertThat(domain.cloneProjectedAtTime(now).getRegistrationExpirationTime())
+ assertThat(domain.cloneProjectedAtTime(now).getRegistrationExpirationDateTime())
.isEqualTo(newExpiration);
}
@@ -801,7 +810,7 @@ void testClone_extendsExpirationForNonExpiredTransferredDomain() {
.setTransferData(transferData)
.build());
- assertThat(domain.cloneProjectedAtTime(now).getRegistrationExpirationTime())
+ assertThat(domain.cloneProjectedAtTime(now).getRegistrationExpirationDateTime())
.isEqualTo(newExpiration);
}
@@ -843,7 +852,7 @@ void testClone_removesBulkTokenFromTransferredDomain() {
assertThat(domain.getCurrentBulkToken()).isPresent();
Domain clonedDomain = domain.cloneProjectedAtTime(now);
- assertThat(clonedDomain.getRegistrationExpirationTime()).isEqualTo(newExpiration);
+ assertThat(clonedDomain.getRegistrationExpirationDateTime()).isEqualTo(newExpiration);
assertThat(clonedDomain.getCurrentBulkToken()).isEmpty();
}
@@ -868,7 +877,7 @@ void testClone_doesNotExtendExpirationForPendingTransfer() {
.setTransferData(transferData)
.build());
- assertThat(domain.cloneProjectedAtTime(now).getRegistrationExpirationTime())
+ assertThat(domain.cloneProjectedAtTime(now).getRegistrationExpirationDateTime())
.isEqualTo(previousExpiration);
}
@@ -906,7 +915,7 @@ void testClone_doesNotRemoveBulkTokenForPendingTransfer() {
.build());
Domain clonedDomain = domain.cloneProjectedAtTime(now);
- assertThat(clonedDomain.getRegistrationExpirationTime()).isEqualTo(previousExpiration);
+ assertThat(clonedDomain.getRegistrationExpirationDateTime()).isEqualTo(previousExpiration);
assertThat(clonedDomain.getCurrentBulkToken().get()).isEqualTo(allocationToken.createVKey());
}
@@ -943,8 +952,8 @@ void testClone_transferDuringAutorenew() {
.setAutorenewBillingEvent(recurrenceBillKey)
.build());
Domain clone = domain.cloneProjectedAtTime(now);
- assertThat(clone.getRegistrationExpirationTime())
- .isEqualTo(domain.getRegistrationExpirationTime().plusYears(1));
+ assertThat(clone.getRegistrationExpirationDateTime())
+ .isEqualTo(domain.getRegistrationExpirationDateTime().plusYears(1));
// Transferring removes the AUTORENEW grace period and adds a TRANSFER grace period
assertThat(getOnlyElement(clone.getGracePeriods()).getType())
.isEqualTo(GracePeriodStatus.TRANSFER);
diff --git a/core/src/test/java/google/registry/model/domain/GracePeriodTest.java b/core/src/test/java/google/registry/model/domain/GracePeriodTest.java
index bc79c043adc..8453d28ddc2 100644
--- a/core/src/test/java/google/registry/model/domain/GracePeriodTest.java
+++ b/core/src/test/java/google/registry/model/domain/GracePeriodTest.java
@@ -68,7 +68,7 @@ void testSuccess_forBillingEvent() {
assertThat(gracePeriod.getBillingEvent()).isEqualTo(onetime.createVKey());
assertThat(gracePeriod.getBillingRecurrence()).isNull();
assertThat(gracePeriod.getRegistrarId()).isEqualTo("TheRegistrar");
- assertThat(gracePeriod.getExpirationTime()).isEqualTo(now.plusDays(1));
+ assertThat(gracePeriod.getExpirationDateTime()).isEqualTo(now.plusDays(1));
assertThat(gracePeriod.hasBillingEvent()).isTrue();
}
@@ -82,7 +82,7 @@ void testSuccess_forRecurrence() {
assertThat(gracePeriod.getBillingEvent()).isNull();
assertThat(gracePeriod.getBillingRecurrence()).isEqualTo(recurrenceKey);
assertThat(gracePeriod.getRegistrarId()).isEqualTo("TheRegistrar");
- assertThat(gracePeriod.getExpirationTime()).isEqualTo(now.plusDays(1));
+ assertThat(gracePeriod.getExpirationDateTime()).isEqualTo(now.plusDays(1));
assertThat(gracePeriod.hasBillingEvent()).isTrue();
}
@@ -96,7 +96,7 @@ void testSuccess_createWithoutBillingEvent() {
assertThat(gracePeriod.getBillingEvent()).isNull();
assertThat(gracePeriod.getBillingRecurrence()).isNull();
assertThat(gracePeriod.getRegistrarId()).isEqualTo("TheRegistrar");
- assertThat(gracePeriod.getExpirationTime()).isEqualTo(now);
+ assertThat(gracePeriod.getExpirationDateTime()).isEqualTo(now);
assertThat(gracePeriod.hasBillingEvent()).isFalse();
}
diff --git a/core/src/test/java/google/registry/model/tld/label/PremiumListUtilsTest.java b/core/src/test/java/google/registry/model/tld/label/PremiumListUtilsTest.java
index 7abd8f5cbb9..add2245f5d3 100644
--- a/core/src/test/java/google/registry/model/tld/label/PremiumListUtilsTest.java
+++ b/core/src/test/java/google/registry/model/tld/label/PremiumListUtilsTest.java
@@ -17,20 +17,27 @@
import static com.google.common.truth.Truth.assertThat;
import static google.registry.model.tld.label.PremiumListUtils.parseToPremiumList;
import static org.joda.money.CurrencyUnit.USD;
+import static org.joda.time.DateTimeZone.UTC;
import static org.junit.jupiter.api.Assertions.assertThrows;
import com.google.common.collect.ImmutableList;
import java.math.BigDecimal;
+import org.joda.time.DateTime;
import org.junit.jupiter.api.Test;
/** Unit tests for {@link PremiumListUtils}. */
class PremiumListUtilsTest {
+ private static final DateTime SAMPLE_TIME = DateTime.now(UTC);
+
@Test
void parseInputToPremiumList_works() {
PremiumList premiumList =
parseToPremiumList(
- "testlist", USD, ImmutableList.of("foo,USD 99.50", "bar,USD 30", "baz,USD 10"));
+ "testlist",
+ USD,
+ ImmutableList.of("foo,USD 99.50", "bar,USD 30", "baz,USD 10"),
+ SAMPLE_TIME);
assertThat(premiumList.getName()).isEqualTo("testlist");
assertThat(premiumList.getLabelsToPrices())
.containsExactly("foo", twoDigits(99.50), "bar", twoDigits(30), "baz", twoDigits(10));
@@ -45,7 +52,8 @@ void parseInputToPremiumList_throwsOnInconsistentCurrencies() {
parseToPremiumList(
"testlist",
USD,
- ImmutableList.of("foo,USD 99.50", "bar,USD 30", "baz,JPY 990")));
+ ImmutableList.of("foo,USD 99.50", "bar,USD 30", "baz,JPY 990"),
+ SAMPLE_TIME));
assertThat(thrown).hasMessageThat().isEqualTo("The currency unit must be USD");
}
diff --git a/core/src/test/java/google/registry/reporting/icann/IcannReportingStagerTest.java b/core/src/test/java/google/registry/reporting/icann/IcannReportingStagerTest.java
index 77092e5e1d9..4e2714781c3 100644
--- a/core/src/test/java/google/registry/reporting/icann/IcannReportingStagerTest.java
+++ b/core/src/test/java/google/registry/reporting/icann/IcannReportingStagerTest.java
@@ -16,6 +16,7 @@
import static com.google.common.truth.Truth.assertThat;
import static java.nio.charset.StandardCharsets.UTF_8;
+import static org.joda.time.DateTimeZone.UTC;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@@ -31,15 +32,18 @@
import google.registry.bigquery.BigqueryUtils.TableType;
import google.registry.gcs.GcsUtils;
import google.registry.reporting.icann.IcannReportingModule.ReportType;
+import google.registry.testing.FakeClock;
import google.registry.testing.FakeResponse;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
+import org.joda.time.DateTime;
import org.joda.time.YearMonth;
import org.junit.jupiter.api.Test;
/** Unit tests for {@link google.registry.reporting.icann.IcannReportingStager}. */
class IcannReportingStagerTest {
+ private final FakeClock clock = new FakeClock(DateTime.now(UTC));
private BigqueryConnection bigquery = mock(BigqueryConnection.class);
FakeResponse response = new FakeResponse();
private YearMonth yearMonth = new YearMonth(2017, 6);
@@ -63,7 +67,7 @@ private void setUpBigquery() {
when(bigquery.startQuery(any(String.class), any(DestinationTable.class)))
.thenReturn(fakeFuture());
DestinationTable.Builder tableBuilder =
- new DestinationTable.Builder()
+ new DestinationTable.Builder(clock)
.datasetId("testdataset")
.type(TableType.TABLE)
.name("tablename")
diff --git a/core/src/test/java/google/registry/testing/AbstractEppResourceSubject.java b/core/src/test/java/google/registry/testing/AbstractEppResourceSubject.java
index baebec91be9..a8a039c4df3 100644
--- a/core/src/test/java/google/registry/testing/AbstractEppResourceSubject.java
+++ b/core/src/test/java/google/registry/testing/AbstractEppResourceSubject.java
@@ -148,15 +148,15 @@ public And hasExactlyStatusValues(StatusValue... statusValues) {
}
public And hasDeletionTime(DateTime deletionTime) {
- return hasValue(deletionTime, actual.getDeletionTime(), "getDeletionTime()");
+ return hasValue(deletionTime, actual.getDeletionDateTime(), "getDeletionTime()");
}
public And hasLastEppUpdateTime(DateTime lastUpdateTime) {
- return hasValue(lastUpdateTime, actual.getLastEppUpdateTime(), "has lastEppUpdateTime");
+ return hasValue(lastUpdateTime, actual.getLastEppUpdateDateTime(), "has lastEppUpdateTime");
}
public And hasLastEppUpdateTimeAtLeast(DateTime before) {
- DateTime lastEppUpdateTime = actual.getLastEppUpdateTime();
+ DateTime lastEppUpdateTime = actual.getLastEppUpdateDateTime();
check("getLastEppUpdateTime()").that(lastEppUpdateTime).isAtLeast(before);
return andChainer();
}
diff --git a/core/src/test/java/google/registry/testing/DomainSubject.java b/core/src/test/java/google/registry/testing/DomainSubject.java
index 0036528baee..507a548c9c1 100644
--- a/core/src/test/java/google/registry/testing/DomainSubject.java
+++ b/core/src/test/java/google/registry/testing/DomainSubject.java
@@ -78,7 +78,7 @@ public And hasCurrentSponsorRegistrarId(String registrarId) {
public And hasRegistrationExpirationTime(DateTime expiration) {
return hasValue(
- expiration, actual.getRegistrationExpirationTime(), "getRegistrationExpirationTime()");
+ expiration, actual.getRegistrationExpirationDateTime(), "getRegistrationExpirationTime()");
}
public And hasLastTransferTime(DateTime lastTransferTime) {
diff --git a/core/src/test/java/google/registry/tools/CommandTestCase.java b/core/src/test/java/google/registry/tools/CommandTestCase.java
index e2060506d3f..d298a0239a0 100644
--- a/core/src/test/java/google/registry/tools/CommandTestCase.java
+++ b/core/src/test/java/google/registry/tools/CommandTestCase.java
@@ -80,6 +80,18 @@ public final void beforeEachCommandTestCase() throws Exception {
RegistryToolEnvironment.UNITTEST.setup(systemPropertyExtension);
command = newCommandInstance();
+ // Inject the fake clock into the command if it has a clock field.
+ for (Class> c = command.getClass(); c != null; c = c.getSuperclass()) {
+ try {
+ java.lang.reflect.Field clockField = c.getDeclaredField("clock");
+ clockField.setAccessible(true);
+ clockField.set(command, fakeClock);
+ break;
+ } catch (NoSuchFieldException e) {
+ // Fall through.
+ }
+ }
+
// Capture standard output/error. Use a single-byte encoding to emulate platforms where default
// charset is not UTF_8.
oldStdout = System.out;
diff --git a/core/src/test/java/google/registry/tools/CreatePremiumListCommandTest.java b/core/src/test/java/google/registry/tools/CreatePremiumListCommandTest.java
index 947fdffe816..ace6ce512e4 100644
--- a/core/src/test/java/google/registry/tools/CreatePremiumListCommandTest.java
+++ b/core/src/test/java/google/registry/tools/CreatePremiumListCommandTest.java
@@ -54,7 +54,6 @@ void commandRun_successCreateList() throws Exception {
// since the old entity is always null and file cannot be empty, the prompt will NOT be "No entity
// changes to apply."
void commandPrompt_successStageNewEntity() throws Exception {
- CreatePremiumListCommand command = new CreatePremiumListCommand();
command.inputFile = Paths.get(premiumTermsPath);
command.currencyUnit = "USD";
command.prompt();
@@ -63,7 +62,6 @@ void commandPrompt_successStageNewEntity() throws Exception {
@Test
void commandPrompt_successStageNewEntityWithOverride() throws Exception {
- CreatePremiumListCommand command = new CreatePremiumListCommand();
String alterTld = "override";
command.inputFile = Paths.get(premiumTermsPath);
command.override = true;
@@ -75,7 +73,6 @@ void commandPrompt_successStageNewEntityWithOverride() throws Exception {
@Test
void commandPrompt_failureNoInputFile() {
- CreatePremiumListCommand command = new CreatePremiumListCommand();
assertThrows(NullPointerException.class, command::prompt);
}
@@ -83,7 +80,6 @@ void commandPrompt_failureNoInputFile() {
void commandPrompt_failurePremiumListAlreadyExists() {
String randomStr = "random";
DatabaseHelper.createTld(randomStr);
- CreatePremiumListCommand command = new CreatePremiumListCommand();
command.name = randomStr;
command.currencyUnit = "USD";
IllegalArgumentException thrown = assertThrows(IllegalArgumentException.class, command::prompt);
@@ -92,7 +88,6 @@ void commandPrompt_failurePremiumListAlreadyExists() {
@Test
void commandPrompt_failureMismatchedTldFileName_noOverride() throws Exception {
- CreatePremiumListCommand command = new CreatePremiumListCommand();
String fileName = "random";
Path tmpPath = tmpDir.resolve(String.format("%s.txt", fileName));
Files.write(new byte[0], tmpPath.toFile());
@@ -111,7 +106,6 @@ void commandPrompt_failureMismatchedTldFileName_noOverride() throws Exception {
@Test
void commandPrompt_failureMismatchedTldName_noOverride() {
- CreatePremiumListCommand command = new CreatePremiumListCommand();
String fileName = "random";
command.name = fileName;
command.currencyUnit = "USD";
diff --git a/core/src/test/java/google/registry/tools/CreateReservedListCommandTest.java b/core/src/test/java/google/registry/tools/CreateReservedListCommandTest.java
index 4575b073119..acbb6c679d2 100644
--- a/core/src/test/java/google/registry/tools/CreateReservedListCommandTest.java
+++ b/core/src/test/java/google/registry/tools/CreateReservedListCommandTest.java
@@ -162,7 +162,6 @@ private void runNameTestWithOverride(String name) throws Exception {
@Test
void testStageEntityChange_succeeds() throws Exception {
- CreateReservedListCommand command = new CreateReservedListCommand();
// file content is populated in @BeforeEach of CreateOrUpdateReservedListCommandTestCase.java
command.input = Paths.get(reservedTermsPath);
command.init();
@@ -176,7 +175,6 @@ void testStageEntityChange_succeeds() throws Exception {
void testStageEntityChange_succeedsWithEmptyFile() throws Exception {
Path tmpPath = tmpDir.resolve("xn--q9jyb4c_common-tmp.txt");
Files.write(new byte[0], tmpPath.toFile());
- CreateReservedListCommand command = new CreateReservedListCommand();
command.input = tmpPath;
command.init();
assertThat(command.prompt()).contains("reservedListMap=[]");
diff --git a/core/src/test/java/google/registry/tools/UnrenewDomainCommandTest.java b/core/src/test/java/google/registry/tools/UnrenewDomainCommandTest.java
index 9f4d161c882..378231a46af 100644
--- a/core/src/test/java/google/registry/tools/UnrenewDomainCommandTest.java
+++ b/core/src/test/java/google/registry/tools/UnrenewDomainCommandTest.java
@@ -78,12 +78,12 @@ void test_unrenewTwoDomains_worksSuccessfully() throws Exception {
assertThat(
ForeignKeyUtils.loadResource(Domain.class, "foo.tld", fakeClock.nowUtc())
.get()
- .getRegistrationExpirationTime())
+ .getRegistrationExpirationDateTime())
.isEqualTo(DateTime.parse("2019-12-06T13:55:01.001Z"));
assertThat(
ForeignKeyUtils.loadResource(Domain.class, "bar.tld", fakeClock.nowUtc())
.get()
- .getRegistrationExpirationTime())
+ .getRegistrationExpirationDateTime())
.isEqualTo(DateTime.parse("2018-12-06T13:55:01.002Z"));
assertInStdout("Successfully unrenewed all domains.");
}
@@ -149,8 +149,8 @@ void test_unrenewDomain_savesDependentEntitiesCorrectly() throws Exception {
.build()));
// Check that fields on domain were updated correctly.
- assertThat(domain.getRegistrationExpirationTime()).isEqualTo(newExpirationTime);
- assertThat(domain.getLastEppUpdateTime()).isEqualTo(unrenewTime);
+ assertThat(domain.getRegistrationExpirationDateTime()).isEqualTo(newExpirationTime);
+ assertThat(domain.getLastEppUpdateDateTime()).isEqualTo(unrenewTime);
assertThat(domain.getLastEppUpdateRegistrarId()).isEqualTo("TheRegistrar");
}
diff --git a/core/src/test/java/google/registry/tools/UpdatePremiumListCommandTest.java b/core/src/test/java/google/registry/tools/UpdatePremiumListCommandTest.java
index b76ab2cdad6..c0a46d67f7b 100644
--- a/core/src/test/java/google/registry/tools/UpdatePremiumListCommandTest.java
+++ b/core/src/test/java/google/registry/tools/UpdatePremiumListCommandTest.java
@@ -60,7 +60,6 @@ void commandPrompt_successStageEntityChange() throws Exception {
File tmpFile = tmpDir.resolve(String.format("%s.txt", TLD_TEST)).toFile();
String newPremiumListData = "omg,USD 1234";
Files.asCharSink(tmpFile, UTF_8).write(newPremiumListData);
- UpdatePremiumListCommand command = new UpdatePremiumListCommand();
command.inputFile = Paths.get(tmpFile.getPath());
command.name = TLD_TEST;
assertThat(command.prompt()).contains("Update premium list for prime?");
@@ -69,7 +68,6 @@ void commandPrompt_successStageEntityChange() throws Exception {
@Test
void commandPrompt_successStageNoChange() throws Exception {
File tmpFile = tmpDir.resolve(String.format("%s.txt", TLD_TEST)).toFile();
- UpdatePremiumListCommand command = new UpdatePremiumListCommand();
command.inputFile = Paths.get(tmpFile.getPath());
command.name = TLD_TEST;
assertThat(command.prompt())
@@ -82,7 +80,6 @@ void commandRun_successUpdateList() throws Exception {
String newPremiumListData = "eth,USD 9999";
Files.asCharSink(tmpFile, UTF_8).write(newPremiumListData);
- UpdatePremiumListCommand command = new UpdatePremiumListCommand();
// data come from @beforeEach of CreateOrUpdatePremiumListCommandTestCase.java
command.inputFile = Paths.get(tmpFile.getPath());
runCommandForced("--name=" + TLD_TEST, "--input=" + command.inputFile);
@@ -96,7 +93,6 @@ void commandRun_successUpdateList() throws Exception {
void commandRun_successNoChange() throws Exception {
File tmpFile = tmpDir.resolve(String.format("%s.txt", TLD_TEST)).toFile();
- UpdatePremiumListCommand command = new UpdatePremiumListCommand();
command.inputFile = Paths.get(tmpFile.getPath());
runCommandForced("--name=" + TLD_TEST, "--input=" + command.inputFile);
@@ -113,7 +109,6 @@ void commandRun_successUpdateList_whenExistingListIsEmpty() throws Exception {
String newPremiumListData = "eth,USD 9999";
Files.asCharSink(newPremiumFile, UTF_8).write(newPremiumListData);
- UpdatePremiumListCommand command = new UpdatePremiumListCommand();
// data come from @beforeEach of CreateOrUpdatePremiumListCommandTestCase.java
command.inputFile = Paths.get(newPremiumFile.getPath());
runCommandForced("--name=" + TLD_TEST, "--input=" + command.inputFile);
@@ -129,7 +124,6 @@ void commandRun_successUpdateMultiLineList() throws Exception {
String premiumTerms = "foo,USD 9000\ndoge,USD 100\nelon,USD 2021";
Files.asCharSink(tmpFile, UTF_8).write(premiumTerms);
- UpdatePremiumListCommand command = new UpdatePremiumListCommand();
command.inputFile = Paths.get(tmpFile.getPath());
runCommandForced("--name=" + TLD_TEST, "--input=" + command.inputFile);
@@ -146,7 +140,6 @@ void commandPrompt_failureUpdateEmptyList() throws Exception {
Path tmpPath = tmpDir.resolve(String.format("%s.txt", TLD_TEST));
Files.write(new byte[0], tmpPath.toFile());
- UpdatePremiumListCommand command = new UpdatePremiumListCommand();
command.inputFile = tmpPath;
command.name = TLD_TEST;
IllegalArgumentException thrown = assertThrows(IllegalArgumentException.class, command::prompt);
@@ -156,7 +149,6 @@ void commandPrompt_failureUpdateEmptyList() throws Exception {
@Test
void commandPrompt_failureNoPreviousVersion() {
registry = createTld("random", null, null);
- UpdatePremiumListCommand command = new UpdatePremiumListCommand();
command.name = "random";
IllegalArgumentException thrown = assertThrows(IllegalArgumentException.class, command::prompt);
assertThat(thrown)
@@ -166,13 +158,11 @@ void commandPrompt_failureNoPreviousVersion() {
@Test
void commandPrompt_failureNoInputFile() {
- UpdatePremiumListCommand command = new UpdatePremiumListCommand();
assertThrows(NullPointerException.class, command::prompt);
}
@Test
void commandPrompt_failureTldFromNameDoesNotExist() {
- UpdatePremiumListCommand command = new UpdatePremiumListCommand();
command.name = "random2";
IllegalArgumentException thrown = assertThrows(IllegalArgumentException.class, command::prompt);
assertThat(thrown)
@@ -182,7 +172,6 @@ void commandPrompt_failureTldFromNameDoesNotExist() {
@Test
void commandPrompt_failureTldFromInputFileDoesNotExist() {
- UpdatePremiumListCommand command = new UpdatePremiumListCommand();
// using tld extracted from file name but this tld is not part of the registry
command.inputFile = Paths.get(tmpDir.resolve("random3.txt").toFile().getPath());
IllegalArgumentException thrown = assertThrows(IllegalArgumentException.class, command::prompt);
@@ -197,7 +186,6 @@ void commandDryRun_noChangesMade() throws Exception {
String newPremiumListData = "eth,USD 9999";
Files.asCharSink(tmpFile, UTF_8).write(newPremiumListData);
- UpdatePremiumListCommand command = new UpdatePremiumListCommand();
command.inputFile = Paths.get(tmpFile.getPath());
runCommandForced("--name=" + TLD_TEST, "--input=" + command.inputFile, "--dry_run");
diff --git a/core/src/test/java/google/registry/tools/UpdateReservedListCommandTest.java b/core/src/test/java/google/registry/tools/UpdateReservedListCommandTest.java
index 52d3f5f12cd..8d7f4943ea0 100644
--- a/core/src/test/java/google/registry/tools/UpdateReservedListCommandTest.java
+++ b/core/src/test/java/google/registry/tools/UpdateReservedListCommandTest.java
@@ -98,7 +98,6 @@ void testSuccess_noChanges() throws Exception {
Files.asCharSink(reservedTermsFile, UTF_8).write(reservedTermsCsv);
reservedTermsPath = reservedTermsFile.getPath();
// create a command instance and assign its input
- UpdateReservedListCommand command = new UpdateReservedListCommand();
command.input = Paths.get(reservedTermsPath);
// run again with terms from example_reserved_terms.csv
command.init();
@@ -110,7 +109,6 @@ void testSuccess_noChanges() throws Exception {
void testSuccess_withChanges() throws Exception {
// changes come from example_reserved_terms.csv, which are populated in @BeforeEach of
// CreateOrUpdateReservedListCommandTestCases.java
- UpdateReservedListCommand command = new UpdateReservedListCommand();
command.input = Paths.get(reservedTermsPath);
command.init();
diff --git a/core/src/test/java/google/registry/ui/server/console/domains/ConsoleBulkDomainActionTest.java b/core/src/test/java/google/registry/ui/server/console/domains/ConsoleBulkDomainActionTest.java
index 7f5338f5e45..da0162a688e 100644
--- a/core/src/test/java/google/registry/ui/server/console/domains/ConsoleBulkDomainActionTest.java
+++ b/core/src/test/java/google/registry/ui/server/console/domains/ConsoleBulkDomainActionTest.java
@@ -19,6 +19,7 @@
import static google.registry.testing.DatabaseHelper.loadSingleton;
import static google.registry.testing.DatabaseHelper.persistDomainWithDependentResources;
import static google.registry.testing.DatabaseHelper.persistResource;
+import static google.registry.util.DateTimeUtils.plusDays;
import static jakarta.servlet.http.HttpServletResponse.SC_BAD_REQUEST;
import static jakarta.servlet.http.HttpServletResponse.SC_FORBIDDEN;
import static jakarta.servlet.http.HttpServletResponse.SC_OK;
@@ -92,7 +93,7 @@ void testSuccess_delete() {
{"example.tld":{"message":"Command completed successfully; action pending",\
"responseCode":1001}}\
""");
- assertThat(loadByEntity(domain).getDeletionTime()).isEqualTo(clock.nowUtc().plusDays(35));
+ assertThat(loadByEntity(domain).getDeletionTime()).isEqualTo(plusDays(clock.now(), 35));
ConsoleUpdateHistory history = loadSingleton(ConsoleUpdateHistory.class).get();
assertThat(history.getType()).isEqualTo(ConsoleUpdateHistory.Type.DOMAIN_DELETE);
assertThat(history.getDescription()).hasValue("example.tld");
@@ -162,7 +163,7 @@ void testHalfSuccess_halfNonexistent() throws Exception {
"nonexistent.tld":{"message":"The domain with given ID (nonexistent.tld) doesn\\u0027t exist.",\
"responseCode":2303}}\
""");
- assertThat(loadByEntity(domain).getDeletionTime()).isEqualTo(clock.nowUtc().plusDays(35));
+ assertThat(loadByEntity(domain).getDeletionTime()).isEqualTo(plusDays(clock.now(), 35));
ConsoleUpdateHistory history = loadSingleton(ConsoleUpdateHistory.class).get();
assertThat(history.getType()).isEqualTo(ConsoleUpdateHistory.Type.DOMAIN_DELETE);
assertThat(history.getDescription()).hasValue("example.tld");
diff --git a/networking/src/main/java/google/registry/networking/module/CertificateSupplierModule.java b/networking/src/main/java/google/registry/networking/module/CertificateSupplierModule.java
index d0b24f1ebed..ef4fb9e13c2 100644
--- a/networking/src/main/java/google/registry/networking/module/CertificateSupplierModule.java
+++ b/networking/src/main/java/google/registry/networking/module/CertificateSupplierModule.java
@@ -25,6 +25,7 @@
import dagger.Lazy;
import dagger.Module;
import dagger.Provides;
+import google.registry.util.Clock;
import google.registry.util.SelfSignedCaCertificate;
import jakarta.inject.Named;
import jakarta.inject.Provider;
@@ -156,9 +157,9 @@ static Supplier> provideCertificatesSupplier(
@Singleton
@Provides
- static SelfSignedCaCertificate provideSelfSignedCertificate() {
+ static SelfSignedCaCertificate provideSelfSignedCertificate(Clock clock) {
try {
- return SelfSignedCaCertificate.create();
+ return SelfSignedCaCertificate.create(clock);
} catch (Exception e) {
throw new RuntimeException(e);
}
diff --git a/networking/src/test/java/google/registry/networking/handler/SslClientInitializerTest.java b/networking/src/test/java/google/registry/networking/handler/SslClientInitializerTest.java
index 7db756da6d1..928d3ed5f7a 100644
--- a/networking/src/test/java/google/registry/networking/handler/SslClientInitializerTest.java
+++ b/networking/src/test/java/google/registry/networking/handler/SslClientInitializerTest.java
@@ -22,6 +22,7 @@
import static org.joda.time.DateTimeZone.UTC;
import com.google.common.collect.ImmutableList;
+import google.registry.testing.FakeClock;
import google.registry.util.SelfSignedCaCertificate;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandler;
@@ -173,7 +174,7 @@ void testSuccess_nullPort(SslProvider sslProvider) {
@MethodSource("provideTestCombinations")
void testFailure_defaultTrustManager_rejectSelfSignedCert(SslProvider sslProvider)
throws Exception {
- SelfSignedCaCertificate ssc = SelfSignedCaCertificate.create(SSL_HOST);
+ SelfSignedCaCertificate ssc = SelfSignedCaCertificate.create(SSL_HOST, new FakeClock());
LocalAddress localAddress =
new LocalAddress("DEFAULT_TRUST_MANAGER_REJECT_SELF_SIGNED_CERT_" + sslProvider);
nettyExtension.setUpServer(localAddress, getServerHandler(false, ssc.key(), ssc.cert()));
@@ -204,7 +205,7 @@ void testSuccess_customTrustManager_acceptCertSignedByTrustedCa(SslProvider sslP
KeyPair keyPair = getKeyPair();
// Generate a self-signed certificate, and use it to sign the key pair.
- SelfSignedCaCertificate ssc = SelfSignedCaCertificate.create();
+ SelfSignedCaCertificate ssc = SelfSignedCaCertificate.create(new FakeClock());
X509Certificate cert = signKeyPair(ssc, keyPair, SSL_HOST);
// Set up the server to use the signed cert and private key to perform handshake;
@@ -239,7 +240,7 @@ void testFailure_customTrustManager_serverCertExpired(SslProvider sslProvider) t
KeyPair keyPair = getKeyPair();
// Generate a self-signed certificate, and use it to sign the key pair.
- SelfSignedCaCertificate ssc = SelfSignedCaCertificate.create();
+ SelfSignedCaCertificate ssc = SelfSignedCaCertificate.create(new FakeClock());
X509Certificate cert =
signKeyPair(
ssc, keyPair, SSL_HOST, DateTime.now(UTC).minusDays(2), DateTime.now(UTC).minusDays(1));
@@ -276,7 +277,7 @@ void testFailure_customTrustManager_serverCertNotYetValid(SslProvider sslProvide
KeyPair keyPair = getKeyPair();
// Generate a self-signed certificate, and use it to sign the key pair.
- SelfSignedCaCertificate ssc = SelfSignedCaCertificate.create();
+ SelfSignedCaCertificate ssc = SelfSignedCaCertificate.create(new FakeClock());
X509Certificate cert =
signKeyPair(
ssc, keyPair, SSL_HOST, DateTime.now(UTC).plusDays(1), DateTime.now(UTC).plusDays(2));
@@ -310,8 +311,8 @@ void testSuccess_customTrustManager_acceptSelfSignedCert_clientCertRequired(
new LocalAddress(
"CUSTOM_TRUST_MANAGER_ACCEPT_SELF_SIGNED_CERT_CLIENT_CERT_REQUIRED_" + sslProvider);
- SelfSignedCaCertificate serverSsc = SelfSignedCaCertificate.create(SSL_HOST);
- SelfSignedCaCertificate clientSsc = SelfSignedCaCertificate.create();
+ SelfSignedCaCertificate serverSsc = SelfSignedCaCertificate.create(SSL_HOST, new FakeClock());
+ SelfSignedCaCertificate clientSsc = SelfSignedCaCertificate.create(new FakeClock());
// Set up the server to require client certificate.
nettyExtension.setUpServer(
@@ -352,7 +353,7 @@ void testFailure_customTrustManager_wrongHostnameInCertificate(SslProvider sslPr
KeyPair keyPair = getKeyPair();
// Generate a self-signed certificate, and use it to sign the key pair.
- SelfSignedCaCertificate ssc = SelfSignedCaCertificate.create();
+ SelfSignedCaCertificate ssc = SelfSignedCaCertificate.create(new FakeClock());
X509Certificate cert = signKeyPair(ssc, keyPair, "wrong.com");
// Set up the server to use the signed cert and private key to perform handshake;
diff --git a/networking/src/test/java/google/registry/networking/handler/SslServerInitializerTest.java b/networking/src/test/java/google/registry/networking/handler/SslServerInitializerTest.java
index d1736bfa848..d7646e00b5b 100644
--- a/networking/src/test/java/google/registry/networking/handler/SslServerInitializerTest.java
+++ b/networking/src/test/java/google/registry/networking/handler/SslServerInitializerTest.java
@@ -24,6 +24,7 @@
import com.google.common.base.Suppliers;
import com.google.common.collect.ImmutableList;
+import google.registry.testing.FakeClock;
import google.registry.util.SelfSignedCaCertificate;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelInitializer;
@@ -148,7 +149,7 @@ private ChannelHandler getClientHandler(
@ParameterizedTest
@MethodSource("provideTestCombinations")
void testSuccess_swappedInitializerWithSslHandler(SslProvider sslProvider) throws Exception {
- SelfSignedCaCertificate ssc = SelfSignedCaCertificate.create(SSL_HOST);
+ SelfSignedCaCertificate ssc = SelfSignedCaCertificate.create(SSL_HOST, new FakeClock());
SslServerInitializer sslServerInitializer =
new SslServerInitializer<>(
true,
@@ -169,13 +170,13 @@ void testSuccess_swappedInitializerWithSslHandler(SslProvider sslProvider) throw
@ParameterizedTest
@MethodSource("provideTestCombinations")
void testSuccess_trustAnyClientCert(SslProvider sslProvider) throws Exception {
- SelfSignedCaCertificate serverSsc = SelfSignedCaCertificate.create(SSL_HOST);
+ SelfSignedCaCertificate serverSsc = SelfSignedCaCertificate.create(SSL_HOST, new FakeClock());
LocalAddress localAddress = new LocalAddress("TRUST_ANY_CLIENT_CERT_" + sslProvider);
nettyExtension.setUpServer(
localAddress,
getServerHandler(true, false, sslProvider, serverSsc.key(), serverSsc.cert()));
- SelfSignedCaCertificate clientSsc = SelfSignedCaCertificate.create();
+ SelfSignedCaCertificate clientSsc = SelfSignedCaCertificate.create(new FakeClock());
nettyExtension.setUpClient(
localAddress,
getClientHandler(sslProvider, serverSsc.cert(), clientSsc.key(), clientSsc.cert()));
@@ -193,7 +194,7 @@ void testSuccess_trustAnyClientCert(SslProvider sslProvider) throws Exception {
@ParameterizedTest
@MethodSource("provideTestCombinations")
void testFailure_cipherNotAccepted(SslProvider sslProvider) throws Exception {
- SelfSignedCaCertificate serverSsc = SelfSignedCaCertificate.create(SSL_HOST);
+ SelfSignedCaCertificate serverSsc = SelfSignedCaCertificate.create(SSL_HOST, new FakeClock());
LocalAddress localAddress = new LocalAddress("CIPHER_NOT_ACCEPTED_" + sslProvider);
nettyExtension.setUpServer(
@@ -220,7 +221,7 @@ void testFailure_cipherNotAccepted(SslProvider sslProvider) throws Exception {
@ParameterizedTest
@MethodSource("provideTestCombinations")
void testSuccess_someCiphersNotAccepted(SslProvider sslProvider) throws Exception {
- SelfSignedCaCertificate serverSsc = SelfSignedCaCertificate.create(SSL_HOST);
+ SelfSignedCaCertificate serverSsc = SelfSignedCaCertificate.create(SSL_HOST, new FakeClock());
LocalAddress localAddress = new LocalAddress("SOME_CIPHERS_NOT_ACCEPTED_" + sslProvider);
nettyExtension.setUpServer(
@@ -258,7 +259,7 @@ void testSuccess_someCiphersNotAccepted(SslProvider sslProvider) throws Exceptio
@ParameterizedTest
@MethodSource("provideTestCombinations")
void testFailure_protocolNotAccepted(SslProvider sslProvider) throws Exception {
- SelfSignedCaCertificate serverSsc = SelfSignedCaCertificate.create(SSL_HOST);
+ SelfSignedCaCertificate serverSsc = SelfSignedCaCertificate.create(SSL_HOST, new FakeClock());
LocalAddress localAddress = new LocalAddress("PROTOCOL_NOT_ACCEPTED_" + sslProvider);
nettyExtension.setUpServer(
@@ -288,7 +289,7 @@ void testFailure_protocolNotAccepted(SslProvider sslProvider) throws Exception {
@ParameterizedTest
@MethodSource("provideTestCombinations")
void testFailure_clientCertExpired(SslProvider sslProvider) throws Exception {
- SelfSignedCaCertificate serverSsc = SelfSignedCaCertificate.create(SSL_HOST);
+ SelfSignedCaCertificate serverSsc = SelfSignedCaCertificate.create(SSL_HOST, new FakeClock());
LocalAddress localAddress = new LocalAddress("CLIENT_CERT_EXPIRED_" + sslProvider);
nettyExtension.setUpServer(
@@ -309,7 +310,7 @@ void testFailure_clientCertExpired(SslProvider sslProvider) throws Exception {
@ParameterizedTest
@MethodSource("provideTestCombinations")
void testFailure_clientCertNotYetValid(SslProvider sslProvider) throws Exception {
- SelfSignedCaCertificate serverSsc = SelfSignedCaCertificate.create(SSL_HOST);
+ SelfSignedCaCertificate serverSsc = SelfSignedCaCertificate.create(SSL_HOST, new FakeClock());
LocalAddress localAddress = new LocalAddress("CLIENT_CERT_EXPIRED_" + sslProvider);
nettyExtension.setUpServer(
@@ -330,7 +331,7 @@ void testFailure_clientCertNotYetValid(SslProvider sslProvider) throws Exception
@ParameterizedTest
@MethodSource("provideTestCombinations")
void testSuccess_doesNotRequireClientCert(SslProvider sslProvider) throws Exception {
- SelfSignedCaCertificate serverSsc = SelfSignedCaCertificate.create(SSL_HOST);
+ SelfSignedCaCertificate serverSsc = SelfSignedCaCertificate.create(SSL_HOST, new FakeClock());
LocalAddress localAddress = new LocalAddress("DOES_NOT_REQUIRE_CLIENT_CERT_" + sslProvider);
nettyExtension.setUpServer(
@@ -353,7 +354,7 @@ void testSuccess_doesNotRequireClientCert(SslProvider sslProvider) throws Except
@MethodSource("provideTestCombinations")
void testSuccess_CertSignedByOtherCa(SslProvider sslProvider) throws Exception {
// The self-signed cert of the CA.
- SelfSignedCaCertificate caSsc = SelfSignedCaCertificate.create();
+ SelfSignedCaCertificate caSsc = SelfSignedCaCertificate.create(new FakeClock());
KeyPair keyPair = getKeyPair();
X509Certificate serverCert = signKeyPair(caSsc, keyPair, SSL_HOST);
LocalAddress localAddress = new LocalAddress("CERT_SIGNED_BY_OTHER_CA_" + sslProvider);
@@ -368,7 +369,7 @@ void testSuccess_CertSignedByOtherCa(SslProvider sslProvider) throws Exception {
// Serving both the server cert, and the CA cert
serverCert,
caSsc.cert()));
- SelfSignedCaCertificate clientSsc = SelfSignedCaCertificate.create();
+ SelfSignedCaCertificate clientSsc = SelfSignedCaCertificate.create(new FakeClock());
nettyExtension.setUpClient(
localAddress,
getClientHandler(
@@ -392,7 +393,7 @@ void testSuccess_CertSignedByOtherCa(SslProvider sslProvider) throws Exception {
@ParameterizedTest
@MethodSource("provideTestCombinations")
void testFailure_requireClientCertificate(SslProvider sslProvider) throws Exception {
- SelfSignedCaCertificate serverSsc = SelfSignedCaCertificate.create(SSL_HOST);
+ SelfSignedCaCertificate serverSsc = SelfSignedCaCertificate.create(SSL_HOST, new FakeClock());
LocalAddress localAddress = new LocalAddress("REQUIRE_CLIENT_CERT_" + sslProvider);
nettyExtension.setUpServer(
@@ -417,13 +418,14 @@ void testFailure_requireClientCertificate(SslProvider sslProvider) throws Except
@ParameterizedTest
@MethodSource("provideTestCombinations")
void testFailure_wrongHostnameInCertificate(SslProvider sslProvider) throws Exception {
- SelfSignedCaCertificate serverSsc = SelfSignedCaCertificate.create("wrong.com");
+ SelfSignedCaCertificate serverSsc =
+ SelfSignedCaCertificate.create("wrong.com", new FakeClock());
LocalAddress localAddress = new LocalAddress("WRONG_HOSTNAME_" + sslProvider);
nettyExtension.setUpServer(
localAddress,
getServerHandler(true, false, sslProvider, serverSsc.key(), serverSsc.cert()));
- SelfSignedCaCertificate clientSsc = SelfSignedCaCertificate.create();
+ SelfSignedCaCertificate clientSsc = SelfSignedCaCertificate.create(new FakeClock());
nettyExtension.setUpClient(
localAddress,
getClientHandler(sslProvider, serverSsc.cert(), clientSsc.key(), clientSsc.cert()));
diff --git a/networking/src/test/java/google/registry/networking/module/CertificateSupplierModuleTest.java b/networking/src/test/java/google/registry/networking/module/CertificateSupplierModuleTest.java
index 70ffbfe3ecb..13acae86ac3 100644
--- a/networking/src/test/java/google/registry/networking/module/CertificateSupplierModuleTest.java
+++ b/networking/src/test/java/google/registry/networking/module/CertificateSupplierModuleTest.java
@@ -26,6 +26,8 @@
import dagger.Module;
import dagger.Provides;
import google.registry.networking.module.CertificateSupplierModule.Mode;
+import google.registry.testing.FakeClock;
+import google.registry.util.Clock;
import google.registry.util.SelfSignedCaCertificate;
import jakarta.inject.Named;
import jakarta.inject.Singleton;
@@ -59,7 +61,7 @@ private static TestComponent createComponentForPem(Object... objects) throws Exc
@BeforeEach
void beforeEach() throws Exception {
- ssc = SelfSignedCaCertificate.create();
+ ssc = SelfSignedCaCertificate.create(new FakeClock());
KeyPair keyPair = getKeyPair();
key = keyPair.getPrivate();
cert = signKeyPair(ssc, keyPair, "example.tld");
@@ -147,6 +149,11 @@ Duration provideCachingDuration() {
// Make the supplier always return the save value for test to save time.
return Duration.ofDays(1);
}
+
+ @Provides
+ Clock provideClock() {
+ return new FakeClock();
+ }
}
/**
diff --git a/proxy/src/test/java/google/registry/proxy/EppProtocolModuleTest.java b/proxy/src/test/java/google/registry/proxy/EppProtocolModuleTest.java
index f6fb6f53460..fa71772ec4a 100644
--- a/proxy/src/test/java/google/registry/proxy/EppProtocolModuleTest.java
+++ b/proxy/src/test/java/google/registry/proxy/EppProtocolModuleTest.java
@@ -24,6 +24,7 @@
import com.google.common.base.Throwables;
import google.registry.proxy.handler.HttpsRelayServiceHandler.NonOkHttpResponseException;
+import google.registry.testing.FakeClock;
import google.registry.util.SelfSignedCaCertificate;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
@@ -122,7 +123,7 @@ private static FullHttpResponse makeEppHttpResponse(
@Override
void beforeEach() throws Exception {
testComponent = makeTestComponent();
- certificate = SelfSignedCaCertificate.create().cert();
+ certificate = SelfSignedCaCertificate.create(new FakeClock()).cert();
initializeChannel(
ch -> {
ch.attr(REMOTE_ADDRESS_KEY).set(CLIENT_ADDRESS);
diff --git a/proxy/src/test/java/google/registry/proxy/handler/EppServiceHandlerTest.java b/proxy/src/test/java/google/registry/proxy/handler/EppServiceHandlerTest.java
index cc4c4578d1e..8ccab79f1ae 100644
--- a/proxy/src/test/java/google/registry/proxy/handler/EppServiceHandlerTest.java
+++ b/proxy/src/test/java/google/registry/proxy/handler/EppServiceHandlerTest.java
@@ -32,6 +32,7 @@
import google.registry.proxy.TestUtils;
import google.registry.proxy.handler.HttpsRelayServiceHandler.NonOkHttpResponseException;
import google.registry.proxy.metric.FrontendMetrics;
+import google.registry.testing.FakeClock;
import google.registry.util.ProxyHttpHeaders;
import google.registry.util.SelfSignedCaCertificate;
import io.netty.buffer.ByteBuf;
@@ -114,7 +115,7 @@ private FullHttpRequest makeEppHttpRequest(String content, Cookie... cookies) th
@BeforeEach
void beforeEach() throws Exception {
- clientCertificate = SelfSignedCaCertificate.create().cert();
+ clientCertificate = SelfSignedCaCertificate.create(new FakeClock()).cert();
channel = setUpNewChannel(eppServiceHandler);
}
@@ -171,7 +172,7 @@ void testSuccess_connectionMetrics_twoConnections_differentClients() throws Exce
new EppServiceHandler(
RELAY_HOST, RELAY_PATH, false, () -> ID_TOKEN, HELLO.getBytes(UTF_8), metrics);
EmbeddedChannel channel2 = setUpNewChannel(eppServiceHandler2);
- X509Certificate clientCertificate2 = SelfSignedCaCertificate.create().cert();
+ X509Certificate clientCertificate2 = SelfSignedCaCertificate.create(new FakeClock()).cert();
setHandshakeSuccess(channel2, clientCertificate2);
String certHash2 = getCertificateHash(clientCertificate2);
diff --git a/util/src/main/java/google/registry/util/PosixTarHeader.java b/util/src/main/java/google/registry/util/PosixTarHeader.java
index 4d9b40550d2..5c68086c253 100644
--- a/util/src/main/java/google/registry/util/PosixTarHeader.java
+++ b/util/src/main/java/google/registry/util/PosixTarHeader.java
@@ -324,12 +324,12 @@ public static class Builder {
private final byte[] header = new byte[HEADER_LENGTH];
private boolean hasName = false;
private boolean hasSize = false;
+ private boolean hasMtime = false;
public Builder() {
setMode(DEFAULT_MODE);
setUid(DEFAULT_UID);
setGid(DEFAULT_GID);
- setMtime(DateTime.now(UTC));
setType(DEFAULT_TYPE);
setMagic();
setVersion();
@@ -418,6 +418,7 @@ public Builder setSize(long size) {
public Builder setMtime(DateTime mtime) {
checkNotNull(mtime, "mtime");
setField("mtime", 136, 12, String.format("%011o", mtime.getMillis() / MILLIS_PER_SECOND));
+ hasMtime = true;
return this;
}
@@ -483,8 +484,10 @@ private void setVersion() {
public PosixTarHeader build() {
checkState(hasName, "name not set");
checkState(hasSize, "size not set");
+ checkState(hasMtime, "mtime not set");
hasName = false;
hasSize = false;
+ hasMtime = false;
setChksum(); // Calculate the checksum last.
return new PosixTarHeader(header.clone());
}
diff --git a/util/src/main/java/google/registry/util/SelfSignedCaCertificate.java b/util/src/main/java/google/registry/util/SelfSignedCaCertificate.java
index 189c77cf549..4f58929ce0f 100644
--- a/util/src/main/java/google/registry/util/SelfSignedCaCertificate.java
+++ b/util/src/main/java/google/registry/util/SelfSignedCaCertificate.java
@@ -15,7 +15,6 @@
package google.registry.util;
import static com.google.common.base.Preconditions.checkArgument;
-import static org.joda.time.DateTimeZone.UTC;
import com.google.common.collect.ImmutableMap;
import java.math.BigInteger;
@@ -42,8 +41,6 @@
public class SelfSignedCaCertificate {
private static final String DEFAULT_ISSUER_FQDN = "registry-test";
- private static final DateTime DEFAULT_NOT_BEFORE = DateTime.now(UTC).minusHours(1);
- private static final DateTime DEFAULT_NOT_AFTER = DateTime.now(UTC).plusDays(1);
private static final Random RANDOM = new Random();
private static final BouncyCastleProvider PROVIDER = new BouncyCastleProvider();
@@ -68,13 +65,16 @@ public X509Certificate cert() {
return cert;
}
- public static SelfSignedCaCertificate create() throws Exception {
+ public static SelfSignedCaCertificate create(Clock clock) throws Exception {
return create(
- keyGen.generateKeyPair(), DEFAULT_ISSUER_FQDN, DEFAULT_NOT_BEFORE, DEFAULT_NOT_AFTER);
+ keyGen.generateKeyPair(),
+ DEFAULT_ISSUER_FQDN,
+ clock.nowUtc().minusHours(1),
+ clock.nowUtc().plusDays(1));
}
- public static SelfSignedCaCertificate create(String fqdn) throws Exception {
- return create(fqdn, DEFAULT_NOT_BEFORE, DEFAULT_NOT_AFTER);
+ public static SelfSignedCaCertificate create(String fqdn, Clock clock) throws Exception {
+ return create(fqdn, clock.nowUtc().minusHours(1), clock.nowUtc().plusDays(1));
}
public static SelfSignedCaCertificate create(String fqdn, DateTime from, DateTime to)
diff --git a/util/src/test/java/google/registry/util/DateTimeUtilsTest.java b/util/src/test/java/google/registry/util/DateTimeUtilsTest.java
index 4dc92aa1f14..eaacd8308af 100644
--- a/util/src/test/java/google/registry/util/DateTimeUtilsTest.java
+++ b/util/src/test/java/google/registry/util/DateTimeUtilsTest.java
@@ -15,7 +15,9 @@
package google.registry.util;
import static com.google.common.truth.Truth.assertThat;
+import static google.registry.util.DateTimeUtils.END_INSTANT;
import static google.registry.util.DateTimeUtils.END_OF_TIME;
+import static google.registry.util.DateTimeUtils.START_INSTANT;
import static google.registry.util.DateTimeUtils.START_OF_TIME;
import static google.registry.util.DateTimeUtils.earliestOf;
import static google.registry.util.DateTimeUtils.isAtOrAfter;
@@ -23,12 +25,15 @@
import static google.registry.util.DateTimeUtils.latestOf;
import static google.registry.util.DateTimeUtils.leapSafeAddYears;
import static google.registry.util.DateTimeUtils.leapSafeSubtractYears;
+import static google.registry.util.DateTimeUtils.toDateTime;
+import static google.registry.util.DateTimeUtils.toInstant;
import static google.registry.util.DateTimeUtils.toLocalDate;
import static google.registry.util.DateTimeUtils.toSqlDate;
import static org.junit.jupiter.api.Assertions.assertThrows;
import com.google.common.collect.ImmutableList;
import java.sql.Date;
+import java.time.Instant;
import org.joda.time.DateTime;
import org.joda.time.LocalDate;
import org.junit.jupiter.api.Test;
@@ -42,7 +47,7 @@ class DateTimeUtilsTest {
@Test
void testSuccess_earliestOf() {
assertThat(earliestOf(START_OF_TIME, END_OF_TIME)).isEqualTo(START_OF_TIME);
- assertThat(earliestOf(sampleDates)).isEqualTo(START_OF_TIME);
+ assertThat(DateTimeUtils.earliestDateTimeOf(sampleDates)).isEqualTo(START_OF_TIME);
}
@Test
@@ -72,6 +77,12 @@ void testSuccess_leapSafeAddYears() {
assertThat(leapSafeAddYears(startDate, 4)).isEqualTo(DateTime.parse("2016-02-28T00:00:00Z"));
}
+ @Test
+ void test_leapSafeAddYears_worksWithInstants() {
+ Instant startDate = Instant.parse("2012-02-29T00:00:00Z");
+ assertThat(leapSafeAddYears(startDate, 4)).isEqualTo(Instant.parse("2016-02-28T00:00:00Z"));
+ }
+
@Test
void testSuccess_leapSafeSubtractYears() {
DateTime startDate = DateTime.parse("2012-02-29T00:00:00Z");
@@ -80,6 +91,13 @@ void testSuccess_leapSafeSubtractYears() {
.isEqualTo(DateTime.parse("2008-02-28T00:00:00Z"));
}
+ @Test
+ void test_leapSafeSubtractYears_worksWithInstants() {
+ Instant startDate = Instant.parse("2012-02-29T00:00:00Z");
+ assertThat(leapSafeSubtractYears(startDate, 4))
+ .isEqualTo(Instant.parse("2008-02-28T00:00:00Z"));
+ }
+
@Test
void testSuccess_leapSafeSubtractYears_zeroYears() {
DateTime leapDay = DateTime.parse("2012-02-29T00:00:00Z");
@@ -93,7 +111,7 @@ void testFailure_earliestOfEmpty() {
@Test
void testFailure_latestOfEmpty() {
- assertThrows(IllegalArgumentException.class, () -> earliestOf(ImmutableList.of()));
+ assertThrows(IllegalArgumentException.class, () -> latestOf(ImmutableList.of()));
}
@Test
@@ -107,4 +125,32 @@ void testSuccess_toLocalDate() {
Date date = Date.valueOf("2020-02-29");
assertThat(toLocalDate(date)).isEqualTo(LocalDate.parse("2020-02-29"));
}
+
+ @Test
+ void test_startOfTimeConstants_areTheSame() {
+ assertThat(toInstant(START_OF_TIME)).isEqualTo(START_INSTANT);
+ assertThat(toDateTime(START_INSTANT)).isEqualTo(START_OF_TIME);
+ assertThat(toInstant(toDateTime(START_INSTANT))).isEqualTo(START_INSTANT);
+ assertThat(toDateTime(toInstant(START_OF_TIME))).isEqualTo(START_OF_TIME);
+ }
+
+ @Test
+ void test_endOfTimeConstants_areTheSame() {
+ assertThat(toInstant(END_OF_TIME)).isEqualTo(END_INSTANT);
+ assertThat(toDateTime(END_INSTANT)).isEqualTo(END_OF_TIME);
+ assertThat(toInstant(toDateTime(END_INSTANT))).isEqualTo(END_INSTANT);
+ assertThat(toDateTime(toInstant(END_OF_TIME))).isEqualTo(END_OF_TIME);
+ }
+
+ @Test
+ void test_instantConversionMethods_workCorrectly() {
+ assertThat(toInstant(DateTime.parse("2024-03-27T10:15:30.105Z")))
+ .isEqualTo(Instant.parse("2024-03-27T10:15:30.105Z"));
+ assertThat(toDateTime(Instant.parse("2024-03-27T10:15:30.105Z")))
+ .isEqualTo(DateTime.parse("2024-03-27T10:15:30.105Z"));
+ assertThat(toInstant(toDateTime(Instant.parse("2024-03-27T10:15:30.105Z"))))
+ .isEqualTo(Instant.parse("2024-03-27T10:15:30.105Z"));
+ assertThat(toDateTime(toInstant(DateTime.parse("2024-03-27T10:15:30.105Z"))))
+ .isEqualTo(DateTime.parse("2024-03-27T10:15:30.105Z"));
+ }
}
diff --git a/util/src/test/java/google/registry/util/PosixTarHeaderTest.java b/util/src/test/java/google/registry/util/PosixTarHeaderTest.java
index da8a1a70c0f..1b0d41bc902 100644
--- a/util/src/test/java/google/registry/util/PosixTarHeaderTest.java
+++ b/util/src/test/java/google/registry/util/PosixTarHeaderTest.java
@@ -27,6 +27,7 @@
import java.util.Arrays;
import java.util.zip.GZIPInputStream;
import org.joda.time.DateTime;
+import org.joda.time.DateTimeZone;
import org.joda.time.format.ISODateTimeFormat;
import org.junit.jupiter.api.Test;
@@ -199,7 +200,11 @@ void testLoad() {
@Test
void testBadChecksum() {
PosixTarHeader header =
- new PosixTarHeader.Builder().setName("(◕‿◕).txt").setSize(31337).build();
+ new PosixTarHeader.Builder()
+ .setName("(◕‿◕).txt")
+ .setSize(31337)
+ .setMtime(DateTime.now(DateTimeZone.UTC))
+ .build();
byte[] bytes = header.getBytes();
bytes[150] = '0';
bytes[151] = '0';
@@ -234,6 +239,7 @@ void testHashEquals() {
new PosixTarHeader.Builder()
.setName("(•︵•).txt") // Awwwww! It looks so sad...
.setSize(123)
+ .setMtime(DateTime.now(DateTimeZone.UTC))
.build())
.testEquals();
}