Refactor foundational temporal types to java.time (#3036)

* Migrates core classes (Clock, Sleeper, TransactionManager) and extensive domain models from Joda-Time to java.time.
* Restores original public API method names while substituting parameters/return values with `java.time.Instant`.
* Updates JAXB XJC `bindings.xjb` to natively generate `java.time.Instant` and `java.time.LocalDate`, eliminating `toDateTime` wrapper methods.
* Fixes XML serializers (`DateAdapter`) to robustly convert OffsetDateTime timezone strings to UTC.
* Cleans up redundant imports and Checkstyle failures across the codebase.

Remaining Joda-Time surface area to migrate in future tasks:
* Command-line parameters (e.g. `DateTimeParameter`, `DateParameter`, `IntervalParameter`) in `google.registry.tools.params`.
* EPP/RDAP flow testing infrastructure (`EppTestCase`, `RdapActionBaseTestCase`, `FlowTestCase`).
* Beam pipelines and Load Testing modules (`Spec11PipelineTest`, `RdePipelineTest`, `RegistryJpaReadTest`, `EppClient`).
* Utility bridges and converters (`DateTimeUtils.toDateTime/toInstant`, `DateTimeConverter`, `UtcDateTimeAdapter`).
* Remaining UI Console tests and Actions.
This commit is contained in:
Ben McIlwain
2026-05-08 21:04:00 +00:00
committed by GitHub
parent 60d3653b46
commit b69d51add1
320 changed files with 2450 additions and 3488 deletions
@@ -27,7 +27,6 @@ import static google.registry.request.Action.Method.POST;
import static google.registry.request.RequestParameters.PARAM_BATCH_SIZE;
import static google.registry.request.RequestParameters.PARAM_DRY_RUN;
import static google.registry.request.RequestParameters.PARAM_TLDS;
import static google.registry.util.DateTimeUtils.toInstant;
import static google.registry.util.RegistryEnvironment.PRODUCTION;
import com.google.common.base.Strings;
@@ -48,11 +47,11 @@ import google.registry.util.Clock;
import google.registry.util.RegistryEnvironment;
import jakarta.inject.Inject;
import jakarta.persistence.TypedQuery;
import java.time.Duration;
import java.time.Instant;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import org.joda.time.DateTime;
import org.joda.time.Duration;
/**
* Deletes all prober {@link Domain}s and their subordinate history entries, poll messages, and
@@ -74,7 +73,7 @@ public class DeleteProberDataAction implements Runnable {
* <p>In practice, the prober's connection will time out well before this duration. This includes
* a decent buffer.
*/
private static final Duration DOMAIN_USED_DURATION = Duration.standardHours(1);
private static final Duration DOMAIN_USED_DURATION = Duration.ofHours(1);
/**
* The minimum amount of time we want a domain to be "soft deleted".
@@ -82,7 +81,7 @@ public class DeleteProberDataAction implements Runnable {
* <p>The domain has to remain soft deleted for at least enough time for the DNS task to run and
* remove it from DNS itself. This is probably on the order of minutes.
*/
private static final Duration SOFT_DELETE_DELAY = Duration.standardHours(1);
private static final Duration SOFT_DELETE_DELAY = Duration.ofHours(1);
// Domains to delete must:
// 1. Be in one of the prober TLDs
@@ -150,7 +149,7 @@ public class DeleteProberDataAction implements Runnable {
AtomicInteger softDeletedDomains = new AtomicInteger();
AtomicInteger hardDeletedDomains = new AtomicInteger();
AtomicReference<ImmutableList<Domain>> domainsBatch = new AtomicReference<>();
DateTime startTime = clock.nowUtc();
Instant startTime = clock.now();
do {
tm().transact(
TRANSACTION_REPEATABLE_READ,
@@ -169,7 +168,7 @@ public class DeleteProberDataAction implements Runnable {
hardDeletedDomains.get(), batchSize);
// Automatically kill the job if it is running for over 20 hours
} while (clock.nowUtc().isBefore(startTime.plusHours(20))
} while (clock.now().isBefore(startTime.plus(Duration.ofHours(20)))
&& domainsBatch.get().size() == batchSize);
logger.atInfo().log(
"%s %d domains.",
@@ -183,15 +182,14 @@ public class DeleteProberDataAction implements Runnable {
ImmutableSet<String> deletableTlds,
AtomicInteger softDeletedDomains,
AtomicInteger hardDeletedDomains,
DateTime now) {
Instant now) {
TypedQuery<Domain> query =
tm().query(DOMAIN_QUERY_STRING, Domain.class)
.setParameter("tlds", deletableTlds)
.setParameter(
"creationTimeCutoff",
CreateAutoTimestamp.create(toInstant(now.minus(DOMAIN_USED_DURATION))))
.setParameter("nowMinusSoftDeleteDelay", toInstant(now.minus(SOFT_DELETE_DELAY)))
.setParameter("now", toInstant(now));
"creationTimeCutoff", CreateAutoTimestamp.create(now.minus(DOMAIN_USED_DURATION)))
.setParameter("nowMinusSoftDeleteDelay", now.minus(SOFT_DELETE_DELAY))
.setParameter("now", now);
ImmutableList<Domain> domainList =
query.setMaxResults(batchSize).getResultStream().collect(toImmutableList());
ImmutableList.Builder<String> domainRepoIdsToHardDelete = new ImmutableList.Builder<>();
@@ -19,7 +19,6 @@ import static google.registry.persistence.transaction.TransactionManagerFactory.
import static google.registry.request.Action.Method.POST;
import static google.registry.tools.LockOrUnlockDomainCommand.REGISTRY_LOCK_STATUSES;
import static google.registry.util.DateTimeUtils.isAtOrAfter;
import static google.registry.util.DateTimeUtils.toJodaDuration;
import static jakarta.servlet.http.HttpServletResponse.SC_NO_CONTENT;
import static jakarta.servlet.http.HttpServletResponse.SC_OK;
@@ -238,8 +237,7 @@ public class RelockDomainAction implements Runnable {
}
}
Duration timeBeforeRetry = previousAttempts < ATTEMPTS_BEFORE_SLOWDOWN ? TEN_MINUTES : ONE_HOUR;
domainLockUtils.enqueueDomainRelock(
toJodaDuration(timeBeforeRetry), oldUnlockRevisionId, previousAttempts + 1);
domainLockUtils.enqueueDomainRelock(timeBeforeRetry, oldUnlockRevisionId, previousAttempts + 1);
}
private void sendSuccessEmail(RegistryLock oldLock) {
@@ -16,7 +16,6 @@ package google.registry.batch;
import static com.google.common.collect.ImmutableList.toImmutableList;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.util.DateTimeUtils.toDateTime;
import static google.registry.util.PreconditionsUtils.checkArgumentNotNull;
import static java.time.ZoneOffset.UTC;
import static org.apache.http.HttpStatus.SC_INTERNAL_SERVER_ERROR;
@@ -131,11 +130,11 @@ public class SendExpiringCertificateNotificationEmailAction implements Runnable
registrar,
registrar.getClientCertificate().isPresent()
&& certificateChecker.shouldReceiveExpiringNotification(
toDateTime(registrar.getLastExpiringCertNotificationSentDate()),
registrar.getLastExpiringCertNotificationSentDate(),
registrar.getClientCertificate().get()),
registrar.getFailoverClientCertificate().isPresent()
&& certificateChecker.shouldReceiveExpiringNotification(
toDateTime(registrar.getLastExpiringFailoverCertNotificationSentDate()),
registrar.getLastExpiringFailoverCertNotificationSentDate(),
registrar.getFailoverClientCertificate().get())))
.filter(
registrarInfo ->
@@ -155,7 +154,7 @@ public class SendExpiringCertificateNotificationEmailAction implements Runnable
Optional<String> certificate) {
if (certificate.isEmpty()
|| !certificateChecker.shouldReceiveExpiringNotification(
toDateTime(lastExpiringCertNotificationSentDate), certificate.get())) {
lastExpiringCertNotificationSentDate, certificate.get())) {
return false;
}
try {
@@ -14,6 +14,7 @@
package google.registry.beam.billing;
import static google.registry.util.DateTimeUtils.toLocalDate;
import static java.time.ZoneOffset.UTC;
import com.google.common.base.Joiner;
@@ -23,7 +24,6 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.time.Instant;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.regex.Pattern;
import org.apache.beam.sdk.coders.AtomicCoder;
@@ -164,11 +164,10 @@ public record BillingEvent(
/** Returns the grouping key for this {@code BillingEvent}, to generate the overall invoice. */
InvoiceGroupingKey getInvoiceGroupingKey() {
return new InvoiceGroupingKey(
ZonedDateTime.ofInstant(billingTime(), UTC).toLocalDate().withDayOfMonth(1).toString(),
toLocalDate(billingTime()).withDayOfMonth(1).toString(),
years() == 0
? ""
: ZonedDateTime.ofInstant(billingTime(), UTC)
.toLocalDate()
: toLocalDate(billingTime())
.withDayOfMonth(1)
.plusYears(years())
.minusDays(1)
@@ -311,7 +311,7 @@ public class ExpandBillingRecurrencesPipeline implements Serializable {
for (Instant eventTime : eventTimesToExpand) {
recurrenceLastExpansionTime = latestOf(recurrenceLastExpansionTime, eventTime);
oneTimesToExpandCounter.inc();
Instant billingTime = eventTime.plusMillis(tld.getAutoRenewGracePeriodLength().getMillis());
Instant billingTime = eventTime.plus(tld.getAutoRenewGracePeriodLength());
// Note that the DomainHistory is created as of transaction time, as opposed to event time.
// This might be counterintuitive because other DomainHistories are created at the time
// mutation events occur, such as in DomainDeleteFlow or DomainRenewFlow. Therefore, it is
@@ -17,7 +17,6 @@ package google.registry.beam.resave;
import static com.google.common.collect.ImmutableList.toImmutableList;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.util.DateTimeUtils.END_INSTANT;
import static google.registry.util.DateTimeUtils.toInstant;
import static org.apache.beam.sdk.values.TypeDescriptors.integers;
import com.google.common.collect.ImmutableList;
@@ -33,6 +32,7 @@ import google.registry.model.host.Host;
import google.registry.persistence.PersistenceModule.TransactionIsolationLevel;
import google.registry.persistence.VKey;
import java.io.Serializable;
import java.time.Instant;
import org.apache.beam.sdk.Pipeline;
import org.apache.beam.sdk.PipelineResult;
import org.apache.beam.sdk.coders.StringUtf8Coder;
@@ -43,13 +43,12 @@ import org.apache.beam.sdk.transforms.ParDo;
import org.apache.beam.sdk.transforms.WithKeys;
import org.apache.beam.sdk.util.ShardedKey;
import org.apache.beam.sdk.values.KV;
import org.joda.time.DateTime;
/**
* A Dataflow Flex pipeline that resaves changed EPP resources in SQL.
*
* <p>Due to the way that Hibernate works, if an entity is unchanged by {@link
* EppResource#cloneProjectedAtTime(DateTime)} it will not actually be re-persisted to the database.
* EppResource#cloneProjectedAtTime(Instant)} it will not actually be re-persisted to the database.
* Thus, the only actual changes occur when objects are changed by projecting them to now, such as
* when a pending transfer is resolved.
*/
@@ -158,14 +157,14 @@ public class ResaveAllEppResourcesPipeline implements Serializable {
public void processElement(@Element KV<ShardedKey<Integer>, Iterable<String>> element) {
tm().transact(
() -> {
DateTime now = tm().getTransactionTime();
Instant now = tm().getTxTime();
ImmutableList<VKey<? extends EppResource>> keys =
Streams.stream(element.getValue())
.map(repoId -> VKey.create(clazz, repoId))
.collect(toImmutableList());
ImmutableList<EppResource> mappedResources =
tm().loadByKeys(keys).values().stream()
.map(r -> r.cloneProjectedAtTime(toInstant(now)))
.map(r -> r.cloneProjectedAtTime(now))
.collect(toImmutableList());
tm().putAll(mappedResources);
});
@@ -35,6 +35,8 @@ import google.registry.util.Retrier;
import google.registry.util.UtilsModule;
import jakarta.inject.Singleton;
import java.io.Serializable;
import java.time.LocalDate;
import java.time.YearMonth;
import org.apache.beam.sdk.Pipeline;
import org.apache.beam.sdk.PipelineResult;
import org.apache.beam.sdk.coders.KvCoder;
@@ -50,9 +52,6 @@ import org.apache.beam.sdk.values.KV;
import org.apache.beam.sdk.values.PCollection;
import org.apache.beam.sdk.values.TypeDescriptor;
import org.apache.beam.sdk.values.TypeDescriptors;
import org.joda.time.LocalDate;
import org.joda.time.YearMonth;
import org.joda.time.format.ISODateTimeFormat;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
@@ -76,7 +75,7 @@ public class Spec11Pipeline implements Serializable {
* @see google.registry.reporting.spec11.Spec11EmailUtils
*/
public static String getSpec11ReportFilePath(LocalDate localDate) {
YearMonth yearMonth = new YearMonth(localDate);
YearMonth yearMonth = YearMonth.from(localDate);
return String.format("icann/spec11/%s/SPEC11_MONTHLY_REPORT_%s", yearMonth, localDate);
}
@@ -155,7 +154,7 @@ public class Spec11Pipeline implements Serializable {
static void saveToSql(
PCollection<KV<DomainNameInfo, ThreatMatch>> threatMatches, Spec11PipelineOptions options) {
LocalDate date = LocalDate.parse(options.getDate(), ISODateTimeFormat.date());
LocalDate date = LocalDate.parse(options.getDate());
String transformId = "Spec11 Threat Matches";
threatMatches
.apply(
@@ -45,6 +45,7 @@ import java.io.IOException;
import java.math.BigDecimal;
import java.time.Duration;
import java.util.Collection;
import java.util.Date;
import java.util.Map;
import java.util.ServiceLoader;
import org.apache.commons.codec.binary.Base64;
@@ -154,7 +155,7 @@ public class DelegatedCredentials extends GoogleCredentials {
@Override
public AccessToken refreshAccessToken() throws IOException {
JsonFactory jsonFactory = JSON_FACTORY;
long currentTime = clock.nowUtc().getMillis();
long currentTime = clock.now().toEpochMilli();
String assertion = createAssertion(jsonFactory, currentTime);
GenericData tokenRequest = new GenericData();
@@ -195,7 +196,7 @@ public class DelegatedCredentials extends GoogleCredentials {
GenericData responseData = response.parseAs(GenericData.class);
String accessToken = validateString(responseData, "access_token", PARSE_ERROR_PREFIX);
int expiresInSeconds = validateInt32(responseData, "expires_in", PARSE_ERROR_PREFIX);
return new AccessToken(accessToken, clock.nowUtc().plusSeconds(expiresInSeconds).toDate());
return new AccessToken(accessToken, Date.from(clock.now().plusSeconds(expiresInSeconds)));
}
String createAssertion(JsonFactory jsonFactory, long currentTime) throws IOException {
@@ -18,7 +18,7 @@ import static com.google.common.base.Suppliers.memoize;
import static com.google.common.collect.ImmutableList.toImmutableList;
import static com.google.common.collect.ImmutableSortedMap.toImmutableSortedMap;
import static google.registry.config.ConfigUtils.makeUrl;
import static google.registry.util.DateTimeUtils.START_OF_TIME;
import static google.registry.util.DateTimeUtils.START_INSTANT;
import static google.registry.util.ResourceUtils.readResourceUtf8;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import static java.util.Comparator.naturalOrder;
@@ -50,14 +50,14 @@ import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.net.URI;
import java.net.URL;
import java.time.Duration;
import java.time.Instant;
import java.util.Map.Entry;
import java.util.Optional;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import javax.annotation.Nullable;
import org.joda.time.DateTime;
import org.joda.time.DateTimeConstants;
import org.joda.time.Duration;
/**
* Central clearing-house for all configuration.
@@ -225,7 +225,7 @@ public final class RegistryConfig {
*/
@Provides
@Config("databaseRetention")
public static java.time.Duration provideDatabaseRetention() {
public static Duration provideDatabaseRetention() {
return getDatabaseRetention();
}
@@ -281,8 +281,8 @@ public final class RegistryConfig {
*/
@Provides
@Config("brdaInterval")
public static java.time.Duration provideBrdaInterval() {
return java.time.Duration.ofDays(7);
public static Duration provideBrdaInterval() {
return Duration.ofDays(7);
}
/**
@@ -315,8 +315,8 @@ public final class RegistryConfig {
*/
@Provides
@Config("publishDnsUpdatesLockDuration")
public static java.time.Duration providePublishDnsUpdatesLockDuration() {
return java.time.Duration.ofMinutes(3);
public static Duration providePublishDnsUpdatesLockDuration() {
return Duration.ofMinutes(3);
}
/**
@@ -343,8 +343,8 @@ public final class RegistryConfig {
*/
@Provides
@Config("readDnsRefreshRequestsActionRuntime")
public static java.time.Duration provideReadDnsRefreshRequestsRuntime() {
return java.time.Duration.ofSeconds(45);
public static Duration provideReadDnsRefreshRequestsRuntime() {
return Duration.ofSeconds(45);
}
/**
@@ -354,8 +354,8 @@ public final class RegistryConfig {
*/
@Provides
@Config("dnsDefaultATtl")
public static java.time.Duration provideDnsDefaultATtl() {
return java.time.Duration.ofHours(1);
public static Duration provideDnsDefaultATtl() {
return Duration.ofHours(1);
}
/**
@@ -365,8 +365,8 @@ public final class RegistryConfig {
*/
@Provides
@Config("dnsDefaultNsTtl")
public static java.time.Duration provideDnsDefaultNsTtl() {
return java.time.Duration.ofHours(3);
public static Duration provideDnsDefaultNsTtl() {
return Duration.ofHours(3);
}
/**
@@ -376,8 +376,8 @@ public final class RegistryConfig {
*/
@Provides
@Config("dnsDefaultDsTtl")
public static java.time.Duration provideDnsDefaultDsTtl() {
return java.time.Duration.ofHours(1);
public static Duration provideDnsDefaultDsTtl() {
return Duration.ofHours(1);
}
@Provides
@@ -757,8 +757,8 @@ public final class RegistryConfig {
*/
@Provides
@Config("rdeInterval")
public static java.time.Duration provideRdeInterval() {
return java.time.Duration.ofDays(1);
public static Duration provideRdeInterval() {
return Duration.ofDays(1);
}
/**
@@ -768,8 +768,8 @@ public final class RegistryConfig {
*/
@Provides
@Config("rdeReportLockTimeout")
public static java.time.Duration provideRdeReportLockTimeout() {
return java.time.Duration.ofMinutes(1);
public static Duration provideRdeReportLockTimeout() {
return Duration.ofMinutes(1);
}
/**
@@ -792,8 +792,8 @@ public final class RegistryConfig {
*/
@Provides
@Config("rdeUploadLockTimeout")
public static java.time.Duration provideRdeUploadLockTimeout() {
return java.time.Duration.ofMinutes(30);
public static Duration provideRdeUploadLockTimeout() {
return Duration.ofMinutes(30);
}
/**
@@ -805,8 +805,8 @@ public final class RegistryConfig {
*/
@Provides
@Config("rdeUploadSftpCooldown")
public static java.time.Duration provideRdeUploadSftpCooldown() {
return java.time.Duration.ofHours(2);
public static Duration provideRdeUploadSftpCooldown() {
return Duration.ofHours(2);
}
/**
@@ -841,8 +841,8 @@ public final class RegistryConfig {
*/
@Provides
@Config("sheetLockTimeout")
public static java.time.Duration provideSheetLockTimeout() {
return java.time.Duration.ofHours(1);
public static Duration provideSheetLockTimeout() {
return Duration.ofHours(1);
}
/**
@@ -865,8 +865,8 @@ public final class RegistryConfig {
*/
@Provides
@Config("emailThrottleDuration")
public static java.time.Duration provideEmailThrottleSeconds(RegistryConfigSettings config) {
return java.time.Duration.ofSeconds(config.misc.emailThrottleSeconds);
public static Duration provideEmailThrottleSeconds(RegistryConfigSettings config) {
return Duration.ofSeconds(config.misc.emailThrottleSeconds);
}
/**
@@ -946,8 +946,8 @@ public final class RegistryConfig {
*/
@Provides
@Config("sshTimeout")
public static java.time.Duration provideSshTimeout() {
return java.time.Duration.ofSeconds(30);
public static Duration provideSshTimeout() {
return Duration.ofSeconds(30);
}
/**
@@ -957,8 +957,8 @@ public final class RegistryConfig {
*/
@Provides
@Config("transactionCooldown")
public static java.time.Duration provideTransactionCooldown() {
return java.time.Duration.ofMinutes(5);
public static Duration provideTransactionCooldown() {
return Duration.ofMinutes(5);
}
/**
@@ -1034,7 +1034,7 @@ public final class RegistryConfig {
@Provides
@Config("metricsWriteInterval")
public static Duration provideMetricsWriteInterval(RegistryConfigSettings config) {
return Duration.standardSeconds(config.monitoring.writeIntervalSeconds);
return Duration.ofSeconds(config.monitoring.writeIntervalSeconds);
}
/**
@@ -1148,8 +1148,8 @@ public final class RegistryConfig {
@Provides
@Config("tokenRefreshDelay")
public static java.time.Duration provideTokenRefreshDelay(RegistryConfigSettings config) {
return java.time.Duration.ofSeconds(config.credentialOAuth.tokenRefreshDelaySeconds);
public static Duration provideTokenRefreshDelay(RegistryConfigSettings config) {
return Duration.ofSeconds(config.credentialOAuth.tokenRefreshDelaySeconds);
}
/** OAuth client ID used by the nomulus tool. */
@@ -1186,28 +1186,28 @@ public final class RegistryConfig {
@Provides
@Config("maxValidityDaysSchedule")
public static ImmutableSortedMap<DateTime, Integer> provideValidityDaysMap(
public static ImmutableSortedMap<Instant, Integer> provideValidityDaysMap(
RegistryConfigSettings config) {
return config.sslCertificateValidation.maxValidityDaysSchedule.entrySet().stream()
.collect(
toImmutableSortedMap(
naturalOrder(),
e ->
"START_OF_TIME".equals(e.getKey())
? START_OF_TIME
: DateTime.parse(e.getKey()),
"START_INSTANT".equals(e.getKey())
? START_INSTANT
: Instant.parse(e.getKey()),
Entry::getValue));
}
@Provides
@Config("expirationWarningDays")
public static int provideExpirationWarningDays(RegistryConfigSettings config) {
public static long provideExpirationWarningDays(RegistryConfigSettings config) {
return config.sslCertificateValidation.expirationWarningDays;
}
@Provides
@Config("expirationWarningIntervalDays")
public static int provideExpirationWarningIntervalDays(RegistryConfigSettings config) {
public static long provideExpirationWarningIntervalDays(RegistryConfigSettings config) {
return config.sslCertificateValidation.expirationWarningIntervalDays;
}
@@ -1327,15 +1327,15 @@ public final class RegistryConfig {
@Provides
@Config("bsaLockLeaseExpiry")
public static java.time.Duration provideBsaLockLeaseExpiry(RegistryConfigSettings config) {
return java.time.Duration.ofMinutes(config.bsa.bsaLockLeaseExpiryMinutes);
public static Duration provideBsaLockLeaseExpiry(RegistryConfigSettings config) {
return Duration.ofMinutes(config.bsa.bsaLockLeaseExpiryMinutes);
}
/** Returns the desired interval between successive BSA downloads. */
@Provides
@Config("bsaDownloadInterval")
public static java.time.Duration provideBsaDownloadInterval(RegistryConfigSettings config) {
return java.time.Duration.ofMinutes(config.bsa.bsaDownloadIntervalMinutes);
public static Duration provideBsaDownloadInterval(RegistryConfigSettings config) {
return Duration.ofMinutes(config.bsa.bsaDownloadIntervalMinutes);
}
/**
@@ -1344,8 +1344,8 @@ public final class RegistryConfig {
*/
@Provides
@Config("bsaMaxNopInterval")
public static java.time.Duration provideBsaMaxNopInterval(RegistryConfigSettings config) {
return java.time.Duration.ofHours(config.bsa.bsaMaxNopIntervalHours);
public static Duration provideBsaMaxNopInterval(RegistryConfigSettings config) {
return Duration.ofHours(config.bsa.bsaMaxNopIntervalHours);
}
@Provides
@@ -1356,16 +1356,14 @@ public final class RegistryConfig {
@Provides
@Config("domainCreateTxnCommitTimeLag")
public static java.time.Duration provideDomainCreateTxnCommitTimeLag(
RegistryConfigSettings config) {
return java.time.Duration.ofSeconds(config.bsa.domainCreateTxnCommitTimeLagSeconds);
public static Duration provideDomainCreateTxnCommitTimeLag(RegistryConfigSettings config) {
return Duration.ofSeconds(config.bsa.domainCreateTxnCommitTimeLagSeconds);
}
@Provides
@Config("bsaValidationMaxStaleness")
public static java.time.Duration provideBsaValidationMaxStaleness(
RegistryConfigSettings config) {
return java.time.Duration.ofSeconds(config.bsa.bsaValidationMaxStalenessSeconds);
public static Duration provideBsaValidationMaxStaleness(RegistryConfigSettings config) {
return Duration.ofSeconds(config.bsa.bsaValidationMaxStalenessSeconds);
}
@Provides
@@ -1376,8 +1374,8 @@ public final class RegistryConfig {
@Provides
@Config("bsaAuthTokenExpiry")
public static java.time.Duration provideBsaAuthTokenExpiry(RegistryConfigSettings config) {
return java.time.Duration.ofSeconds(config.bsa.authTokenExpirySeconds);
public static Duration provideBsaAuthTokenExpiry(RegistryConfigSettings config) {
return Duration.ofSeconds(config.bsa.authTokenExpirySeconds);
}
@Provides
@@ -1490,8 +1488,8 @@ public final class RegistryConfig {
*
* @see google.registry.tools.server.GenerateZoneFilesAction
*/
public static java.time.Duration getDatabaseRetention() {
return java.time.Duration.ofDays(30);
public static Duration getDatabaseRetention() {
return Duration.ofDays(30);
}
public static boolean areServersLocal() {
@@ -1507,8 +1505,8 @@ public final class RegistryConfig {
}
/** Returns the amount of time a singleton should be cached, before expiring. */
public static java.time.Duration getSingletonCacheRefreshDuration() {
return java.time.Duration.ofSeconds(CONFIG_SETTINGS.get().caching.singletonCacheRefreshSeconds);
public static Duration getSingletonCacheRefreshDuration() {
return Duration.ofSeconds(CONFIG_SETTINGS.get().caching.singletonCacheRefreshSeconds);
}
/**
@@ -1517,13 +1515,13 @@ public final class RegistryConfig {
* @see google.registry.model.tld.label.ReservedList
* @see google.registry.model.tld.label.PremiumList
*/
public static java.time.Duration getDomainLabelListCacheDuration() {
return java.time.Duration.ofSeconds(CONFIG_SETTINGS.get().caching.domainLabelCachingSeconds);
public static Duration getDomainLabelListCacheDuration() {
return Duration.ofSeconds(CONFIG_SETTINGS.get().caching.domainLabelCachingSeconds);
}
/** Returns the amount of time a singleton should be cached in persist mode, before expiring. */
public static java.time.Duration getSingletonCachePersistDuration() {
return java.time.Duration.ofSeconds(CONFIG_SETTINGS.get().caching.singletonCachePersistSeconds);
public static Duration getSingletonCachePersistDuration() {
return Duration.ofSeconds(CONFIG_SETTINGS.get().caching.singletonCachePersistSeconds);
}
/**
@@ -1545,8 +1543,8 @@ public final class RegistryConfig {
/**
* Returns the amount of time an EPP resource or key should be cached in memory before expiring.
*/
public static java.time.Duration getEppResourceCachingDuration() {
return java.time.Duration.ofSeconds(CONFIG_SETTINGS.get().caching.eppResourceCachingSeconds);
public static Duration getEppResourceCachingDuration() {
return Duration.ofSeconds(CONFIG_SETTINGS.get().caching.eppResourceCachingSeconds);
}
/** Returns the maximum number of EPP resources and keys to keep in in-memory cache. */
@@ -1555,8 +1553,8 @@ public final class RegistryConfig {
}
/** Returns the amount of time that a particular claims list should be cached. */
public static java.time.Duration getClaimsListCacheDuration() {
return java.time.Duration.ofSeconds(CONFIG_SETTINGS.get().caching.claimsListCachingSeconds);
public static Duration getClaimsListCacheDuration() {
return Duration.ofSeconds(CONFIG_SETTINGS.get().caching.claimsListCachingSeconds);
}
/** Returns the email address that outgoing emails from the app are sent from. */
@@ -214,8 +214,8 @@ public class RegistryConfigSettings {
/** Configuration for the certificate checker. */
public static class SslCertificateValidation {
public Map<String, Integer> maxValidityDaysSchedule;
public int expirationWarningDays;
public int expirationWarningIntervalDays;
public long expirationWarningDays;
public long expirationWarningIntervalDays;
public int minimumRsaKeyLength;
public Set<String> allowedEcdsaCurves;
public String expirationWarningEmailBodyText;
@@ -476,7 +476,7 @@ sslCertificateValidation:
# The entry key is the date closest before the date the certificate was issued
# and the entry value is the applicable maximum validity days for that certificate.
maxValidityDaysSchedule:
"START_OF_TIME": 825
"START_INSTANT": 825
"2020-09-01T00:00:00Z": 398
# The number of days before a certificate expires that indicates the
# certificate is nearing expiration and warnings should be sent.
@@ -17,7 +17,6 @@ package google.registry.dns;
import static com.google.common.collect.ImmutableList.toImmutableList;
import static google.registry.persistence.PersistenceModule.TransactionIsolationLevel.TRANSACTION_REPEATABLE_READ;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.util.DateTimeUtils.toJavaDuration;
import com.google.common.collect.ImmutableCollection;
import com.google.common.collect.ImmutableList;
@@ -151,7 +150,7 @@ public final class DnsUtils {
if (tldName.isPresent()) {
Tld tld = Tld.get(tldName.get().toString());
if (tld.getDnsAPlusAaaaTtl().isPresent()) {
dnsAPlusAaaaTtl = toJavaDuration(tld.getDnsAPlusAaaaTtl().get());
dnsAPlusAaaaTtl = tld.getDnsAPlusAaaaTtl().get();
}
}
return dnsAPlusAaaaTtl.toSeconds();
@@ -44,7 +44,6 @@ import google.registry.model.tld.Tld;
import google.registry.model.tld.Tlds;
import google.registry.util.Clock;
import google.registry.util.Concurrent;
import google.registry.util.DateTimeUtils;
import google.registry.util.Retrier;
import jakarta.inject.Inject;
import jakarta.inject.Named;
@@ -151,7 +150,6 @@ public class CloudDnsWriter extends BaseDnsWriter {
.setTtl(
(int)
tld.getDnsDsTtl()
.map(DateTimeUtils::toJavaDuration)
.orElse(defaultDsTtl)
.toSeconds())
.setType("DS")
@@ -179,7 +177,6 @@ public class CloudDnsWriter extends BaseDnsWriter {
.setTtl(
(int)
tld.getDnsNsTtl()
.map(DateTimeUtils::toJavaDuration)
.orElse(defaultNsTtl)
.toSeconds())
.setType("NS")
@@ -34,7 +34,6 @@ import google.registry.model.host.Host;
import google.registry.model.tld.Tld;
import google.registry.model.tld.Tlds;
import google.registry.util.Clock;
import google.registry.util.DateTimeUtils;
import jakarta.inject.Inject;
import java.io.IOException;
import java.net.Inet4Address;
@@ -196,7 +195,6 @@ public class DnsUpdateWriter extends BaseDnsWriter {
toAbsoluteName(domain.getDomainName()),
DClass.IN,
tld.getDnsDsTtl()
.map(DateTimeUtils::toJavaDuration)
.orElse(dnsDefaultDsTtl)
.toSeconds(),
signerData.getKeyTag(),
@@ -239,7 +237,6 @@ public class DnsUpdateWriter extends BaseDnsWriter {
toAbsoluteName(domain.getDomainName()),
DClass.IN,
tld.getDnsNsTtl()
.map(DateTimeUtils::toJavaDuration)
.orElse(dnsDefaultNsTtl)
.toSeconds(),
toAbsoluteName(hostName));
@@ -60,7 +60,8 @@ public class CheckApiMetrics {
}
public void recordProcessingTime(CheckApiMetric metric) {
long elapsedTime = metric.endTimestamp().getMillis() - metric.startTimestamp().getMillis();
long elapsedTime =
metric.endTimestamp().toEpochMilli() - metric.startTimestamp().toEpochMilli();
processingTime.record(
elapsedTime,
metric.tier().map(Tier::getDisplayLabel).orElse(""),
@@ -98,7 +98,7 @@ public class EppMetrics {
String eppStatusCode =
metric.getStatus().isPresent() ? String.valueOf(metric.getStatus().get().code) : "";
long processingTime =
metric.getEndTimestamp().getMillis() - metric.getStartTimestamp().getMillis();
metric.getEndTimestamp().toEpochMilli() - metric.getStartTimestamp().toEpochMilli();
String commandName = metric.getCommandName().orElse("");
String tld = metric.getTld().orElse("");
requestTime.record(processingTime, commandName, getTrafficType(tld).toString(), eppStatusCode);
@@ -15,15 +15,15 @@
package google.registry.flows.certs;
import static com.google.common.base.Preconditions.checkArgument;
import static google.registry.util.DateTimeUtils.START_OF_TIME;
import static google.registry.util.DateTimeUtils.toDateTime;
import static google.registry.util.DateTimeUtils.START_INSTANT;
import static google.registry.util.DateTimeUtils.plusDays;
import static google.registry.util.DateTimeUtils.toLocalDate;
import static java.nio.charset.StandardCharsets.UTF_8;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSortedMap;
import google.registry.config.RegistryConfig.Config;
import google.registry.util.Clock;
import google.registry.util.DateTimeUtils;
import jakarta.inject.Inject;
import java.io.ByteArrayInputStream;
import java.io.StringWriter;
@@ -33,6 +33,8 @@ import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.security.interfaces.ECPublicKey;
import java.security.interfaces.RSAPublicKey;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.stream.Collectors;
import org.bouncycastle.jcajce.provider.asymmetric.util.EC5Util;
import org.bouncycastle.jce.ECNamedCurveTable;
@@ -41,51 +43,49 @@ import org.bouncycastle.jce.spec.ECParameterSpec;
import org.bouncycastle.openssl.jcajce.JcaMiscPEMGenerator;
import org.bouncycastle.util.io.pem.PemObjectGenerator;
import org.bouncycastle.util.io.pem.PemWriter;
import org.joda.time.DateTime;
import org.joda.time.DateTimeComparator;
import org.joda.time.Days;
/** A utility to check that a given certificate meets our requirements */
public class CertificateChecker {
private final ImmutableSortedMap<DateTime, Integer> maxValidityLengthSchedule;
private final int expirationWarningDays;
private final ImmutableSortedMap<Instant, Integer> maxValidityLengthSchedule;
private final long expirationWarningDays;
private final int minimumRsaKeyLength;
private final Clock clock;
private final ImmutableSet<String> allowedEcdsaCurves;
private final int expirationWarningIntervalDays;
private final long expirationWarningIntervalDays;
/**
* Constructs a CertificateChecker instance with the specified configuration parameters.
*
* <p>The max validity length schedule is a sorted map of {@link DateTime} to {@link Integer}
* <p>The max validity length schedule is a sorted map of {@link Instant} to {@link Integer}
* entries representing a maximum validity period for certificates issued on or after that date.
* The first entry must have a key of {@link DateTimeUtils#START_OF_TIME}, such that every
* possible date has an applicable max validity period. Since security requirements tighten over
* time, the max validity periods will be decreasing as the date increases.
* The first entry must have a key of {@link google.registry.util.DateTimeUtils#START_INSTANT},
* such that every possible date has an applicable max validity period. Since security
* requirements tighten over time, the max validity periods will be decreasing as the date
* increases.
*
* <p>The validity length schedule used by all major Web browsers as of 2020Q4 would be
* represented as:
*
* <pre>
* ImmutableSortedMap.of(
* START_OF_TIME, 825,
* DateTime.parse("2020-09-01T00:00:00Z"), 398
* START_INSTANT, 825,
* Instant.parse("2020-09-01T00:00:00Z"), 398
* );
* </pre>
*/
@Inject
public CertificateChecker(
@Config("maxValidityDaysSchedule")
ImmutableSortedMap<DateTime, Integer> maxValidityDaysSchedule,
@Config("expirationWarningDays") int expirationWarningDays,
@Config("expirationWarningIntervalDays") int expirationWarningIntervalDays,
ImmutableSortedMap<Instant, Integer> maxValidityDaysSchedule,
@Config("expirationWarningDays") long expirationWarningDays,
@Config("expirationWarningIntervalDays") long expirationWarningIntervalDays,
@Config("minimumRsaKeyLength") int minimumRsaKeyLength,
@Config("allowedEcdsaCurves") ImmutableSet<String> allowedEcdsaCurves,
Clock clock) {
checkArgument(
maxValidityDaysSchedule.containsKey(START_OF_TIME),
"Max validity length schedule must contain an entry for START_OF_TIME");
maxValidityDaysSchedule.containsKey(START_INSTANT),
"Max validity length schedule must contain an entry for START_INSTANT");
this.maxValidityLengthSchedule = maxValidityDaysSchedule;
this.expirationWarningDays = expirationWarningDays;
this.minimumRsaKeyLength = minimumRsaKeyLength;
@@ -94,10 +94,10 @@ public class CertificateChecker {
this.clock = clock;
}
private static int getValidityLengthInDays(X509Certificate certificate) {
DateTime start = toDateTime(certificate.getNotBefore().toInstant());
DateTime end = toDateTime(certificate.getNotAfter().toInstant());
return Days.daysBetween(start.withTimeAtStartOfDay(), end.withTimeAtStartOfDay()).getDays();
private static long getValidityLengthInDays(X509Certificate certificate) {
return ChronoUnit.DAYS.between(
toLocalDate(certificate.getNotBefore().toInstant()),
toLocalDate(certificate.getNotAfter().toInstant()));
}
/** Checks if the curve used for a public key is in the list of acceptable curves. */
@@ -159,16 +159,16 @@ public class CertificateChecker {
ImmutableSet.Builder<CertificateViolation> violations = new ImmutableSet.Builder<>();
// Check if currently in validity period
DateTime now = clock.nowUtc();
if (DateTimeComparator.getInstance().compare(certificate.getNotAfter(), now) < 0) {
Instant now = clock.now();
if (certificate.getNotAfter().toInstant().isBefore(now)) {
violations.add(CertificateViolation.EXPIRED);
} else if (DateTimeComparator.getInstance().compare(certificate.getNotBefore(), now) > 0) {
} else if (certificate.getNotBefore().toInstant().isAfter(now)) {
violations.add(CertificateViolation.NOT_YET_VALID);
}
// Check validity period length
int maxValidityDays =
maxValidityLengthSchedule.floorEntry(new DateTime(certificate.getNotBefore())).getValue();
long maxValidityDays =
maxValidityLengthSchedule.floorEntry(certificate.getNotBefore().toInstant()).getValue();
if (getValidityLengthInDays(certificate) > maxValidityDays) {
violations.add(CertificateViolation.VALIDITY_LENGTH_TOO_LONG);
}
@@ -225,25 +225,24 @@ public class CertificateChecker {
/** Returns whether the client should receive a notification email. */
public boolean shouldReceiveExpiringNotification(
DateTime lastExpiringNotificationSentDate, String certificateStr) {
Instant lastExpiringNotificationSentDate, String certificateStr) {
X509Certificate certificate = getCertificate(certificateStr);
DateTime now = clock.nowUtc();
Instant now = clock.now();
// the expiration date is one day after lastValidDate
DateTime lastValidDate = new DateTime(certificate.getNotAfter());
Instant lastValidDate = certificate.getNotAfter().toInstant();
if (lastValidDate.isBefore(now)) {
return false;
}
/*
* Client should receive a notification if:
* 1) client has never received notification (lastExpiringNotificationSentDate is initially
* set to START_OF_TIME) and the certificate has entered the expiring period, OR
* set to START_INSTANT) and the certificate has entered the expiring period, OR
* 2) client has received notification but the interval between now and
* lastExpiringNotificationSentDate is greater than expirationWarningIntervalDays.
*/
return !lastValidDate.isAfter(now.plusDays(expirationWarningDays))
&& (lastExpiringNotificationSentDate.equals(START_OF_TIME)
|| !lastExpiringNotificationSentDate
.plusDays(expirationWarningIntervalDays)
return !lastValidDate.isAfter(plusDays(now, expirationWarningDays))
&& (lastExpiringNotificationSentDate.equals(START_INSTANT)
|| !plusDays(lastExpiringNotificationSentDate, expirationWarningIntervalDays)
.isAfter(now));
}
@@ -53,7 +53,6 @@ import static google.registry.model.tld.label.ReservationType.NAME_COLLISION;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.util.DateTimeUtils.END_INSTANT;
import static google.registry.util.DateTimeUtils.plusYears;
import static google.registry.util.DateTimeUtils.toInstant;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
@@ -121,10 +120,9 @@ import google.registry.model.tmch.ClaimsList;
import google.registry.model.tmch.ClaimsListDao;
import google.registry.tmch.LordnTaskUtils.LordnPhase;
import jakarta.inject.Inject;
import java.time.Duration;
import java.time.Instant;
import java.util.Optional;
import org.joda.time.DateTime;
import org.joda.time.Duration;
/**
* An EPP flow that creates a new domain resource.
@@ -565,7 +563,7 @@ public final class DomainCreateFlow implements MutatingFlow {
ImmutableSet.of(
DomainTransactionRecord.create(
tld.getTldStr(),
now.plusMillis(addGracePeriod.getMillis()),
now.plus(addGracePeriod),
TransactionReportField.netAddsFieldFromYears(period.getValue()),
1)));
}
@@ -603,11 +601,10 @@ public final class DomainCreateFlow implements MutatingFlow {
.setEventTime(now)
.setAllocationToken(allocationToken.map(AllocationToken::createVKey).orElse(null))
.setBillingTime(
now.plusMillis(
(isAnchorTenant
? tld.getAnchorTenantAddGracePeriodLength()
: tld.getAddGracePeriodLength())
.getMillis()))
now.plus(
isAnchorTenant
? tld.getAnchorTenantAddGracePeriodLength()
: tld.getAddGracePeriodLength()))
.setFlags(flagsBuilder.build())
.setDomainHistoryId(domainHistoryId)
.build();
@@ -652,10 +649,9 @@ public final class DomainCreateFlow implements MutatingFlow {
}
private void verifyDomainDoesNotExist() throws ResourceCreateContentionException {
Optional<DateTime> previousDeletionTime =
Optional<Instant> previousDeletionTime =
domainDeletionTimeCache.getDeletionTimeForDomain(targetId);
if (previousDeletionTime.isPresent()
&& !tm().getTxTime().isAfter(toInstant(previousDeletionTime.get()))) {
if (previousDeletionTime.isPresent() && !tm().getTxTime().isAfter(previousDeletionTime.get())) {
throw new ResourceCreateContentionException(targetId);
}
}
@@ -40,9 +40,7 @@ import static google.registry.persistence.transaction.TransactionManagerFactory.
import static google.registry.pricing.PricingEngineProxy.getDomainRenewCost;
import static google.registry.util.CollectionUtils.nullToEmpty;
import static google.registry.util.CollectionUtils.union;
import static google.registry.util.DateTimeUtils.toDateTime;
import static google.registry.util.DateTimeUtils.toInstant;
import static java.time.ZoneOffset.UTC;
import static google.registry.util.DateTimeUtils.minusYears;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
@@ -101,14 +99,13 @@ import google.registry.model.tld.Tld;
import google.registry.model.tld.Tld.TldType;
import google.registry.model.transfer.TransferStatus;
import jakarta.inject.Inject;
import java.time.Duration;
import java.time.Instant;
import java.util.Collections;
import java.util.Optional;
import java.util.Set;
import javax.annotation.Nullable;
import org.joda.money.Money;
import org.joda.time.DateTime;
import org.joda.time.Duration;
/**
* An EPP flow that deletes a domain.
@@ -172,10 +169,9 @@ public final class DomainDeleteFlow implements MutatingFlow, SqlStatementLogging
eppInput.getSingleExtension(DomainDeleteSuperuserExtension.class);
if (domainDeleteSuperuserExtension.isPresent()) {
redemptionGracePeriodLength =
Duration.standardDays(
domainDeleteSuperuserExtension.get().getRedemptionGracePeriodDays());
Duration.ofDays(domainDeleteSuperuserExtension.get().getRedemptionGracePeriodDays());
pendingDeleteLength =
Duration.standardDays(domainDeleteSuperuserExtension.get().getPendingDeleteDays());
Duration.ofDays(domainDeleteSuperuserExtension.get().getPendingDeleteDays());
}
boolean inAddGracePeriod =
existingDomain.getGracePeriodStatuses().contains(GracePeriodStatus.ADD);
@@ -188,11 +184,11 @@ public final class DomainDeleteFlow implements MutatingFlow, SqlStatementLogging
: redemptionGracePeriodLength.plus(pendingDeleteLength);
HistoryEntryId domainHistoryId = createHistoryEntryId(existingDomain);
historyBuilder.setRevisionId(domainHistoryId.getRevisionId());
Instant deletionTime = now.plusMillis(durationUntilDelete.getMillis());
Instant deletionTime = now.plus(durationUntilDelete);
if (durationUntilDelete.equals(Duration.ZERO)) {
builder.setDeletionTime(now).setStatusValues(null);
} else {
Instant redemptionTime = now.plusMillis(redemptionGracePeriodLength.getMillis());
Instant redemptionTime = now.plus(redemptionGracePeriodLength);
asyncTaskEnqueuer.enqueueAsyncResave(
existingDomain.createVKey(), now, ImmutableSortedSet.of(redemptionTime, deletionTime));
builder
@@ -217,7 +213,7 @@ public final class DomainDeleteFlow implements MutatingFlow, SqlStatementLogging
// Enqueue the deletion poll message if the delete is asynchronous or if requested by a
// superuser (i.e. the registrar didn't request this delete and thus should be notified even if
// it is synchronous).
if (durationUntilDelete.isLongerThan(Duration.ZERO) || isSuperuser) {
if (durationUntilDelete.compareTo(Duration.ZERO) > 0 || isSuperuser) {
if (RegistryConfig.getNoPollMessageOnDeletionRegistrarIds()
.contains(existingDomain.getCurrentSponsorRegistrarId())) {
logger.atInfo().log(
@@ -233,7 +229,7 @@ public final class DomainDeleteFlow implements MutatingFlow, SqlStatementLogging
// Send a second poll message immediately if the domain is being deleted asynchronously by a
// registrar other than the sponsoring registrar (which will necessarily be a superuser).
if (durationUntilDelete.isLongerThan(Duration.ZERO)
if (durationUntilDelete.compareTo(Duration.ZERO) > 0
&& !registrarId.equals(existingDomain.getPersistedCurrentSponsorRegistrarId())) {
entitiesToInsert.add(
createImmediateDeletePollMessage(existingDomain, domainHistoryId, now, deletionTime));
@@ -250,12 +246,11 @@ public final class DomainDeleteFlow implements MutatingFlow, SqlStatementLogging
// Take the amount of registration time being refunded off the expiration time.
// This can be either add grace periods or renew grace periods.
BillingEvent billingEvent = tm().loadByKey(gracePeriod.getBillingEvent());
newExpirationTime =
newExpirationTime.atZone(UTC).minusYears(billingEvent.getPeriodYears()).toInstant();
newExpirationTime = minusYears(newExpirationTime, billingEvent.getPeriodYears());
} else if (gracePeriod.getBillingRecurrence() != null) {
// Take 1 year off the registration if in the autorenew grace period (no need to load the
// recurrence billing event; all autorenews are for 1 year).
newExpirationTime = newExpirationTime.atZone(UTC).minusYears(1).toInstant();
newExpirationTime = minusYears(newExpirationTime, 1);
}
}
}
@@ -343,7 +338,7 @@ public final class DomainDeleteFlow implements MutatingFlow, SqlStatementLogging
cancelledRecords,
DomainTransactionRecord.create(
domain.getTld(),
now.plusMillis(durationUntilDelete.getMillis()),
now.plus(durationUntilDelete),
inAddGracePeriod
? TransactionReportField.DELETED_DOMAINS_GRACE
: TransactionReportField.DELETED_DOMAINS_NOGRACE,
@@ -420,9 +415,9 @@ public final class DomainDeleteFlow implements MutatingFlow, SqlStatementLogging
BillingRecurrence billingRecurrence, GracePeriod gracePeriod, Instant now) {
if (gracePeriod.getType() == GracePeriodStatus.AUTO_RENEW) {
// If we updated the autorenew billing event, reuse it.
DateTime autoRenewTime =
toDateTime(billingRecurrence.getRecurrenceTimeOfYear().getLastInstanceBeforeOrAt(now));
return getDomainRenewCost(targetId, toInstant(autoRenewTime), 1);
Instant autoRenewTime =
billingRecurrence.getRecurrenceTimeOfYear().getLastInstanceBeforeOrAt(now);
return getDomainRenewCost(targetId, autoRenewTime, 1);
}
return tm().loadByKey(checkNotNull(gracePeriod.getBillingEvent())).getCost();
}
@@ -15,6 +15,7 @@
package google.registry.flows.domain;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.util.DateTimeUtils.END_INSTANT;
import com.github.benmanes.caffeine.cache.CacheLoader;
import com.github.benmanes.caffeine.cache.Caffeine;
@@ -24,9 +25,10 @@ import com.github.benmanes.caffeine.cache.Ticker;
import com.google.common.collect.ImmutableSet;
import google.registry.model.ForeignKeyUtils;
import google.registry.model.domain.Domain;
import google.registry.util.DateTimeUtils;
import java.time.Duration;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.Optional;
import org.joda.time.DateTime;
/**
* Functionally-static loading cache that keeps track of deletion (AKA drop) times for domains.
@@ -39,7 +41,7 @@ import org.joda.time.DateTime;
*
* <p>The cache is fairly short-lived (as we're concerned about many requests at basically the same
* time), and entries also expire when the drop actually happens. If the domain is re-created after
* a drop, the next load attempt will populate the cache with a deletion time of END_OF_TIME, which
* a drop, the next load attempt will populate the cache with a deletion time of END_INSTANT, which
* will be read from the cache by subsequent attempts.
*
* <p>We take advantage of the fact that Caffeine caches don't store nulls returned from the
@@ -57,8 +59,7 @@ import org.joda.time.DateTime;
public class DomainDeletionTimeCache {
// Max expiry time is ten minutes
private static final long NANOS_IN_ONE_MILLISECOND = 100000L;
private static final long MAX_EXPIRY_NANOS = 10L * 60L * 1000L * NANOS_IN_ONE_MILLISECOND;
private static final long MAX_EXPIRY_NANOS = Duration.ofMinutes(10).toNanos();
private static final int MAX_ENTRIES = 500;
/**
@@ -69,15 +70,15 @@ public class DomainDeletionTimeCache {
*
* <p>NB: the Expiry class requires the return value in <b>nanoseconds</b>, not milliseconds
*/
private static final Expiry<String, DateTime> EXPIRY_POLICY =
private static final Expiry<String, Instant> EXPIRY_POLICY =
new Expiry<>() {
@Override
public long expireAfterCreate(String key, DateTime value, long currentTime) {
public long expireAfterCreate(String key, Instant value, long currentTime) {
// Watch out for Long overflow
long deletionTimeNanos =
value.equals(DateTimeUtils.END_OF_TIME)
value.equals(END_INSTANT)
? Long.MAX_VALUE
: value.getMillis() * NANOS_IN_ONE_MILLISECOND;
: ChronoUnit.NANOS.between(Instant.EPOCH, value);
long nanosUntilDeletion = deletionTimeNanos - currentTime;
return Math.max(0L, Math.min(MAX_EXPIRY_NANOS, nanosUntilDeletion));
}
@@ -85,31 +86,31 @@ public class DomainDeletionTimeCache {
/** Reset the time entirely on update, as if we were creating the entry anew. */
@Override
public long expireAfterUpdate(
String key, DateTime value, long currentTime, long currentDuration) {
String key, Instant value, long currentTime, long currentDuration) {
return expireAfterCreate(key, value, currentTime);
}
/** Reads do not change the expiry duration. */
@Override
public long expireAfterRead(
String key, DateTime value, long currentTime, long currentDuration) {
String key, Instant value, long currentTime, long currentDuration) {
return currentDuration;
}
};
/** Attempt to load the domain's deletion time if the domain exists. */
private static final CacheLoader<String, DateTime> CACHE_LOADER =
private static final CacheLoader<String, Instant> CACHE_LOADER =
(domainName) -> {
ForeignKeyUtils.MostRecentResource mostRecentResource =
ForeignKeyUtils.loadMostRecentResources(
Domain.class, ImmutableSet.of(domainName), false)
.get(domainName);
return mostRecentResource == null ? null : mostRecentResource.getDeletionTime();
return mostRecentResource == null ? null : mostRecentResource.deletionTime();
};
// Unfortunately, maintenance tasks aren't necessarily already in a transaction
private static final Ticker TRANSACTION_TIME_TICKER =
() -> tm().reTransact(() -> tm().getTransactionTime().getMillis() * NANOS_IN_ONE_MILLISECOND);
() -> tm().reTransact(() -> ChronoUnit.NANOS.between(Instant.EPOCH, tm().getTxTime()));
public static DomainDeletionTimeCache create() {
return new DomainDeletionTimeCache(
@@ -120,14 +121,14 @@ public class DomainDeletionTimeCache {
.build(CACHE_LOADER));
}
private final LoadingCache<String, DateTime> cache;
private final LoadingCache<String, Instant> cache;
private DomainDeletionTimeCache(LoadingCache<String, DateTime> cache) {
private DomainDeletionTimeCache(LoadingCache<String, Instant> cache) {
this.cache = cache;
}
/** Returns the domain's deletion time, or null if it doesn't currently exist. */
public Optional<DateTime> getDeletionTimeForDomain(String domainName) {
public Optional<Instant> getDeletionTimeForDomain(String domainName) {
return Optional.ofNullable(cache.get(domainName));
}
}
@@ -124,6 +124,7 @@ import google.registry.tldconfig.idn.IdnLabelValidator;
import google.registry.tools.DigestType;
import google.registry.util.Idn;
import java.math.BigDecimal;
import java.time.Duration;
import java.time.Instant;
import java.util.Comparator;
import java.util.List;
@@ -133,7 +134,6 @@ import java.util.Set;
import javax.annotation.Nullable;
import org.joda.money.CurrencyUnit;
import org.joda.money.Money;
import org.joda.time.Duration;
import org.xbill.DNS.DNSSEC.Algorithm;
/** Static utility functions for domain flows. */
@@ -1114,7 +1114,7 @@ public class DomainFlowUtils {
"FROM DomainHistory WHERE modificationTime >= :beginning AND repoId = "
+ ":repoId ORDER BY modificationTime ASC",
DomainHistory.class)
.setParameter("beginning", now.minusMillis(maxSearchPeriod.getMillis()))
.setParameter("beginning", now.minus(maxSearchPeriod))
.setParameter("repoId", domain.getRepoId())
.getResultList();
}
@@ -34,7 +34,7 @@ import static google.registry.flows.domain.token.AllocationTokenFlowUtils.maybeA
import static google.registry.flows.domain.token.AllocationTokenFlowUtils.verifyBulkTokenAllowedOnDomain;
import static google.registry.model.reporting.HistoryEntry.Type.DOMAIN_RENEW;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.util.DateTimeUtils.toDateTime;
import static google.registry.util.DateTimeUtils.toLocalDate;
import static java.time.ZoneOffset.UTC;
import com.google.common.collect.ImmutableList;
@@ -87,10 +87,10 @@ import google.registry.model.reporting.HistoryEntry.HistoryEntryId;
import google.registry.model.reporting.IcannReportingTypes.ActivityReportField;
import google.registry.model.tld.Tld;
import jakarta.inject.Inject;
import java.time.Duration;
import java.time.Instant;
import java.util.Optional;
import org.joda.money.Money;
import org.joda.time.Duration;
/**
* An EPP flow that renews a domain.
@@ -310,7 +310,7 @@ public final class DomainRenewFlow implements MutatingFlow {
ImmutableSet.of(
DomainTransactionRecord.create(
newDomain.getTld(),
now.plusMillis(renewGracePeriod.getMillis()),
now.plus(renewGracePeriod),
TransactionReportField.netRenewsFieldFromYears(period.getValue()),
1)))
.build();
@@ -335,7 +335,7 @@ public final class DomainRenewFlow implements MutatingFlow {
// If the date they specify doesn't match the expiration, fail. (This is an idempotence check).
if (!command
.getCurrentExpirationDate()
.equals(toDateTime(existingDomain.getRegistrationExpirationTime()).toLocalDate())) {
.equals(toLocalDate(existingDomain.getRegistrationExpirationTime()))) {
throw new IncorrectCurrentExpirationDateException();
}
}
@@ -359,7 +359,7 @@ public final class DomainRenewFlow implements MutatingFlow {
.filter(t -> AllocationToken.TokenBehavior.DEFAULT.equals(t.getTokenBehavior()))
.map(AllocationToken::createVKey)
.orElse(null))
.setBillingTime(now.plusMillis(Tld.get(tld).getRenewGracePeriodLength().getMillis()))
.setBillingTime(now.plus(Tld.get(tld).getRenewGracePeriodLength()))
.setDomainHistoryId(domainHistoryId)
.build();
}
@@ -168,8 +168,7 @@ public final class DomainTransferApproveFlow implements MutatingFlow {
hasBulkToken ? null : existingBillingRecurrence)
.getRenewCost())
.setEventTime(now)
.setBillingTime(
now.plusMillis(Tld.get(tldStr).getTransferGracePeriodLength().getMillis()))
.setBillingTime(now.plus(Tld.get(tldStr).getTransferGracePeriodLength()))
.setDomainHistoryId(domainHistoryId)
.build());
@@ -292,7 +291,7 @@ public final class DomainTransferApproveFlow implements MutatingFlow {
cancelingRecords,
DomainTransactionRecord.create(
newDomain.getTld(),
now.plusMillis(tld.getTransferGracePeriodLength().getMillis()),
now.plus(tld.getTransferGracePeriodLength()),
TRANSFER_SUCCESSFUL,
1)))
.build();
@@ -32,7 +32,6 @@ import static google.registry.model.reporting.HistoryEntry.Type.DOMAIN_TRANSFER_
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.util.CollectionUtils.union;
import static google.registry.util.DateTimeUtils.END_INSTANT;
import static google.registry.util.DateTimeUtils.toDateTime;
import com.google.common.collect.ImmutableSet;
import google.registry.flows.EppException;
@@ -108,8 +107,7 @@ public final class DomainTransferRejectFlow implements MutatingFlow {
checkAllowedAccessToTld(registrarId, existingDomain.getTld());
}
Domain newDomain =
denyPendingTransfer(
existingDomain, TransferStatus.CLIENT_REJECTED, toDateTime(now), registrarId);
denyPendingTransfer(existingDomain, TransferStatus.CLIENT_REJECTED, now, registrarId);
DomainHistory domainHistory = buildDomainHistory(newDomain, tld, now);
tm().update(newDomain);
tm().insertAll(
@@ -220,7 +220,7 @@ public final class DomainTransferRequestFlow implements MutatingFlow {
domainTransferRequestSuperuserExtension ->
now.plus(
domainTransferRequestSuperuserExtension.getAutomaticTransferLength(), DAYS))
.orElseGet(() -> now.plusMillis(tld.getAutomaticTransferLength().getMillis()));
.orElseGet(() -> now.plus(tld.getAutomaticTransferLength()));
// If the domain will be in the auto-renew grace period at the moment of transfer, the transfer
// will subsume the autorenew, so we don't add the normal extra year from the transfer.
// The gaining registrar is still billed for the extra year; the losing registrar will get a
@@ -368,8 +368,8 @@ public final class DomainTransferRequestFlow implements MutatingFlow {
ImmutableSet.of(
DomainTransactionRecord.create(
tld.getTldStr(),
now.plusMillis(tld.getAutomaticTransferLength().getMillis())
.plusMillis(tld.getTransferGracePeriodLength().getMillis()),
now.plus(tld.getAutomaticTransferLength())
.plus(tld.getTransferGracePeriodLength()),
TransactionReportField.TRANSFER_SUCCESSFUL,
1)))
.build();
@@ -316,8 +316,7 @@ public final class DomainTransferUtils {
.setCost(transferCost)
.setPeriodYears(1)
.setEventTime(automaticTransferTime)
.setBillingTime(
automaticTransferTime.plusMillis(registry.getTransferGracePeriodLength().getMillis()))
.setBillingTime(automaticTransferTime.plus(registry.getTransferGracePeriodLength()))
.setDomainHistoryId(domainHistoryId)
.build();
}
@@ -33,13 +33,13 @@ import google.registry.request.auth.Auth;
import google.registry.util.Clock;
import google.registry.util.RegistryEnvironment;
import jakarta.inject.Inject;
import java.time.Duration;
import java.time.Instant;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Random;
import java.util.function.Function;
import org.joda.time.DateTime;
/**
* Simple load test action that can generate configurable QPSes of various EPP actions.
@@ -160,7 +160,7 @@ public class LoadTestAction implements Runnable {
@Override
public void run() {
validateAndLogRequest();
DateTime initialStartSecond = clock.nowUtc().plusSeconds(delaySeconds);
Instant initialStartSecond = clock.now().plus(Duration.ofSeconds(delaySeconds));
ImmutableList.Builder<String> preTaskXmls = new ImmutableList.Builder<>();
ImmutableList.Builder<String> hostPrefixesBuilder = new ImmutableList.Builder<>();
for (int i = 0; i < successfulDomainCreatesPerSecond; i++) {
@@ -169,12 +169,12 @@ public class LoadTestAction implements Runnable {
preTaskXmls.add(
xmlHostCreateTmpl.replace("%host%", hostPrefix));
}
enqueue(createTasks(preTaskXmls.build(), clock.nowUtc()));
enqueue(createTasks(preTaskXmls.build(), clock.now()));
ImmutableList<String> hostPrefixes = hostPrefixesBuilder.build();
ImmutableList.Builder<Task> tasks = new ImmutableList.Builder<>();
for (int offsetSeconds = 0; offsetSeconds < runSeconds; offsetSeconds++) {
DateTime startSecond = initialStartSecond.plusSeconds(offsetSeconds);
Instant startSecond = initialStartSecond.plus(Duration.ofSeconds(offsetSeconds));
// The first "failed" creates might actually succeed if the object doesn't already exist, but
// that shouldn't affect the load numbers.
tasks.addAll(
@@ -265,12 +265,11 @@ public class LoadTestAction implements Runnable {
return name.toString();
}
private ImmutableList<Task> createTasks(ImmutableList<String> xmls, DateTime start) {
private ImmutableList<Task> createTasks(ImmutableList<String> xmls, Instant start) {
ImmutableList.Builder<Task> tasks = new ImmutableList.Builder<>();
for (int i = 0; i < xmls.size(); i++) {
// Space tasks evenly within across a second.
Instant scheduleTime =
Instant.ofEpochMilli(start.plusMillis((int) (1000.0 / xmls.size() * i)).getMillis());
Instant scheduleTime = start.plus(Duration.ofMillis((long) (1000.0 / xmls.size() * i)));
tasks.add(
cloudTasksUtils
.createTask(
@@ -42,6 +42,7 @@ import google.registry.model.tld.Tld.TldState;
import google.registry.persistence.VKey;
import java.io.IOException;
import java.math.BigDecimal;
import java.time.Duration;
import java.time.Instant;
import java.util.ArrayList;
import java.util.LinkedHashMap;
@@ -51,7 +52,6 @@ import java.util.Set;
import java.util.SortedMap;
import org.joda.money.CurrencyUnit;
import org.joda.money.Money;
import org.joda.time.Duration;
/** A collection of static utility classes/functions to convert entities to/from YAML files. */
public class EntityYamlUtils {
@@ -337,7 +337,7 @@ public class EntityYamlUtils {
public TimedTransitionProperty<TldState> deserialize(
JsonParser jp, DeserializationContext context) throws IOException {
SortedMap<String, String> valueMap = jp.readValueAs(SortedMap.class);
return TimedTransitionProperty.fromValueMapInstant(
return TimedTransitionProperty.fromValueMap(
valueMap.keySet().stream()
.collect(
toImmutableSortedMap(
@@ -363,7 +363,7 @@ public class EntityYamlUtils {
public TimedTransitionProperty<Money> deserialize(JsonParser jp, DeserializationContext context)
throws IOException {
SortedMap<String, LinkedHashMap<String, Object>> valueMap = jp.readValueAs(SortedMap.class);
return TimedTransitionProperty.fromValueMapInstant(
return TimedTransitionProperty.fromValueMap(
valueMap.keySet().stream()
.collect(
toImmutableSortedMap(
@@ -393,7 +393,7 @@ public class EntityYamlUtils {
public TimedTransitionProperty<FeatureStatus> deserialize(
JsonParser jp, DeserializationContext context) throws IOException {
SortedMap<String, String> valueMap = jp.readValueAs(SortedMap.class);
return TimedTransitionProperty.fromValueMapInstant(
return TimedTransitionProperty.fromValueMap(
valueMap.keySet().stream()
.collect(
toImmutableSortedMap(
@@ -115,7 +115,7 @@ public abstract class EppResource extends UpdateAutoTimestampEntity implements B
* <ul>
* <li>For deleted resources, this is in the past.
* <li>For pending-delete resources, this is in the near future.
* <li>For active resources, this is {@code END_OF_TIME}.
* <li>For active resources, this is {@code END_INSTANT}.
* </ul>
*
* <p>This scheme allows for setting pending deletes in the future and having them magically drop
@@ -20,7 +20,6 @@ import static google.registry.persistence.transaction.TransactionManagerFactory.
import static google.registry.util.DateTimeUtils.START_INSTANT;
import static google.registry.util.DateTimeUtils.isAtOrAfter;
import static google.registry.util.DateTimeUtils.isBeforeOrAt;
import static google.registry.util.DateTimeUtils.toInstant;
import com.google.common.collect.ImmutableSet;
import com.google.common.flogger.FluentLogger;
@@ -39,7 +38,6 @@ import java.time.Instant;
import java.util.Comparator;
import java.util.function.Function;
import javax.annotation.Nullable;
import org.joda.time.DateTime;
/** Utilities for working with {@link EppResource}. */
public final class EppResourceUtils {
@@ -65,18 +63,12 @@ public final class EppResourceUtils {
return String.format("%X-%s", repoId, roidSuffix);
}
/** Helper to call {@link EppResource#cloneProjectedAtTime} without warnings. */
@SuppressWarnings("unchecked")
private static <T extends EppResource> T cloneProjectedAtTime(T resource, DateTime now) {
return (T) resource.cloneProjectedAtTime(toInstant(now));
}
/**
* Returns a Function that transforms an EppResource to the given DateTime, suitable for use with
* Returns a Function that transforms an EppResource to the given Instant, suitable for use with
* Iterables.transform() over a collection of EppResources.
*/
public static <T extends EppResource> Function<T, T> transformAtTime(final DateTime now) {
return (T resource) -> cloneProjectedAtTime(resource, now);
public static <T extends EppResource> Function<T, T> transformAtTime(final Instant now) {
return (T resource) -> (T) resource.cloneProjectedAtTime(now);
}
public static boolean isActive(EppResource resource, Instant time) {
@@ -84,28 +76,10 @@ public final class EppResourceUtils {
&& time.isBefore(resource.getDeletionTime());
}
/**
* @deprecated Use {@link #isActive(EppResource, Instant)}
*/
@Deprecated
@SuppressWarnings("InlineMeSuggester")
public static boolean isActive(EppResource resource, DateTime time) {
return isActive(resource, toInstant(time));
}
public static boolean isDeleted(EppResource resource, Instant time) {
return !isActive(resource, time);
}
/**
* @deprecated Use {@link #isDeleted(EppResource, Instant)}
*/
@Deprecated
@SuppressWarnings("InlineMeSuggester")
public static boolean isDeleted(EppResource resource, DateTime time) {
return isDeleted(resource, toInstant(time));
}
/** Process an automatic transfer on a domain. */
public static void setAutomaticTransferSuccessProperties(
DomainBase.Builder<?, ?> builder, DomainTransferData transferData) {
@@ -173,16 +147,6 @@ public final class EppResourceUtils {
: null);
}
/**
* @deprecated Use {@link #loadAtPointInTime(EppResource, Instant)}
*/
@Deprecated
@SuppressWarnings("InlineMeSuggester")
public static <T extends EppResource> T loadAtPointInTime(
final T resource, final DateTime timestamp) {
return loadAtPointInTime(resource, toInstant(timestamp));
}
/**
* Returns the most recent revision of a given EppResource before or at the provided timestamp,
* falling back to using the resource as-is if there are no revisions.
@@ -207,21 +171,6 @@ public final class EppResourceUtils {
return resourceAtPointInTime;
}
/**
* Returns a set of {@link VKey} for domains that reference a specified host.
*
* @param key the referent key
* @param now the logical time of the check /** Returns the domains that are linked to this host
* at the given time.
* @deprecated Use {@link #getLinkedDomainKeys(VKey, Instant, Integer)}
*/
@Deprecated
@SuppressWarnings("InlineMeSuggester")
public static ImmutableSet<VKey<Domain>> getLinkedDomainKeys(
VKey<Host> key, DateTime now, @Nullable Integer limit) {
return getLinkedDomainKeys(key, toInstant(now), limit);
}
/** Returns the domains that are linked to this host at the given time. */
public static ImmutableSet<VKey<Domain>> getLinkedDomainKeys(
VKey<Host> key, Instant now, @Nullable Integer limit) {
@@ -246,17 +195,6 @@ public final class EppResourceUtils {
});
}
/**
* Returns whether this host is linked to any domains at the given time.
*
* @deprecated Use {@link #isLinked(VKey, Instant)}
*/
@Deprecated
@SuppressWarnings("InlineMeSuggester")
public static boolean isLinked(VKey<Host> key, DateTime now) {
return isLinked(key, toInstant(now));
}
/** Returns whether this resource is linked to any domains at the given time. */
public static boolean isLinked(VKey<Host> key, Instant now) {
return !getLinkedDomainKeys(key, now, 1).isEmpty();
@@ -20,8 +20,6 @@ import static google.registry.config.RegistryConfig.getEppResourceCachingDuratio
import static google.registry.config.RegistryConfig.getEppResourceMaxCachedEntries;
import static google.registry.persistence.transaction.TransactionManagerFactory.replicaTm;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.util.DateTimeUtils.toDateTime;
import static google.registry.util.DateTimeUtils.toInstant;
import com.github.benmanes.caffeine.cache.CacheLoader;
import com.github.benmanes.caffeine.cache.LoadingCache;
@@ -43,7 +41,6 @@ import java.util.Map;
import java.util.Map.Entry;
import java.util.Optional;
import java.util.Set;
import org.joda.time.DateTime;
/**
* Util class for mapping a foreign key to a {@link VKey} or {@link EppResource}.
@@ -65,30 +62,7 @@ public final class ForeignKeyUtils {
Domain.class, "domainName",
Host.class, "hostName");
public record MostRecentResource(String repoId, Instant deletionTime) {
/**
* @deprecated Use {@link #deletionTime()}
*/
@Deprecated
public DateTime getDeletionTime() {
return toDateTime(deletionTime);
}
}
/**
* Loads an optional {@link VKey} to an {@link EppResource} from the database by foreign key.
*
* <p>Returns empty if no resource with this foreign key was ever created, or if the most recently
* created resource was deleted before time "now".
*
* @deprecated Use {@link #loadKey(Class, String, Instant)}
*/
@Deprecated
@SuppressWarnings("InlineMeSuggester")
public static <E extends EppResource> Optional<VKey<E>> loadKey(
Class<E> clazz, String foreignKey, DateTime now) {
return loadKey(clazz, foreignKey, toInstant(now));
}
public record MostRecentResource(String repoId, Instant deletionTime) {}
/**
* Loads an optional {@link VKey} to an {@link EppResource} from the database by foreign key.
@@ -101,21 +75,6 @@ public final class ForeignKeyUtils {
return Optional.ofNullable(loadKeys(clazz, ImmutableList.of(foreignKey), now).get(foreignKey));
}
/**
* Loads an {@link EppResource} from the database by foreign key.
*
* <p>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 Use {@link #loadResource(Class, String, Instant)}
*/
@Deprecated
@SuppressWarnings("InlineMeSuggester")
public static <E extends EppResource> Optional<E> loadResource(
Class<E> clazz, String foreignKey, DateTime now) {
return loadResource(clazz, foreignKey, toInstant(now));
}
/**
* Loads an {@link EppResource} from the database by foreign key.
*
@@ -129,22 +88,6 @@ public final class ForeignKeyUtils {
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.
*
* <p>The returned map will omit any foreign keys for which the {@link EppResource} doesn't exist
* or has been soft-deleted.
*
* @deprecated Use {@link #loadKeys(Class, Collection, Instant)}
*/
@Deprecated
@SuppressWarnings("InlineMeSuggester")
public static <E extends EppResource> ImmutableMap<String, VKey<E>> loadKeys(
Class<E> clazz, Collection<String> foreignKeys, DateTime now) {
return loadKeys(clazz, foreignKeys, toInstant(now));
}
/**
* 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.
@@ -159,20 +102,6 @@ public final class ForeignKeyUtils {
.collect(toImmutableMap(Entry::getKey, e -> VKey.create(clazz, e.getValue().repoId())));
}
/**
* Load a map of {@link String} foreign keys to the {@link EppResource} that are active at or
* after the specified moment in time.
*
* <p>The returned map will omit any foreign keys for which the {@link EppResource} doesn't exist
* or has been soft-deleted.
*/
@SuppressWarnings({"unchecked", "InlineMeSuggester"})
@Deprecated
public static <E extends EppResource> ImmutableMap<String, E> loadResources(
Class<E> clazz, Collection<String> foreignKeys, DateTime now) {
return loadResources(clazz, foreignKeys, toInstant(now));
}
/**
* Load a map of {@link String} foreign keys to the {@link EppResource} that are active at or
* after the specified moment in time.
@@ -198,7 +127,7 @@ public final class ForeignKeyUtils {
* should monotonically increase as one cannot create a domain/host/contact with the same foreign
* key without soft deleting the existing resource first. However, in test, there's no such
* guarantee and one must make sure that no two resources with the same foreign key exist with the
* same max {@code deleteTime}, usually {@code END_OF_TIME}, lest this method throws an error due
* same max {@code deleteTime}, usually {@code END_INSTANT}, lest this method throws an error due
* to duplicate keys.
*/
public static <E extends EppResource>
@@ -322,25 +251,6 @@ public final class ForeignKeyUtils {
foreignKeyToRepoIdCache = createForeignKeyToRepoIdCache(effectiveExpiry);
}
/**
* Load a list of {@link VKey} to {@link EppResource} instances by class and foreign key strings
* that are active at or after the specified moment in time, using the cache if enabled.
*
* <p>The returned map will omit any keys for which the {@link EppResource} doesn't exist or has
* been soft-deleted.
*
* <p>Don't use the cached version of this method unless you really need it for performance
* reasons, and are OK with the trade-offs in loss of transactional consistency.
*
* @deprecated Use {@link #loadKeysByCacheIfEnabled(Class, Collection, Instant)}
*/
@Deprecated
@SuppressWarnings("InlineMeSuggester")
public static <E extends EppResource> ImmutableMap<String, VKey<E>> loadKeysByCacheIfEnabled(
Class<E> clazz, Collection<String> foreignKeys, DateTime now) {
return loadKeysByCacheIfEnabled(clazz, foreignKeys, toInstant(now));
}
/**
* Load a list of {@link VKey} to {@link EppResource} instances by class and foreign key strings
* that are active at or after the specified moment in time, using the cache if enabled.
@@ -367,18 +277,6 @@ public final class ForeignKeyUtils {
e -> VKey.create(clazz, e.getValue().get().repoId())));
}
/**
* Loads an optional {@link VKey} to an {@link EppResource} using the cache.
*
* @deprecated Use {@link #loadKeyByCache(Class, String, Instant)}
*/
@Deprecated
@SuppressWarnings("InlineMeSuggester")
public static <E extends EppResource> Optional<VKey<E>> loadKeyByCache(
Class<E> clazz, String foreignKey, DateTime now) {
return loadKeyByCache(clazz, foreignKey, toInstant(now));
}
/** Loads an optional {@link VKey} to an {@link EppResource} using the cache. */
public static <E extends EppResource> Optional<VKey<E>> loadKeyByCache(
Class<E> clazz, String foreignKey, Instant now) {
@@ -461,33 +359,6 @@ public final class ForeignKeyUtils {
foreignKeyToResourceCache = createForeignKeyToResourceCache(effectiveExpiry);
}
/**
* Loads the last created version of an {@link EppResource} from the database by foreign key,
* using a cache, if caching is enabled in config settings.
*
* <p>Returns null if no resource with this foreign key was ever created, or if the most recently
* created resource was deleted before time "now".
*
* <p>Loading an {@link EppResource} by itself is not sufficient to know its current state since
* it may have various expirable conditions and status values that might implicitly change its
* state as time progresses even if it has not been updated in the database. Rather, the resource
* must be combined with a timestamp to view its current state. We use a global last updated
* timestamp to guarantee monotonically increasing write times, and forward our projected time to
* the greater of this timestamp or "now". This guarantees that we're not projecting into the
* past.
*
* <p>Do not call this cached version for anything that needs transactional consistency. It should
* only be used when it's OK if the data is potentially being out of date, e.g. RDAP.
*
* @deprecated Use {@link #loadResourceByCacheIfEnabled(Class, String, Instant)}
*/
@Deprecated
@SuppressWarnings("InlineMeSuggester")
public static <E extends EppResource> Optional<E> loadResourceByCacheIfEnabled(
Class<E> clazz, String foreignKey, DateTime now) {
return loadResourceByCacheIfEnabled(clazz, foreignKey, toInstant(now));
}
/**
* Loads the last created version of an {@link EppResource} from the database by foreign key,
* using a cache, if caching is enabled in config settings.
@@ -513,22 +384,6 @@ public final class ForeignKeyUtils {
: loadResource(clazz, foreignKey, now);
}
/**
* Loads the last created version of an {@link EppResource} from the replica database by foreign
* key, using a cache.
*
* <p>This method ignores the config setting for caching, and is reserved for use cases that can
* tolerate slightly stale data.
*
* @deprecated Use {@link #loadResourceByCache(Class, String, Instant)}
*/
@Deprecated
@SuppressWarnings("InlineMeSuggester")
public static <E extends EppResource> Optional<E> loadResourceByCache(
Class<E> clazz, String foreignKey, DateTime now) {
return loadResourceByCache(clazz, foreignKey, toInstant(now));
}
/**
* Loads the last created version of an {@link EppResource} from the replica database by foreign
* key, using a cache.
@@ -22,7 +22,6 @@ import static google.registry.model.tld.Tld.TldState.GENERAL_AVAILABILITY;
import static google.registry.model.tld.Tld.TldState.START_DATE_SUNRISE;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.util.DateTimeUtils.START_INSTANT;
import static google.registry.util.DateTimeUtils.toInstant;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
@@ -46,6 +45,7 @@ import google.registry.persistence.VKey;
import google.registry.tools.IamClient;
import google.registry.util.CidrAddressBlock;
import google.registry.util.RegistryEnvironment;
import java.time.Duration;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Collection;
@@ -55,8 +55,6 @@ import java.util.function.Function;
import java.util.regex.Pattern;
import org.joda.money.CurrencyUnit;
import org.joda.money.Money;
import org.joda.time.DateTime;
import org.joda.time.Duration;
/**
* Class to help build and persist all the OT&amp;E entities in the database.
@@ -94,9 +92,9 @@ public final class OteAccountBuilder {
private static final Pattern REGISTRAR_PATTERN = Pattern.compile("^[a-z\\d]{3,14}$");
// Durations are short so that registrars can test with quick transfer (etc.) turnaround.
private static final Duration SHORT_ADD_GRACE_PERIOD = Duration.standardMinutes(60);
private static final Duration SHORT_REDEMPTION_GRACE_PERIOD = Duration.standardMinutes(10);
private static final Duration SHORT_PENDING_DELETE_LENGTH = Duration.standardMinutes(5);
private static final Duration SHORT_ADD_GRACE_PERIOD = Duration.ofMinutes(60);
private static final Duration SHORT_REDEMPTION_GRACE_PERIOD = Duration.ofMinutes(10);
private static final Duration SHORT_PENDING_DELETE_LENGTH = Duration.ofMinutes(5);
private static final String DEFAULT_PREMIUM_LIST = "default_sandbox_list";
@@ -234,8 +232,8 @@ public final class OteAccountBuilder {
}
/** Sets the client certificate to all the OT&amp;E Registrars. */
public OteAccountBuilder setCertificate(String asciiCert, DateTime now) {
return transformRegistrars(builder -> builder.setClientCertificate(asciiCert, toInstant(now)));
public OteAccountBuilder setCertificate(String asciiCert, Instant now) {
return transformRegistrars(builder -> builder.setClientCertificate(asciiCert, now));
}
/** Sets the IP allowlist to all the OT&amp;E Registrars. */
@@ -16,7 +16,6 @@ package google.registry.model;
import static com.google.common.base.Preconditions.checkArgument;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.util.DateTimeUtils.toInstant;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
@@ -33,7 +32,6 @@ import google.registry.model.transfer.TransferResponse;
import google.registry.model.transfer.TransferResponse.DomainTransferResponse;
import google.registry.model.transfer.TransferStatus;
import java.time.Instant;
import org.joda.time.DateTime;
/** Static utility functions for domain transfers. */
public final class ResourceTransferUtils {
@@ -73,20 +71,6 @@ public final class ResourceTransferUtils {
domain.getDomainName(), actionResult, transferRequestTrid, processedDate);
}
/**
* Create a pending action notification response indicating the resolution of a transfer.
*
* @deprecated Use {@link #createPendingTransferNotificationResponse(Domain, Trid, boolean,
* Instant)}
*/
@Deprecated
@SuppressWarnings("InlineMeSuggester")
public static PendingActionNotificationResponse createPendingTransferNotificationResponse(
Domain domain, Trid transferRequestTrid, boolean actionResult, DateTime processedDate) {
return createPendingTransferNotificationResponse(
domain, transferRequestTrid, actionResult, toInstant(processedDate));
}
/** If there is a transfer out, delete the server-approve entities and enqueue a poll message. */
public static void handlePendingTransferOnDelete(
Domain domain, Domain newDomain, Instant now, HistoryEntry historyEntry) {
@@ -109,18 +93,6 @@ public final class ResourceTransferUtils {
.build());
}
/**
* If there is a transfer out, delete the server-approve entities and enqueue a poll message.
*
* @deprecated Use {@link #handlePendingTransferOnDelete(Domain, Domain, Instant, HistoryEntry)}
*/
@Deprecated
@SuppressWarnings("InlineMeSuggester")
public static void handlePendingTransferOnDelete(
Domain domain, Domain newDomain, DateTime now, HistoryEntry historyEntry) {
handlePendingTransferOnDelete(domain, newDomain, toInstant(now), historyEntry);
}
/**
* Turn a domain into a builder with its pending transfer resolved.
*
@@ -165,18 +137,6 @@ public final class ResourceTransferUtils {
.build();
}
/**
* Resolve a pending transfer by awarding it to the gaining client.
*
* @deprecated Use {@link #approvePendingTransfer(Domain, TransferStatus, Instant)}
*/
@Deprecated
@SuppressWarnings("InlineMeSuggester")
public static Domain approvePendingTransfer(
Domain domain, TransferStatus transferStatus, DateTime now) {
return approvePendingTransfer(domain, transferStatus, toInstant(now));
}
/**
* Resolve a pending transfer by denying it.
*
@@ -193,16 +153,4 @@ public final class ResourceTransferUtils {
.setLastEppUpdateRegistrarId(lastEppUpdateRegistrarId)
.build();
}
/**
* Resolve a pending transfer by denying it.
*
* @deprecated Use {@link #denyPendingTransfer(Domain, TransferStatus, Instant, String)}
*/
@Deprecated
@SuppressWarnings("InlineMeSuggester")
public static Domain denyPendingTransfer(
Domain domain, TransferStatus transferStatus, DateTime now, String lastEppUpdateRegistrarId) {
return denyPendingTransfer(domain, transferStatus, toInstant(now), lastEppUpdateRegistrarId);
}
}
@@ -83,9 +83,9 @@ public class BillingRecurrence extends BillingBase {
*
* <p>Note that this is a recurrence of the event time, not the billing time. The billing time can
* be calculated by adding the relevant grace period length to this date. The reason for this
* requirement is that the event time recurs on a {@link org.joda.time.Period} schedule (same day
* of year, which can be 365 or 366 days later) which is what {@link TimeOfYear} can model,
* whereas the billing time is a fixed {@link org.joda.time.Duration} later.
* requirement is that the event time recurs on a year-based schedule (same day of year, which can
* be 365 or 366 days later) which is what {@link TimeOfYear} can model, whereas the billing time
* is a fixed {@link java.time.Duration} later.
*/
@Embedded
@AttributeOverrides(
@@ -20,7 +20,6 @@ import static com.google.common.collect.ImmutableSet.toImmutableSet;
import static google.registry.config.RegistryConfig.getSingletonCacheRefreshDuration;
import static google.registry.model.common.FeatureFlag.FeatureStatus.ACTIVE;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.util.DateTimeUtils.toInstant;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
@@ -32,7 +31,6 @@ import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSortedMap;
import com.google.common.collect.Maps;
import com.google.common.collect.Ordering;
import google.registry.model.Buildable;
import google.registry.model.CacheUtils;
import google.registry.model.EntityYamlUtils.TimedTransitionPropertyFeatureStatusDeserializer;
@@ -49,7 +47,6 @@ import java.util.Map;
import java.util.Optional;
import java.util.Set;
import org.hibernate.annotations.Type;
import org.joda.time.DateTime;
@Entity
public class FeatureFlag extends ImmutableObject implements Buildable {
@@ -182,10 +179,6 @@ public class FeatureFlag extends ImmutableObject implements Buildable {
return status;
}
public FeatureStatus getStatus(DateTime time) {
return getStatus(toInstant(time));
}
public FeatureStatus getStatus(Instant time) {
return status.getValueAtTime(time);
}
@@ -194,24 +187,14 @@ public class FeatureFlag extends ImmutableObject implements Buildable {
* Returns whether the flag is active now, or else the flag's default value if it doesn't exist.
*/
public static boolean isActiveNow(FeatureName featureName) {
tm().assertInTransaction();
return isActiveAt(featureName, tm().getTxTime());
}
/**
* Returns whether the flag is active at the given time, or else the flag's default value if it
* doesn't exist.
*/
public static boolean isActiveAt(FeatureName featureName, DateTime dateTime) {
return isActiveAt(featureName, toInstant(dateTime));
}
/**
* Returns whether the flag is active at the given time, or else the flag's default value if it
* doesn't exist.
*/
public static boolean isActiveAt(FeatureName featureName, Instant instant) {
tm().assertInTransaction();
return CACHE
.get(featureName)
.map(flag -> flag.getStatus(instant).equals(ACTIVE))
@@ -244,16 +227,8 @@ public class FeatureFlag extends ImmutableObject implements Buildable {
return this;
}
public Builder setStatusMap(ImmutableSortedMap<DateTime, FeatureStatus> statusMap) {
return setStatusMapInstant(
statusMap.entrySet().stream()
.collect(
ImmutableSortedMap.toImmutableSortedMap(
Ordering.natural(), e -> toInstant(e.getKey()), Map.Entry::getValue)));
}
public Builder setStatusMapInstant(ImmutableSortedMap<Instant, FeatureStatus> statusMap) {
getInstance().status = TimedTransitionProperty.fromValueMapInstant(statusMap);
public Builder setStatusMap(ImmutableSortedMap<Instant, FeatureStatus> statusMap) {
getInstance().status = TimedTransitionProperty.fromValueMap(statusMap);
return this;
}
}
@@ -20,8 +20,6 @@ import static com.google.common.collect.ImmutableSortedMap.toImmutableSortedMap;
import static google.registry.util.DateTimeUtils.START_INSTANT;
import static google.registry.util.DateTimeUtils.formatInstant;
import static google.registry.util.DateTimeUtils.latestOf;
import static google.registry.util.DateTimeUtils.toDateTime;
import static google.registry.util.DateTimeUtils.toInstant;
import com.fasterxml.jackson.annotation.JsonValue;
import com.google.common.collect.ImmutableMultimap;
@@ -34,7 +32,6 @@ import java.util.Map;
import java.util.stream.Collectors;
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
import org.joda.time.DateTime;
/**
* An entity property whose value transitions over time. Each value it takes on becomes active at a
@@ -70,6 +67,9 @@ public class TimedTransitionProperty<V extends Serializable> implements UnsafeSe
checkArgument(
backingMap.containsKey(START_INSTANT),
"Must provide transition entry for the start of time (Unix Epoch)");
checkArgument(
Ordering.natural().equals(backingMap.comparator()),
"Timed transition value map must have transition time keys in chronological order");
this.backingMap = ImmutableSortedMap.copyOfSorted(backingMap);
}
@@ -83,7 +83,7 @@ public class TimedTransitionProperty<V extends Serializable> implements UnsafeSe
* START_INSTANT}.
*/
public static <V extends Serializable> TimedTransitionProperty<V> withInitialValue(V value) {
return fromValueMapInstant(ImmutableSortedMap.of(START_INSTANT, value));
return fromValueMap(ImmutableSortedMap.of(START_INSTANT, value));
}
/**
@@ -91,53 +91,12 @@ public class TimedTransitionProperty<V extends Serializable> implements UnsafeSe
* in the given map.
*
* <p>The map must contain a value for {@code START_INSTANT}.
*
* @deprecated Use {@link #fromValueMapInstant(ImmutableSortedMap)}
*/
@Deprecated
@SuppressWarnings("InlineMeSuggester")
public static <V extends Serializable> TimedTransitionProperty<V> fromValueMap(
ImmutableSortedMap<DateTime, V> valueMap) {
return fromValueMapInstant(toInstantMap(valueMap));
}
/**
* Returns a {@link TimedTransitionProperty} that contains the transition values and times defined
* in the given map.
*
* <p>The map must contain a value for {@code START_INSTANT}.
*/
public static <V extends Serializable> TimedTransitionProperty<V> fromValueMapInstant(
ImmutableSortedMap<Instant, V> valueMap) {
return new TimedTransitionProperty<>(valueMap);
}
/**
* Returns a {@link TimedTransitionProperty} that contains the transition values and times defined
* in the given map.
*
* <p>The map must contain a value for {@code START_OF_TIME}. The map is also validated against a
* set of allowed transitions.
*
* @deprecated Use {@link #makeInstant(ImmutableSortedMap, ImmutableMultimap, String,
* Serializable, String)}
*/
@Deprecated
@SuppressWarnings("InlineMeSuggester")
public static <V extends Serializable> TimedTransitionProperty<V> make(
ImmutableSortedMap<DateTime, V> valueMap,
ImmutableMultimap<V, V> allowedTransitions,
String mapName,
V initialValue,
String initialValueErrorMessage) {
return makeInstant(
toInstantMap(valueMap),
allowedTransitions,
mapName,
initialValue,
initialValueErrorMessage);
}
/**
* Returns a {@link TimedTransitionProperty} that contains the transition values and times defined
* in the given map.
@@ -145,44 +104,27 @@ public class TimedTransitionProperty<V extends Serializable> implements UnsafeSe
* <p>The map must contain a value for {@code START_INSTANT}. The map is also validated against a
* set of allowed transitions.
*/
public static <V extends Serializable> TimedTransitionProperty<V> makeInstant(
public static <V extends Serializable> TimedTransitionProperty<V> make(
ImmutableSortedMap<Instant, V> valueMap,
ImmutableMultimap<V, V> allowedTransitions,
String mapName,
V initialValue,
String initialValueErrorMessage) {
validateTimedTransitionMapInstant(valueMap, allowedTransitions, mapName);
validateTimedTransitionMap(valueMap, allowedTransitions, mapName);
checkArgument(valueMap.firstEntry().getValue().equals(initialValue), initialValueErrorMessage);
return fromValueMapInstant(valueMap);
}
/**
* Validates a timed transition map.
*
* @deprecated Use {@link #validateTimedTransitionMapInstant(ImmutableSortedMap,
* ImmutableMultimap, String)}
*/
@Deprecated
@SuppressWarnings("InlineMeSuggester")
public static <V extends Serializable> void validateTimedTransitionMap(
ImmutableSortedMap<DateTime, V> valueMap,
ImmutableMultimap<V, V> allowedTransitions,
String mapName) {
validateTimedTransitionMapInstant(toInstantMap(valueMap), allowedTransitions, mapName);
return fromValueMap(valueMap);
}
/** Validates a timed transition map. */
public static <V extends Serializable> void validateTimedTransitionMapInstant(
public static <V extends Serializable> void validateTimedTransitionMap(
ImmutableSortedMap<Instant, V> valueMap,
ImmutableMultimap<V, V> allowedTransitions,
String mapName) {
checkArgument(
Ordering.natural().equals(valueMap.comparator()),
"Timed transition value map must have transition time keys in chronological order");
checkArgument(!valueMap.isEmpty(), "%s map cannot be null or empty.", mapName);
checkArgument(
valueMap.firstKey().equals(START_INSTANT), "%s map must start at START_OF_TIME.", mapName);
valueMap.firstKey().equals(START_INSTANT), "%s map must start at START_INSTANT.", mapName);
V lastValue = null;
for (V value : valueMap.values()) {
@@ -199,17 +141,6 @@ public class TimedTransitionProperty<V extends Serializable> implements UnsafeSe
}
}
private static <V> ImmutableSortedMap<Instant, V> toInstantMap(
ImmutableSortedMap<DateTime, V> valueMap) {
checkArgument(
Ordering.natural().equals(valueMap.comparator()),
"Timed transition value map must have transition time keys in chronological order");
return valueMap.entrySet().stream()
.collect(
toImmutableSortedMap(
Ordering.natural(), e -> toInstant(e.getKey()), Map.Entry::getValue));
}
/** Checks whether the property is valid. */
public void checkValidity() {
checkState(
@@ -217,39 +148,16 @@ public class TimedTransitionProperty<V extends Serializable> implements UnsafeSe
"Timed transition values missing required entry for the start of time (Unix Epoch)");
}
/** Returns the value of the property that is active at the given time. */
public V getValueAtTime(DateTime time) {
return getValueAtTime(toInstant(time));
}
/** Returns the value of the property that is active at the given time. */
public V getValueAtTime(Instant time) {
return backingMap.floorEntry(latestOf(START_INSTANT, time)).getValue();
}
/** Returns the map of all the transitions that have been defined for this property. */
public ImmutableSortedMap<DateTime, V> toValueMap() {
return backingMap.entrySet().stream()
.collect(
toImmutableSortedMap(
Ordering.natural(), e -> toDateTime(e.getKey()), Map.Entry::getValue));
}
/** Returns the map of all the transitions that have been defined for this property. */
public ImmutableSortedMap<Instant, V> toValueMapInstant() {
public ImmutableSortedMap<Instant, V> toValueMap() {
return backingMap;
}
/**
* Returns the time of the next transition after the given time. Returns null if there is no
* subsequent transition.
*/
@Nullable
public DateTime getNextTransitionAfter(DateTime time) {
Instant nextTransition = getNextTransitionAfter(toInstant(time));
return nextTransition == null ? null : toDateTime(nextTransition);
}
/** Returns the time of the next transition. Returns null if there is no subsequent transition. */
@Nullable
public Instant getNextTransitionAfter(Instant time) {
@@ -30,8 +30,8 @@ import jakarta.persistence.Index;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import java.time.Instant;
import java.util.Optional;
import org.joda.time.DateTime;
@Entity
@WithVKey(Long.class)
@@ -47,7 +47,7 @@ public class ConsoleUpdateHistory extends ImmutableObject implements Buildable {
@Column(nullable = false)
@Expose
DateTime modificationTime;
Instant modificationTime;
/** The HTTP method (e.g. POST, PUT) used to make this modification. */
@Column(nullable = false)
@@ -76,7 +76,7 @@ public class ConsoleUpdateHistory extends ImmutableObject implements Buildable {
return revisionId;
}
public DateTime getModificationTime() {
public Instant getModificationTime() {
return modificationTime;
}
@@ -141,7 +141,7 @@ public class ConsoleUpdateHistory extends ImmutableObject implements Buildable {
return super.build();
}
public Builder setModificationTime(DateTime modificationTime) {
public Builder setModificationTime(Instant modificationTime) {
getInstance().modificationTime = modificationTime;
return this;
}
@@ -14,7 +14,6 @@
package google.registry.model.console;
import static google.registry.util.DateTimeUtils.toDateTime;
import static google.registry.util.PreconditionsUtils.checkArgumentNotNull;
import google.registry.model.Buildable;
@@ -31,7 +30,6 @@ import jakarta.persistence.Id;
import java.time.Instant;
import java.util.Optional;
import java.util.UUID;
import org.joda.time.DateTime;
/**
* Represents a password reset request of some type.
@@ -64,7 +62,7 @@ public class PasswordResetRequest extends ImmutableObject implements Buildable {
@Column(nullable = false)
String requester;
@Column DateTime fulfillmentTime;
@Column Instant fulfillmentTime;
@Column(nullable = false)
String destinationEmail;
@@ -84,20 +82,11 @@ public class PasswordResetRequest extends ImmutableObject implements Buildable {
return requestTime.getTimestamp();
}
/**
* @deprecated Use {@link #getRequestTime()}
*/
@Deprecated
@SuppressWarnings("InlineMeSuggester")
public DateTime getRequestDateTime() {
return toDateTime(requestTime.getTimestamp());
}
public String getRequester() {
return requester;
}
public Optional<DateTime> getFulfillmentTime() {
public Optional<Instant> getFulfillmentTime() {
return Optional.ofNullable(fulfillmentTime);
}
@@ -153,7 +142,7 @@ public class PasswordResetRequest extends ImmutableObject implements Buildable {
return this;
}
public Builder setFulfillmentTime(DateTime fulfillmentTime) {
public Builder setFulfillmentTime(Instant fulfillmentTime) {
getInstance().fulfillmentTime = fulfillmentTime;
return this;
}
@@ -18,7 +18,6 @@
elementFormDefault = XmlNsForm.QUALIFIED)
@XmlAccessorType(XmlAccessType.FIELD)
@XmlJavaTypeAdapters({
@XmlJavaTypeAdapter(UtcInstantAdapter.class),
@XmlJavaTypeAdapter(UtcInstantAdapter.class)
})
package google.registry.model.contact;
@@ -80,7 +80,6 @@ import jakarta.persistence.Enumerated;
import jakarta.persistence.Id;
import jakarta.persistence.MappedSuperclass;
import jakarta.persistence.Transient;
import java.time.Duration;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.HashSet;
@@ -495,8 +494,7 @@ public class DomainBase extends EppResource {
GracePeriodStatus.TRANSFER,
domain.getRepoId(),
transferExpirationTime.plus(
Duration.ofMillis(
Tld.get(domain.getTld()).getTransferGracePeriodLength().getMillis())),
Tld.get(domain.getTld()).getTransferGracePeriodLength()),
transferData.getGainingRegistrarId(),
transferData.getServerApproveBillingEvent())));
} else {
@@ -533,8 +531,7 @@ public class DomainBase extends EppResource {
GracePeriod.createForRecurrence(
GracePeriodStatus.AUTO_RENEW,
domain.getRepoId(),
lastAutorenewTime.plusMillis(
Tld.get(domain.getTld()).getAutoRenewGracePeriodLength().getMillis()),
lastAutorenewTime.plus(Tld.get(domain.getTld()).getAutoRenewGracePeriodLength()),
domain.getCurrentSponsorRegistrarId(),
domain.getAutorenewBillingEvent()));
newLastEppUpdateTime = Optional.of(lastAutorenewTime);
@@ -782,7 +779,7 @@ public class DomainBase extends EppResource {
/**
* Sets the autorenew end time, or clears it if empty is passed.
*
* <p>Note that {@link DateTimeUtils#END_OF_TIME} is used as a sentinel value in the database
* <p>Note that {@link DateTimeUtils#END_INSTANT} is used as a sentinel value in the database
* representation to signify that autorenew doesn't end, and is mapped to empty here for the
* purposes of more legible business logic.
*/
@@ -46,10 +46,10 @@ import jakarta.xml.bind.annotation.XmlTransient;
import jakarta.xml.bind.annotation.XmlType;
import jakarta.xml.bind.annotation.XmlValue;
import java.time.Instant;
import java.time.LocalDate;
import java.util.Optional;
import java.util.Set;
import javax.annotation.Nullable;
import org.joda.time.LocalDate;
/** A collection of {@link Domain} commands. */
public class DomainCommand {
@@ -23,6 +23,7 @@ import com.google.gson.annotations.Expose;
import google.registry.model.Buildable;
import google.registry.model.CreateAutoTimestamp;
import google.registry.model.UpdateAutoTimestampEntity;
import google.registry.persistence.converter.DurationUserType;
import jakarta.persistence.Access;
import jakarta.persistence.AccessType;
import jakarta.persistence.AttributeOverride;
@@ -37,10 +38,11 @@ import jakarta.persistence.Index;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.OneToOne;
import jakarta.persistence.Table;
import java.time.Duration;
import java.time.Instant;
import java.util.Optional;
import javax.annotation.Nullable;
import org.joda.time.Duration;
import org.hibernate.annotations.Type;
/**
* Represents a registry lock/unlock object, meaning that the domain is locked on the registry
@@ -156,6 +158,8 @@ public final class RegistryLock extends UpdateAutoTimestampEntity implements Bui
/** The duration after which we will re-lock this domain after it is unlocked. */
@Column(columnDefinition = "interval")
@Type(DurationUserType.class)
@Expose
private Duration relockDuration;
public String getRepoId() {
@@ -18,9 +18,8 @@
elementFormDefault = XmlNsForm.QUALIFIED)
@XmlAccessorType(XmlAccessType.FIELD)
@XmlJavaTypeAdapters({
@XmlJavaTypeAdapter(UtcInstantAdapter.class),
@XmlJavaTypeAdapter(UtcInstantAdapter.class),
@XmlJavaTypeAdapter(DateAdapter.class)
@XmlJavaTypeAdapter(value = UtcInstantAdapter.class, type = java.time.Instant.class),
@XmlJavaTypeAdapter(value = DateAdapter.class, type = java.time.LocalDate.class)
})
package google.registry.model.domain;
@@ -343,8 +343,8 @@ public class AllocationToken extends UpdateAutoTimestampEntity implements Builda
}
@JsonIgnore
public ImmutableSortedMap<Instant, TokenStatus> getTokenStatusTransitionsMapInstant() {
return tokenStatusTransitions.toValueMapInstant();
public ImmutableSortedMap<Instant, TokenStatus> getTokenStatusTransitionsMap() {
return tokenStatusTransitions.toValueMap();
}
public ImmutableSet<CommandName> getAllowedEppActions() {
@@ -568,7 +568,7 @@ public class AllocationToken extends UpdateAutoTimestampEntity implements Builda
public Builder setTokenStatusTransitions(ImmutableSortedMap<Instant, TokenStatus> transitions) {
getInstance().tokenStatusTransitions =
TimedTransitionProperty.makeInstant(
TimedTransitionProperty.make(
transitions,
VALID_TOKEN_STATUS_TRANSITIONS,
"tokenStatusTransitions",
@@ -18,7 +18,6 @@
elementFormDefault = XmlNsForm.QUALIFIED)
@XmlAccessorType(XmlAccessType.FIELD)
@XmlJavaTypeAdapters({
@XmlJavaTypeAdapter(UtcInstantAdapter.class),
@XmlJavaTypeAdapter(UtcInstantAdapter.class)
})
package google.registry.model.eppinput;
@@ -18,7 +18,6 @@
elementFormDefault = XmlNsForm.QUALIFIED)
@XmlAccessorType(XmlAccessType.FIELD)
@XmlJavaTypeAdapters({
@XmlJavaTypeAdapter(UtcInstantAdapter.class),
@XmlJavaTypeAdapter(UtcInstantAdapter.class)
})
package google.registry.model.eppoutput;
@@ -18,7 +18,6 @@
elementFormDefault = XmlNsForm.QUALIFIED)
@XmlAccessorType(XmlAccessType.FIELD)
@XmlJavaTypeAdapters({
@XmlJavaTypeAdapter(UtcInstantAdapter.class),
@XmlJavaTypeAdapter(UtcInstantAdapter.class),
@XmlJavaTypeAdapter(InetAddressAdapter.class)
})
@@ -14,8 +14,6 @@
package google.registry.model.poll;
import static google.registry.util.DateTimeUtils.toInstant;
import com.google.common.annotations.VisibleForTesting;
import google.registry.model.ImmutableObject;
import google.registry.model.UnsafeSerializable;
@@ -31,7 +29,6 @@ import jakarta.xml.bind.annotation.XmlType;
import jakarta.xml.bind.annotation.XmlValue;
import jakarta.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import java.time.Instant;
import org.joda.time.DateTime;
/** The {@link ResponseData} returned when completing a pending action on a domain. */
@XmlTransient
@@ -105,16 +102,6 @@ public class PendingActionNotificationResponse extends ImmutableObject
trid,
processedDate);
}
/**
* @deprecated Use {@link #create(String, boolean, Trid, Instant)}
*/
@Deprecated
@SuppressWarnings("InlineMeSuggester")
public static DomainPendingActionNotificationResponse create(
String domainName, boolean actionResult, Trid trid, DateTime processedDate) {
return create(domainName, actionResult, trid, toInstant(processedDate));
}
}
/** An adapter to output the XML in response to resolving a pending command on a contact. */
@@ -139,16 +126,6 @@ public class PendingActionNotificationResponse extends ImmutableObject
trid,
processedDate);
}
/**
* @deprecated Use {@link #create(String, boolean, Trid, Instant)}
*/
@Deprecated
@SuppressWarnings("InlineMeSuggester")
public static ContactPendingActionNotificationResponse create(
String contactId, boolean actionResult, Trid trid, DateTime processedDate) {
return create(contactId, actionResult, trid, toInstant(processedDate));
}
}
/** An adapter to output the XML in response to resolving a pending command on a host. */
@@ -170,15 +147,5 @@ public class PendingActionNotificationResponse extends ImmutableObject
return init(
new HostPendingActionNotificationResponse(), hostName, actionResult, trid, processedDate);
}
/**
* @deprecated Use {@link #create(String, boolean, Trid, Instant)}
*/
@Deprecated
@SuppressWarnings("InlineMeSuggester")
public static HostPendingActionNotificationResponse create(
String hostName, boolean actionResult, Trid trid, DateTime processedDate) {
return create(hostName, actionResult, trid, toInstant(processedDate));
}
}
}
@@ -18,8 +18,6 @@ import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkState;
import static google.registry.util.DateTimeUtils.END_INSTANT;
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.PreconditionsUtils.checkArgumentNotNull;
import com.google.common.collect.ImmutableList;
@@ -60,7 +58,6 @@ import jakarta.persistence.InheritanceType;
import jakarta.persistence.Table;
import java.time.Instant;
import java.util.Optional;
import org.joda.time.DateTime;
/**
* A poll message that is pending for a registrar.
@@ -246,15 +243,6 @@ public abstract class PollMessage extends ImmutableObject
return thisCastToDerived();
}
/**
* @deprecated Use {@link #setEventTime(Instant)}
*/
@Deprecated
@SuppressWarnings("InlineMeSuggester")
public B setEventTime(DateTime eventTime) {
return setEventTime(toInstant(eventTime));
}
public B setEventTime(Instant eventTime) {
getInstance().eventTime = eventTime;
return thisCastToDerived();
@@ -403,15 +391,6 @@ public abstract class PollMessage extends ImmutableObject
return new Builder(clone(this));
}
/**
* @deprecated Use {@link #getExtendedRegistrationExpirationTime()}
*/
@Deprecated
@SuppressWarnings("InlineMeSuggester")
public DateTime getExtendedRegistrationExpirationDateTime() {
return toDateTime(extendedRegistrationExpirationTime);
}
public Instant getExtendedRegistrationExpirationTime() {
return extendedRegistrationExpirationTime;
}
@@ -584,15 +563,6 @@ public abstract class PollMessage extends ImmutableObject
return this;
}
/**
* @deprecated Use {@link #setAutorenewEndTime(Instant)}
*/
@Deprecated
@SuppressWarnings("InlineMeSuggester")
public Builder setAutorenewEndTime(DateTime autorenewEndTime) {
return setAutorenewEndTime(toInstant(autorenewEndTime));
}
public Builder setAutorenewEndTime(Instant autorenewEndTime) {
getInstance().autorenewEndTime = autorenewEndTime;
return this;
@@ -18,7 +18,6 @@
elementFormDefault = XmlNsForm.QUALIFIED)
@XmlAccessorType(XmlAccessType.FIELD)
@XmlJavaTypeAdapters({
@XmlJavaTypeAdapter(UtcInstantAdapter.class),
@XmlJavaTypeAdapter(UtcInstantAdapter.class)
})
package google.registry.model.poll;
@@ -17,15 +17,13 @@ package google.registry.model.rde;
import static com.google.common.base.Preconditions.checkArgument;
import static google.registry.model.rde.RdeNamingUtils.makePartialName;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.util.DateTimeUtils.toJodaLocalDate;
import static google.registry.util.DateTimeUtils.toLocalDate;
import com.google.common.base.VerifyException;
import google.registry.model.ImmutableObject;
import google.registry.model.UpdateAutoTimestampEntity;
import google.registry.persistence.VKey;
import google.registry.persistence.converter.LocalDateConverter;
import jakarta.persistence.Column;
import jakarta.persistence.Convert;
import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
@@ -33,8 +31,8 @@ import jakarta.persistence.Id;
import jakarta.persistence.IdClass;
import java.io.Serializable;
import java.time.Instant;
import java.time.LocalDate;
import java.util.Optional;
import org.joda.time.LocalDate;
/**
* Entity for tracking RDE revisions.
@@ -82,16 +80,16 @@ public final class RdeRevision extends UpdateAutoTimestampEntity {
*
* @return {@code 0} for first deposit generation and {@code >0} for resends
*/
public static int getNextRevision(String tld, Instant date, RdeMode mode) {
RdeRevisionId revisionId = RdeRevisionId.create(tld, toJodaLocalDate(date), mode);
public static int getNextRevision(String tld, Instant watermark, RdeMode mode) {
RdeRevisionId revisionId = RdeRevisionId.create(tld, toLocalDate(watermark), mode);
Optional<RdeRevision> revisionOptional =
tm().transact(() -> tm().loadByKeyIfPresent(VKey.create(RdeRevision.class, revisionId)));
return revisionOptional.map(rdeRevision -> rdeRevision.revision + 1).orElse(0);
}
/** Returns the latest revision of the report already generated for the given triplet. */
public static Optional<Integer> getCurrentRevision(String tld, Instant date, RdeMode mode) {
int nextRevision = getNextRevision(tld, date, mode);
public static Optional<Integer> getCurrentRevision(String tld, Instant watermark, RdeMode mode) {
int nextRevision = getNextRevision(tld, watermark, mode);
if (nextRevision == 0) {
return Optional.empty();
}
@@ -107,10 +105,10 @@ public final class RdeRevision extends UpdateAutoTimestampEntity {
* @throws IllegalStateException if not in a transaction
* @throws VerifyException if the state doesn't meet the above criteria
*/
public static void saveRevision(String tld, Instant date, RdeMode mode, int revision) {
public static void saveRevision(String tld, Instant watermark, RdeMode mode, int revision) {
checkArgument(revision >= 0, "Negative revision: %s", revision);
tm().assertInTransaction();
RdeRevisionId revisionId = RdeRevisionId.create(tld, toJodaLocalDate(date), mode);
RdeRevisionId revisionId = RdeRevisionId.create(tld, toLocalDate(watermark), mode);
Optional<RdeRevision> revisionOptional =
tm().loadByKeyIfPresent(VKey.create(RdeRevision.class, revisionId));
if (revision == 0) {
@@ -125,7 +123,7 @@ public final class RdeRevision extends UpdateAutoTimestampEntity {
checkArgument(
revisionOptional.isPresent(),
"Couldn't find existing RDE revision %s when trying to save new revision %s",
makePartialName(tld, date, mode),
makePartialName(tld, watermark, mode),
revision);
checkArgument(
revisionOptional.get().revision == revision - 1,
@@ -133,7 +131,7 @@ public final class RdeRevision extends UpdateAutoTimestampEntity {
revision - 1,
revisionOptional.get());
}
tm().put(RdeRevision.create(tld, toJodaLocalDate(date), mode, revision));
tm().put(RdeRevision.create(tld, toLocalDate(watermark), mode, revision));
}
/** Class to represent the composite primary key of {@link RdeRevision} entity. */
@@ -141,9 +139,8 @@ public final class RdeRevision extends UpdateAutoTimestampEntity {
String tld;
// Auto-conversion doesn't work for ID classes, we must specify @Column and @Convert
// Auto-conversion doesn't work for ID classes, we must specify @Column
@Column(columnDefinition = "date")
@Convert(converter = LocalDateConverter.class)
LocalDate date;
@Enumerated(EnumType.STRING)
@@ -19,7 +19,6 @@ import static com.google.common.collect.ImmutableList.toImmutableList;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.util.DateTimeUtils.END_INSTANT;
import static google.registry.util.DateTimeUtils.START_INSTANT;
import static google.registry.util.DateTimeUtils.toInstant;
import com.google.common.collect.ImmutableCollection;
import com.google.common.collect.ImmutableList;
@@ -37,7 +36,6 @@ import java.time.Instant;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Stream;
import org.joda.time.DateTime;
/** Retrieves {@link HistoryEntry} descendants (e.g. {@link DomainHistory}). */
public class HistoryEntryDao {
@@ -50,18 +48,6 @@ public class HistoryEntryDao {
Host.class,
HostHistory.class);
/**
* Loads all history objects in the times specified, including all types.
*
* @deprecated Use {@link #loadAllHistoryObjects(Instant, Instant)}
*/
@Deprecated
@SuppressWarnings("InlineMeSuggester")
public static ImmutableList<HistoryEntry> loadAllHistoryObjects(
DateTime afterTime, DateTime beforeTime) {
return loadAllHistoryObjects(toInstant(afterTime), toInstant(beforeTime));
}
/** Loads all history objects in the times specified, including all types. */
public static ImmutableList<HistoryEntry> loadAllHistoryObjects(
Instant afterTime, Instant beforeTime) {
@@ -88,16 +74,6 @@ public class HistoryEntryDao {
return loadHistoryObjectsForResource(resourceKey, START_INSTANT, END_INSTANT, subclazz);
}
/**
* @deprecated Use {@link #loadHistoryObjectsForResource(VKey, Instant, Instant)}
*/
@Deprecated
@SuppressWarnings("InlineMeSuggester")
public static ImmutableList<HistoryEntry> loadHistoryObjectsForResource(
VKey<? extends EppResource> resourceKey, DateTime afterTime, DateTime beforeTime) {
return loadHistoryObjectsForResource(resourceKey, toInstant(afterTime), toInstant(beforeTime));
}
/** Loads all history objects in the time period specified for the given {@link EppResource}. */
public static ImmutableList<HistoryEntry> loadHistoryObjectsForResource(
VKey<? extends EppResource> resourceKey, Instant afterTime, Instant beforeTime) {
@@ -105,20 +81,6 @@ public class HistoryEntryDao {
() -> loadHistoryObjectsForResourceInternal(resourceKey, afterTime, beforeTime));
}
/**
* @deprecated Use {@link #loadHistoryObjectsForResource(VKey, Instant, Instant, Class)}
*/
@Deprecated
@SuppressWarnings("InlineMeSuggester")
public static <T extends HistoryEntry> ImmutableList<T> loadHistoryObjectsForResource(
VKey<? extends EppResource> resourceKey,
DateTime afterTime,
DateTime beforeTime,
Class<T> subclazz) {
return loadHistoryObjectsForResource(
resourceKey, toInstant(afterTime), toInstant(beforeTime), subclazz);
}
/**
* Loads all history objects in the time period specified for the given {@link EppResource} and
* cast to the appropriate subclass.
@@ -32,8 +32,8 @@ import jakarta.persistence.Id;
import jakarta.persistence.Index;
import jakarta.persistence.Table;
import java.io.Serializable;
import java.time.LocalDate;
import java.util.Set;
import org.joda.time.LocalDate;
@Entity
@Table(
@@ -16,7 +16,7 @@ package google.registry.model.reporting;
import com.google.common.collect.ImmutableList;
import google.registry.persistence.transaction.JpaTransactionManager;
import org.joda.time.LocalDate;
import java.time.LocalDate;
/**
* Data access object for {@link Spec11ThreatMatch}.
@@ -24,8 +24,7 @@ import static google.registry.persistence.transaction.TransactionManagerFactory.
import static google.registry.util.CollectionUtils.nullToEmptyImmutableCopy;
import static google.registry.util.DateTimeUtils.END_INSTANT;
import static google.registry.util.DateTimeUtils.START_INSTANT;
import static google.registry.util.DateTimeUtils.toDateTime;
import static google.registry.util.DateTimeUtils.toInstant;
import static google.registry.util.DateTimeUtils.formatInstant;
import static google.registry.util.PreconditionsUtils.checkArgumentNotNull;
import static org.joda.money.CurrencyUnit.USD;
@@ -77,7 +76,6 @@ import google.registry.persistence.converter.AllocationTokenVkeyListUserType;
import google.registry.persistence.converter.BillingCostTransitionUserType;
import google.registry.persistence.converter.TldStateTransitionUserType;
import google.registry.tldconfig.idn.IdnTableEnum;
import google.registry.util.DateTimeUtils;
import google.registry.util.Idn;
import jakarta.persistence.AttributeOverride;
import jakarta.persistence.Column;
@@ -86,6 +84,7 @@ import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.persistence.Id;
import java.time.Duration;
import java.time.Instant;
import java.util.List;
import java.util.Map;
@@ -98,8 +97,6 @@ import javax.annotation.Nullable;
import org.hibernate.annotations.Type;
import org.joda.money.CurrencyUnit;
import org.joda.money.Money;
import org.joda.time.DateTime;
import org.joda.time.Duration;
/** Persisted per-TLD configuration data. */
@Entity
@@ -121,14 +118,14 @@ public class Tld extends ImmutableObject implements Buildable, UnsafeSerializabl
public static final boolean DEFAULT_ESCROW_ENABLED = false;
public static final boolean DEFAULT_DNS_PAUSED = false;
public static final Duration DEFAULT_ADD_GRACE_PERIOD = Duration.standardDays(5);
public static final Duration DEFAULT_AUTO_RENEW_GRACE_PERIOD = Duration.standardDays(45);
public static final Duration DEFAULT_REDEMPTION_GRACE_PERIOD = Duration.standardDays(30);
public static final Duration DEFAULT_RENEW_GRACE_PERIOD = Duration.standardDays(5);
public static final Duration DEFAULT_TRANSFER_GRACE_PERIOD = Duration.standardDays(5);
public static final Duration DEFAULT_AUTOMATIC_TRANSFER_LENGTH = Duration.standardDays(5);
public static final Duration DEFAULT_PENDING_DELETE_LENGTH = Duration.standardDays(5);
public static final Duration DEFAULT_ANCHOR_TENANT_ADD_GRACE_PERIOD = Duration.standardDays(30);
public static final Duration DEFAULT_ADD_GRACE_PERIOD = Duration.ofDays(5);
public static final Duration DEFAULT_AUTO_RENEW_GRACE_PERIOD = Duration.ofDays(45);
public static final Duration DEFAULT_REDEMPTION_GRACE_PERIOD = Duration.ofDays(30);
public static final Duration DEFAULT_RENEW_GRACE_PERIOD = Duration.ofDays(5);
public static final Duration DEFAULT_TRANSFER_GRACE_PERIOD = Duration.ofDays(5);
public static final Duration DEFAULT_AUTOMATIC_TRANSFER_LENGTH = Duration.ofDays(5);
public static final Duration DEFAULT_PENDING_DELETE_LENGTH = Duration.ofDays(5);
public static final Duration DEFAULT_ANCHOR_TENANT_ADD_GRACE_PERIOD = Duration.ofDays(30);
public static final CurrencyUnit DEFAULT_CURRENCY = USD;
public static final Money DEFAULT_CREATE_BILLING_COST = Money.of(USD, 8);
public static final Money DEFAULT_EAP_BILLING_COST = Money.of(USD, 0);
@@ -260,14 +257,9 @@ public class Tld extends ImmutableObject implements Buildable, UnsafeSerializabl
return VKey.create(Tld.class, tldStr);
}
/** Checks if {@code tld} is enrolled with BSA. */
public static boolean isEnrolledWithBsa(Tld tld, DateTime now) {
return isEnrolledWithBsa(tld, toInstant(now));
}
/** Checks if {@code tld} is enrolled with BSA. */
public static boolean isEnrolledWithBsa(Tld tld, Instant now) {
return tld.getBsaEnrollStartTimeInstant().orElse(END_INSTANT).isBefore(now);
return tld.getBsaEnrollStartTime().orElse(END_INSTANT).isBefore(now);
}
/**
@@ -601,13 +593,7 @@ public class Tld extends ImmutableObject implements Buildable, UnsafeSerializabl
/** Returns the time when this TLD was enrolled in the Brand Safety Alliance (BSA) program. */
@JsonIgnore
public Optional<DateTime> getBsaEnrollStartTime() {
return Optional.ofNullable(toDateTime(this.bsaEnrollStartTime));
}
/** Returns the time when this TLD was enrolled in the Brand Safety Alliance (BSA) program. */
@JsonIgnore
public Optional<Instant> getBsaEnrollStartTimeInstant() {
public Optional<Instant> getBsaEnrollStartTime() {
return Optional.ofNullable(this.bsaEnrollStartTime);
}
@@ -697,7 +683,7 @@ public class Tld extends ImmutableObject implements Buildable, UnsafeSerializabl
}
public ImmutableSortedMap<Instant, Money> getCreateBillingCostTransitions() {
return createBillingCostTransitions.toValueMapInstant();
return createBillingCostTransitions.toValueMap();
}
/**
@@ -728,11 +714,11 @@ public class Tld extends ImmutableObject implements Buildable, UnsafeSerializabl
}
public ImmutableSortedMap<Instant, TldState> getTldStateTransitions() {
return tldStateTransitions.toValueMapInstant();
return tldStateTransitions.toValueMap();
}
public ImmutableSortedMap<Instant, Money> getRenewBillingCostTransitions() {
return renewBillingCostTransitions.toValueMapInstant();
return renewBillingCostTransitions.toValueMap();
}
/** Returns the EAP fee for the tld at the given time. */
@@ -752,13 +738,13 @@ public class Tld extends ImmutableObject implements Buildable, UnsafeSerializabl
// which the domain is separately considered standard vs premium depending on renewal price.
false,
validPeriod,
toDateTime(validPeriod.upperEndpoint()));
formatInstant(validPeriod.upperEndpoint()));
}
@VisibleForTesting
@JsonProperty("eapFeeSchedule")
public ImmutableSortedMap<Instant, Money> getEapFeeScheduleAsMap() {
return eapFeeSchedule.toValueMapInstant();
return eapFeeSchedule.toValueMap();
}
public String getLordnUsername() {
@@ -853,7 +839,7 @@ public class Tld extends ImmutableObject implements Buildable, UnsafeSerializabl
.filter(state -> !TldState.QUIET_PERIOD.equals(state))
.collect(Collectors.toList())),
"The TLD states are chronologically out of order");
getInstance().tldStateTransitions = TimedTransitionProperty.fromValueMapInstant(tldStatesMap);
getInstance().tldStateTransitions = TimedTransitionProperty.fromValueMap(tldStatesMap);
return this;
}
@@ -913,7 +899,7 @@ public class Tld extends ImmutableObject implements Buildable, UnsafeSerializabl
public Builder setAddGracePeriodLength(Duration addGracePeriodLength) {
checkArgument(
addGracePeriodLength.isLongerThan(Duration.ZERO),
addGracePeriodLength.compareTo(Duration.ZERO) > 0,
"addGracePeriodLength must be non-zero");
getInstance().addGracePeriodLength = addGracePeriodLength;
return this;
@@ -922,7 +908,7 @@ public class Tld extends ImmutableObject implements Buildable, UnsafeSerializabl
/** Warning! Changing this will affect the billing time of autorenew events in the past. */
public Builder setAutoRenewGracePeriodLength(Duration autoRenewGracePeriodLength) {
checkArgument(
autoRenewGracePeriodLength.isLongerThan(Duration.ZERO),
autoRenewGracePeriodLength.compareTo(Duration.ZERO) > 0,
"autoRenewGracePeriodLength must be non-zero");
getInstance().autoRenewGracePeriodLength = autoRenewGracePeriodLength;
return this;
@@ -930,7 +916,7 @@ public class Tld extends ImmutableObject implements Buildable, UnsafeSerializabl
public Builder setRedemptionGracePeriodLength(Duration redemptionGracePeriodLength) {
checkArgument(
redemptionGracePeriodLength.isLongerThan(Duration.ZERO),
redemptionGracePeriodLength.compareTo(Duration.ZERO) > 0,
"redemptionGracePeriodLength must be non-zero");
getInstance().redemptionGracePeriodLength = redemptionGracePeriodLength;
return this;
@@ -938,7 +924,7 @@ public class Tld extends ImmutableObject implements Buildable, UnsafeSerializabl
public Builder setRenewGracePeriodLength(Duration renewGracePeriodLength) {
checkArgument(
renewGracePeriodLength.isLongerThan(Duration.ZERO),
renewGracePeriodLength.compareTo(Duration.ZERO) > 0,
"renewGracePeriodLength must be non-zero");
getInstance().renewGracePeriodLength = renewGracePeriodLength;
return this;
@@ -946,7 +932,7 @@ public class Tld extends ImmutableObject implements Buildable, UnsafeSerializabl
public Builder setTransferGracePeriodLength(Duration transferGracePeriodLength) {
checkArgument(
transferGracePeriodLength.isLongerThan(Duration.ZERO),
transferGracePeriodLength.compareTo(Duration.ZERO) > 0,
"transferGracePeriodLength must be non-zero");
getInstance().transferGracePeriodLength = transferGracePeriodLength;
return this;
@@ -954,7 +940,7 @@ public class Tld extends ImmutableObject implements Buildable, UnsafeSerializabl
public Builder setAutomaticTransferLength(Duration automaticTransferLength) {
checkArgument(
automaticTransferLength.isLongerThan(Duration.ZERO),
automaticTransferLength.compareTo(Duration.ZERO) > 0,
"automaticTransferLength must be non-zero");
getInstance().automaticTransferLength = automaticTransferLength;
return this;
@@ -962,7 +948,7 @@ public class Tld extends ImmutableObject implements Buildable, UnsafeSerializabl
public Builder setPendingDeleteLength(Duration pendingDeleteLength) {
checkArgument(
pendingDeleteLength.isLongerThan(Duration.ZERO), "pendingDeleteLength must be non-zero");
pendingDeleteLength.compareTo(Duration.ZERO) > 0, "pendingDeleteLength must be non-zero");
getInstance().pendingDeleteLength = pendingDeleteLength;
return this;
}
@@ -980,7 +966,7 @@ public class Tld extends ImmutableObject implements Buildable, UnsafeSerializabl
createCostsMap.values().stream().allMatch(Money::isPositiveOrZero),
"Create billing cost cannot be negative");
getInstance().createBillingCostTransitions =
TimedTransitionProperty.fromValueMapInstant(createCostsMap);
TimedTransitionProperty.fromValueMap(createCostsMap);
return this;
}
@@ -1033,7 +1019,7 @@ public class Tld extends ImmutableObject implements Buildable, UnsafeSerializabl
renewCostsMap.values().stream().allMatch(Money::isPositiveOrZero),
"Renew billing cost cannot be negative");
getInstance().renewBillingCostTransitions =
TimedTransitionProperty.fromValueMapInstant(renewCostsMap);
TimedTransitionProperty.fromValueMap(renewCostsMap);
return this;
}
@@ -1043,7 +1029,7 @@ public class Tld extends ImmutableObject implements Buildable, UnsafeSerializabl
checkArgument(
eapFeeSchedule.values().stream().allMatch(Money::isPositiveOrZero),
"EAP fee cannot be negative");
getInstance().eapFeeSchedule = TimedTransitionProperty.fromValueMapInstant(eapFeeSchedule);
getInstance().eapFeeSchedule = TimedTransitionProperty.fromValueMap(eapFeeSchedule);
return this;
}
@@ -1121,13 +1107,7 @@ public class Tld extends ImmutableObject implements Buildable, UnsafeSerializabl
return this;
}
public Builder setBsaEnrollStartTime(Optional<DateTime> enrollTime) {
// TODO(b/309175133): forbid if enrolled with BSA
getInstance().bsaEnrollStartTime = enrollTime.map(DateTimeUtils::toInstant).orElse(null);
return this;
}
public Builder setBsaEnrollStartTimeInstant(Optional<Instant> enrollTime) {
public Builder setBsaEnrollStartTime(Optional<Instant> enrollTime) {
// TODO(b/309175133): forbid if enrolled with BSA
getInstance().bsaEnrollStartTime = enrollTime.orElse(null);
return this;
@@ -1145,7 +1125,7 @@ public class Tld extends ImmutableObject implements Buildable, UnsafeSerializabl
&& tldName.equals(InternetDomainName.from(tldName).toString()),
"Cannot create registry for TLD that is not a valid, canonical domain name");
// Check the validity of all TimedTransitionProperties to ensure that they have values for
// START_OF_TIME. The setters above have already checked this for new values, but also check
// START_INSTANT. The setters above have already checked this for new values, but also check
// here to catch cases where we loaded an invalid TimedTransitionProperty from the database
// and cloned it into a new builder, to block re-building a Tld in an invalid state.
instance.tldStateTransitions.checkValidity();
@@ -1172,7 +1152,7 @@ public class Tld extends ImmutableObject implements Buildable, UnsafeSerializabl
instance.getCreateBillingCostTransitions().values().stream().allMatch(currencyCheck),
"Create cost must be in the TLD's currency");
checkArgument(
instance.eapFeeSchedule.toValueMapInstant().values().stream().allMatch(currencyCheck),
instance.eapFeeSchedule.toValueMap().values().stream().allMatch(currencyCheck),
"All EAP fees must be in the TLD's currency");
checkArgumentNotNull(
instance.pricingEngineClassName, "All registries must have a configured pricing engine");
@@ -25,7 +25,6 @@ import static google.registry.model.CacheUtils.memoizeWithShortExpiration;
import static google.registry.model.tld.Tld.isEnrolledWithBsa;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.util.CollectionUtils.entriesToImmutableMap;
import static google.registry.util.DateTimeUtils.toInstant;
import static google.registry.util.PreconditionsUtils.checkArgumentNotNull;
import com.google.common.base.Joiner;
@@ -41,7 +40,6 @@ import java.time.Instant;
import java.util.Optional;
import java.util.function.Supplier;
import java.util.stream.Stream;
import org.joda.time.DateTime;
/** Utilities for finding and listing {@link Tld} entities. */
public final class Tlds {
@@ -159,13 +157,4 @@ public final class Tlds {
public static boolean hasActiveBsaEnrollment(Instant now) {
return getTldEntitiesOfType(TldType.REAL).stream().anyMatch(tld -> isEnrolledWithBsa(tld, now));
}
/**
* @deprecated Use {@link #hasActiveBsaEnrollment(Instant)}
*/
@Deprecated
@SuppressWarnings("InlineMeSuggester")
public static boolean hasActiveBsaEnrollment(DateTime now) {
return hasActiveBsaEnrollment(toInstant(now));
}
}
@@ -33,11 +33,11 @@ import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.MappedSuperclass;
import java.time.Instant;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.Nullable;
import org.joda.time.DateTime;
/**
* Base class for {@link ReservedList} and {@link PremiumList} objects.
@@ -58,7 +58,7 @@ public abstract class BaseDomainLabelList<T extends Comparable<?>, R extends Dom
String name;
@Column(name = "creation_timestamp")
DateTime creationTimestamp;
Instant creationTimestamp;
/** Returns the ID of this revision, or throws if null. */
public long getRevisionId() {
@@ -74,7 +74,7 @@ public abstract class BaseDomainLabelList<T extends Comparable<?>, R extends Dom
}
/** Returns the creation time of this revision of the reserved list. */
public DateTime getCreationTimestamp() {
public Instant getCreationTimestamp() {
return creationTimestamp;
}
@@ -159,7 +159,7 @@ public abstract class BaseDomainLabelList<T extends Comparable<?>, R extends Dom
return thisCastToDerived();
}
public B setCreationTimestamp(DateTime creationTime) {
public B setCreationTimestamp(Instant creationTime) {
getInstance().creationTimestamp = creationTime;
return thisCastToDerived();
}
@@ -131,8 +131,7 @@ public final class PremiumListDao {
checkArgument(!inputData.isEmpty(), "New premium list data cannot be empty");
tm().assertInTransaction();
return save(
PremiumListUtils.parseToPremiumList(
name, currencyUnit, inputData, tm().getTransactionTime()));
PremiumListUtils.parseToPremiumList(name, currencyUnit, inputData, tm().getTxTime()));
}
/** Saves the given premium list (and its premium list entries) to Cloud SQL. */
@@ -18,16 +18,16 @@ import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
import google.registry.model.tld.label.PremiumList.PremiumEntry;
import java.math.BigDecimal;
import java.time.Instant;
import java.util.List;
import java.util.Map;
import org.joda.money.CurrencyUnit;
import org.joda.time.DateTime;
/** Static utility methods for {@link PremiumList}. */
public class PremiumListUtils {
public static PremiumList parseToPremiumList(
String name, CurrencyUnit currencyUnit, List<String> inputData, DateTime creationTime) {
String name, CurrencyUnit currencyUnit, List<String> inputData, Instant creationTime) {
PremiumList partialPremiumList =
new PremiumList.Builder()
.setName(name)
@@ -18,7 +18,6 @@
elementFormDefault = XmlNsForm.QUALIFIED)
@XmlAccessorType(XmlAccessType.FIELD)
@XmlJavaTypeAdapters({
@XmlJavaTypeAdapter(UtcInstantAdapter.class),
@XmlJavaTypeAdapter(UtcInstantAdapter.class)
})
package google.registry.model.transfer;
@@ -25,9 +25,9 @@ import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.security.Security;
import java.time.Duration;
import java.time.Instant;
import java.util.concurrent.TimeoutException;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.joda.time.DateTime;
/** Base for Servlets that handle all requests to our modules. */
public class ServletBase extends HttpServlet {
@@ -71,13 +71,13 @@ public class ServletBase extends HttpServlet {
@Override
public void service(HttpServletRequest req, HttpServletResponse rsp) throws IOException {
logger.atInfo().log("Received %s request.", getClass().getSimpleName());
DateTime startTime = clock.nowUtc();
Instant startTime = clock.now();
try {
requestHandler.handleRequest(req, rsp);
} finally {
logger.atInfo().log(
"Finished %s request. Latency: %.3fs.",
getClass().getSimpleName(), (clock.nowUtc().getMillis() - startTime.getMillis()) / 1000d);
getClass().getSimpleName(), Duration.between(startTime, clock.now()).toMillis() / 1000d);
}
}
}
@@ -18,13 +18,13 @@ import static com.google.common.base.Preconditions.checkNotNull;
import com.google.auto.value.AutoBuilder;
import google.registry.util.Clock;
import java.time.Instant;
import java.util.Optional;
import org.joda.time.DateTime;
/** A record for recording attributes of a domain check metric. */
public record CheckApiMetric(
DateTime startTimestamp,
DateTime endTimestamp,
Instant startTimestamp,
Instant endTimestamp,
Status status,
Optional<Tier> tier,
Optional<Availability> availability) {
@@ -83,7 +83,7 @@ public record CheckApiMetric(
public static Builder builder(Clock clock) {
return new AutoBuilder_CheckApiMetric_Builder().startTimestamp(clock.nowUtc()).setClock(clock);
return new AutoBuilder_CheckApiMetric_Builder().startTimestamp(clock.now()).setClock(clock);
}
/** Builder for {@link CheckApiMetric}. */
@@ -100,12 +100,12 @@ public record CheckApiMetric(
}
public CheckApiMetric build() {
return this.endTimestamp(clock.nowUtc()).autoBuild();
return this.endTimestamp(clock.now()).autoBuild();
}
abstract Builder startTimestamp(DateTime startTimestamp);
abstract Builder startTimestamp(Instant startTimestamp);
abstract Builder endTimestamp(DateTime endTimestamp);
abstract Builder endTimestamp(Instant endTimestamp);
public abstract Builder status(Status status);
@@ -22,13 +22,13 @@ import com.google.common.collect.Iterables;
import google.registry.model.eppoutput.Result.Code;
import google.registry.model.tld.Tlds;
import google.registry.util.Clock;
import java.time.Instant;
import java.util.Optional;
import org.joda.time.DateTime;
/** A record for recording attributes of an EPP metric. */
public record EppMetric(
DateTime startTimestamp,
DateTime endTimestamp,
Instant startTimestamp,
Instant endTimestamp,
Optional<String> commandName,
Optional<String> registrarId,
Optional<String> tld,
@@ -46,16 +46,14 @@ public record EppMetric(
* <p>The start timestamp is recorded now, and the end timestamp at {@code build()}.
*/
public static Builder builderForRequest(Clock clock) {
return builder()
.setStartTimestamp(clock.nowUtc())
.setClock(clock);
return builder().setStartTimestamp(clock.now()).setClock(clock);
}
public DateTime getStartTimestamp() {
public Instant getStartTimestamp() {
return startTimestamp;
}
public DateTime getEndTimestamp() {
public Instant getEndTimestamp() {
return endTimestamp;
}
@@ -82,9 +80,9 @@ public record EppMetric(
/** Builder-only clock to support automatic recording of endTimestamp on {@link #build()}. */
private Clock clock = null;
abstract Builder setStartTimestamp(DateTime startTimestamp);
abstract Builder setStartTimestamp(Instant startTimestamp);
abstract Builder setEndTimestamp(DateTime endTimestamp);
abstract Builder setEndTimestamp(Instant endTimestamp);
abstract Builder setCommandName(String commandName);
@@ -141,7 +139,7 @@ public record EppMetric(
*/
public EppMetric build() {
if (clock != null) {
setEndTimestamp(clock.nowUtc());
setEndTimestamp(clock.now());
}
return autoBuild();
}
@@ -30,7 +30,7 @@ import google.registry.util.GoogleCredentialsBundle;
import google.registry.util.MetricParameters;
import jakarta.inject.Named;
import jakarta.inject.Singleton;
import org.joda.time.Duration;
import java.time.Duration;
/** Dagger module for monitoring and Google Stackdriver service connection objects. */
@Module
@@ -45,7 +45,7 @@ public final class StackdriverModule {
@Provides
@Named("spoofedGceInstanceId")
static String providesSpoofedGceInstanceId(Clock clock) {
return clock.nowUtc().toString();
return clock.now().toString();
}
@Provides
@@ -84,7 +84,7 @@ public final class StackdriverModule {
return new MetricReporter(
metricWriter,
writeInterval.getStandardSeconds(),
writeInterval.toSeconds(),
new ThreadFactoryBuilder().setDaemon(true).build());
}
}
@@ -227,7 +227,7 @@ public class MosApiMetrics {
}
private void pushBatchMetrics(ImmutableList<TldServiceState> states) {
Instant now = Instant.ofEpochMilli(clock.nowUtc().getMillis());
Instant now = clock.now();
TimeInterval interval = new TimeInterval().setEndTime(now.toString());
Stream<TimeSeries> allTimeSeriesStream =
states.stream().flatMap(state -> createMetricsForState(state, interval));
@@ -21,12 +21,11 @@ import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.time.Duration;
import java.util.Objects;
import javax.annotation.Nullable;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.usertype.UserType;
import org.joda.time.Duration;
import org.joda.time.Period;
import org.postgresql.util.PGInterval;
/**
@@ -108,43 +107,31 @@ public class DurationUserType implements UserType<Duration> {
}
public static PGInterval convertToPGInterval(Duration duration) {
// When the period is created from duration by calling duration.toPeriod(), only precise fields
// in the period type will be used. Thus, only the hour, minute, second and millisecond fields
// on the period will be used. The year, month, week and day fields will not be populated:
// 1. If the duration is small, less than one day, then this method will just set
// hours/minutes/seconds correctly.
// 2. If the duration is larger than one day then all the remaining duration will
// be stored in the largest available field, hours in this case.
// So, when we convert the period to a PGInterval instance, we set the days field by extracting
// it from period's hours field.
Period period = duration.toPeriod();
PGInterval interval = new PGInterval();
interval.setDays(period.getHours() / 24);
interval.setHours(period.getHours() % 24);
interval.setMinutes(period.getMinutes());
double millis = (double) period.getMillis() / 1000;
interval.setSeconds(period.getSeconds() + millis);
long seconds = duration.getSeconds();
int nanos = duration.getNano();
interval.setDays((int) (seconds / 86400));
seconds %= 86400;
interval.setHours((int) (seconds / 3600));
seconds %= 3600;
interval.setMinutes((int) (seconds / 60));
seconds %= 60;
interval.setSeconds(seconds + (double) nanos / 1_000_000_000);
return interval;
}
@Nullable
public static Duration convertToDuration(PGInterval dbData) {
PGInterval interval = null;
try {
interval = new PGInterval(dbData.toString());
} catch (SQLException e) {
throw new RuntimeException(e);
}
if (interval.equals(new PGInterval())) {
if (dbData == null) {
return null;
}
final int days = interval.getDays();
final int hours = interval.getHours();
final int mins = interval.getMinutes();
final int secs = (int) interval.getSeconds();
final int millis = interval.getMicroSeconds() / 1000;
return new Period(0, 0, 0, days, hours, mins, secs, millis).toStandardDuration();
double seconds = dbData.getSeconds();
long fullSeconds = (long) seconds;
int nanos = (int) Math.round((seconds - fullSeconds) * 1_000_000_000);
return Duration.ofDays(dbData.getDays())
.plusHours(dbData.getHours())
.plusMinutes(dbData.getMinutes())
.plusSeconds(fullSeconds)
.plusNanos(nanos);
}
}
@@ -1,38 +0,0 @@
// Copyright 2020 The Nomulus Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package google.registry.persistence.converter;
import static google.registry.util.DateTimeUtils.toLocalDate;
import static google.registry.util.DateTimeUtils.toSqlDate;
import jakarta.persistence.AttributeConverter;
import jakarta.persistence.Converter;
import java.sql.Date;
import org.joda.time.LocalDate;
/** JPA converter for {@link LocalDate}, to/from {@link Date}. */
@Converter(autoApply = true)
public class LocalDateConverter implements AttributeConverter<LocalDate, Date> {
@Override
public Date convertToDatabaseColumn(LocalDate attribute) {
return attribute == null ? null : toSqlDate(attribute);
}
@Override
public LocalDate convertToEntityAttribute(Date dbData) {
return dbData == null ? null : toLocalDate(dbData);
}
}
@@ -46,7 +46,7 @@ public abstract class TimedTransitionBaseUserType<V extends Serializable>
@Override
Map<String, String> toStringMap(TimedTransitionProperty<V> map) {
return map.toValueMapInstant().entrySet().stream()
return map.toValueMap().entrySet().stream()
.collect(toImmutableMap(e -> formatInstant(e.getKey()), e -> valueToString(e.getValue())));
}
@@ -59,6 +59,6 @@ public abstract class TimedTransitionBaseUserType<V extends Serializable>
Ordering.natural(),
e -> parseInstant(e.getKey()),
e -> stringToValue(e.getValue())));
return TimedTransitionProperty.fromValueMapInstant(valueMap);
return TimedTransitionProperty.fromValueMap(valueMap);
}
}
@@ -34,7 +34,6 @@ import java.util.concurrent.Callable;
import java.util.concurrent.atomic.AtomicLong;
import java.util.function.Function;
import java.util.stream.Stream;
import org.joda.time.DateTime;
/**
* A {@link JpaTransactionManager} that load-balances across multiple read-only replicas.
@@ -156,11 +155,6 @@ public class DelegatingReplicaJpaTransactionManager implements JpaTransactionMan
});
}
@Override
public DateTime getTransactionTime() {
return getReplica().getTransactionTime();
}
@Override
public Instant getTxTime() {
return getReplica().getTxTime();
@@ -21,7 +21,6 @@ import static com.google.common.collect.ImmutableMap.toImmutableMap;
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;
@@ -83,7 +82,6 @@ import javax.annotation.Nullable;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Environment;
import org.joda.time.DateTime;
/** Implementation of {@link JpaTransactionManager} for JPA compatible database. */
public class JpaTransactionManagerImpl implements JpaTransactionManager {
@@ -340,11 +338,6 @@ public class JpaTransactionManagerImpl implements JpaTransactionManager {
return TransactionIsolationLevel.fromMode(mode);
}
@Override
public DateTime getTransactionTime() {
return toDateTime(getTxTime());
}
@Override
public Instant getTxTime() {
assertInTransaction();
@@ -25,7 +25,6 @@ import java.util.NoSuchElementException;
import java.util.Optional;
import java.util.concurrent.Callable;
import java.util.stream.Stream;
import org.joda.time.DateTime;
/**
* This interface defines the methods to execute database operations with or without a transaction.
@@ -129,10 +128,6 @@ 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();
@@ -282,7 +282,7 @@ public abstract class RdapSearchActionBase extends RdapActionBase {
* there are no pending deletes.
*
* <p>In such cases, it is sufficient to check whether {@code deletionTime} is equal to {@code
* END_OF_TIME}, because any other value means it has already been deleted. This allows us to use
* END_INSTANT}, because any other value means it has already been deleted. This allows us to use
* an equality query for the deletion time.
*
* @param clazz the type of resource to be queried
@@ -14,8 +14,6 @@
package google.registry.rde;
import static google.registry.util.DateTimeUtils.toDateTime;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableSet;
import google.registry.model.domain.Domain;
@@ -89,19 +87,19 @@ final class DomainToXjcConverter {
// o An OPTIONAL <crDate> element that contains the date and time of
// the domain name object creation. This element MUST be present if
// the domain name has been allocated.
bean.setCrDate(toDateTime(model.getCreationTime()));
bean.setCrDate(model.getCreationTime());
// o An OPTIONAL <exDate> element that contains the date and time
// 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(toDateTime(model.getRegistrationExpirationTime()));
bean.setExDate(model.getRegistrationExpirationTime());
// o An OPTIONAL <upDate> 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(toDateTime(model.getLastEppUpdateTime()));
bean.setUpDate(model.getLastEppUpdateTime());
// o An OPTIONAL <upRr> element that contains the identifier of the
// registrar that last updated the domain name object. This element
@@ -114,7 +112,7 @@ final class DomainToXjcConverter {
// the most recent domain object successful transfer. This element
// MUST NOT be present if the domain name object has never been
// transferred.
bean.setTrDate(toDateTime(model.getLastTransferTime()));
bean.setTrDate(model.getLastTransferTime());
// o One or more <status> elements that contain the current status
// descriptors associated with the domain name.
@@ -226,9 +224,9 @@ final class DomainToXjcConverter {
XjcEppcomTrStatusType.fromValue(model.getTransferStatus().getXmlName()));
bean.setReRr(RdeUtils.makeXjcRdeRrType(model.getGainingRegistrarId()));
bean.setAcRr(RdeUtils.makeXjcRdeRrType(model.getLosingRegistrarId()));
bean.setReDate(toDateTime(model.getTransferRequestTime()));
bean.setAcDate(toDateTime(model.getPendingTransferExpirationTime()));
bean.setExDate(toDateTime(model.getTransferredRegistrationExpirationTime()));
bean.setReDate(model.getTransferRequestTime());
bean.setAcDate(model.getPendingTransferExpirationTime());
bean.setExDate(model.getTransferredRegistrationExpirationTime());
return bean;
}
@@ -15,7 +15,6 @@
package google.registry.rde;
import static com.google.common.base.Preconditions.checkArgument;
import static google.registry.util.DateTimeUtils.toDateTime;
import com.google.common.net.InetAddresses;
import google.registry.model.domain.Domain;
@@ -70,13 +69,13 @@ final class HostToXjcConverter {
XjcRdeHost bean = new XjcRdeHost();
bean.setName(model.getHostName());
bean.setRoid(model.getRepoId());
bean.setCrDate(toDateTime(model.getCreationTime()));
bean.setUpDate(toDateTime(model.getLastEppUpdateTime()));
bean.setCrDate(model.getCreationTime());
bean.setUpDate(model.getLastEppUpdateTime());
bean.setCrRr(RdeAdapter.convertRr(model.getCreationRegistrarId(), null));
bean.setUpRr(RdeAdapter.convertRr(model.getLastEppUpdateRegistrarId(), null));
bean.setCrRr(RdeAdapter.convertRr(model.getCreationRegistrarId(), null));
bean.setClID(registrarId);
bean.setTrDate(toDateTime(lastTransferTime));
bean.setTrDate(lastTransferTime);
for (StatusValue status : model.getStatusValues()) {
// TODO(b/34844887): Remove when PENDING_TRANSFER is not persisted on host resources.
if (status.equals(StatusValue.PENDING_TRANSFER)) {
@@ -14,8 +14,6 @@
package google.registry.rde;
import static google.registry.util.DateTimeUtils.toDateTime;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
import google.registry.model.rde.RdeMode;
@@ -67,8 +65,8 @@ public final class RdeCounter {
XjcRdeReport report = new XjcRdeReport();
report.setId(id);
report.setKind(XjcRdeDepositTypeType.FULL);
report.setCrDate(toDateTime(watermark));
report.setWatermark(toDateTime(watermark));
report.setCrDate(watermark);
report.setWatermark(watermark);
report.setVersion(ICANN_REPORT_SPEC_VERSION);
report.setRydeSpecEscrow(URI_ESCROW);
report.setRydeSpecMapping(URI_MAPPING);
@@ -15,7 +15,6 @@
package google.registry.rde;
import static com.google.common.base.Verify.verify;
import static google.registry.util.DateTimeUtils.toDateTime;
import static java.nio.charset.StandardCharsets.UTF_8;
import com.google.common.flogger.FluentLogger;
@@ -75,7 +74,7 @@ public final class RdeMarshaller implements Serializable {
contents.getContents().add(new XjcRdePolicyElement(policy));
XjcRdeDeposit deposit = new XjcRdeDeposit();
deposit.setId(depositId);
deposit.setWatermark(toDateTime(watermark));
deposit.setWatermark(watermark);
deposit.setType(XjcRdeDepositTypeType.FULL);
if (revision > 0) {
deposit.setResend(revision);
@@ -16,7 +16,6 @@ package google.registry.rde;
import static com.google.common.base.MoreObjects.firstNonNull;
import static com.google.common.base.Preconditions.checkState;
import static google.registry.util.DateTimeUtils.toDateTime;
import com.google.common.collect.ImmutableMap;
import google.registry.model.registrar.Registrar;
@@ -140,13 +139,13 @@ final class RegistrarToXjcConverter {
// o A <crDate> element that contains the date and time of registrar-
// object creation.
bean.setCrDate(toDateTime(model.getCreationTime()));
bean.setCrDate(model.getCreationTime());
// o An OPTIONAL <upDate> element that contains the date and time of
// the most recent RDE registrar-object modification. This element
// MUST NOT be present if the rdeRegistrar object has never been
// modified.
bean.setUpDate(toDateTime(model.getLastUpdateTime()));
bean.setUpDate(model.getLastUpdateTime());
return bean;
}
@@ -14,7 +14,6 @@
package google.registry.reporting.spec11;
import static google.registry.util.DateTimeUtils.toJodaLocalDate;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import dagger.Module;
@@ -32,7 +31,7 @@ public class Spec11Module {
@Provides
@Spec11ReportFilePath
static String provideSpec11ReportFilePath(LocalDate localDate) {
return Spec11Pipeline.getSpec11ReportFilePath(toJodaLocalDate(localDate));
return Spec11Pipeline.getSpec11ReportFilePath(localDate);
}
/** Dagger qualifier for the subdirectory we stage to/upload from for Spec11 reports. */
@@ -15,7 +15,6 @@
package google.registry.reporting.spec11;
import static com.google.common.collect.ImmutableSet.toImmutableSet;
import static google.registry.util.DateTimeUtils.toJodaLocalDate;
import static java.nio.charset.StandardCharsets.UTF_8;
import com.google.cloud.storage.BlobId;
@@ -100,8 +99,7 @@ public class Spec11RegistrarThreatMatchesParser {
}
private BlobId getGcsFilename(LocalDate localDate) {
return BlobId.of(
reportingBucket, Spec11Pipeline.getSpec11ReportFilePath(toJodaLocalDate(localDate)));
return BlobId.of(reportingBucket, Spec11Pipeline.getSpec11ReportFilePath(localDate));
}
private RegistrarThreatMatches parseRegistrarThreatMatch(String line) throws JSONException {
@@ -21,8 +21,8 @@ import static com.google.common.net.MediaType.JSON_UTF_8;
import static org.json.simple.JSONValue.toJSONString;
import jakarta.inject.Inject;
import java.time.Instant;
import java.util.Map;
import org.joda.time.DateTime;
/** JSON response object. */
public class JsonResponse {
@@ -72,7 +72,7 @@ public class JsonResponse {
*
* <p>see Response#setDateHeader
*/
public void setDateHeader(String header, DateTime timestamp) {
public void setDateHeader(String header, Instant timestamp) {
response.setDateHeader(header, timestamp);
}
}
@@ -34,11 +34,11 @@ import jakarta.inject.Provider;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.time.Duration;
import java.time.Instant;
import java.util.Objects;
import java.util.Optional;
import javax.annotation.Nullable;
import org.joda.time.DateTime;
import org.joda.time.Duration;
/**
* Dagger-based request processor.
@@ -172,7 +172,7 @@ public class RequestHandler<C> {
.build();
// Apply the selected Route to the component to produce an Action instance, and run it.
boolean success = true;
DateTime startTime = clock.nowUtc();
Instant startTime = clock.now();
try {
route.get().instantiator().apply(component).run();
if (route.get().action().automaticallyPrintOk()) {
@@ -188,7 +188,7 @@ public class RequestHandler<C> {
logger.atSevere().withCause(e).log("Encountered internal server error");
} finally {
requestMetrics.record(
new Duration(startTime, clock.nowUtc()),
Duration.between(startTime, clock.now()),
path,
method,
authResult.get().authLevel(),
@@ -25,9 +25,9 @@ import com.google.monitoring.metrics.EventMetric;
import com.google.monitoring.metrics.LabelDescriptor;
import com.google.monitoring.metrics.MetricRegistryImpl;
import google.registry.request.auth.AuthSettings.AuthLevel;
import java.time.Duration;
import java.util.List;
import java.util.stream.Collectors;
import org.joda.time.Duration;
class RequestMetrics {
@@ -54,14 +54,14 @@ class RequestMetrics {
public void record(
Duration duration, String path, Action.Method method, AuthLevel authLevel, boolean success) {
requestDurationMetric.record(
duration.getMillis(),
duration.toMillis(),
truncatePath(path),
String.valueOf(method),
String.valueOf(authLevel),
String.valueOf(success));
logger.atInfo().log(
"Action called for path=%s, method=%s, authLevel=%s, success=%s. Took: %.3fs.",
path, method, authLevel, success, duration.getMillis() / 1000d);
path, method, authLevel, success, duration.toMillis() / 1000d);
}
private static String truncatePath(String path) {
@@ -19,7 +19,7 @@ import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import org.joda.time.DateTime;
import java.time.Instant;
/**
* HTTP request response object.
@@ -55,7 +55,7 @@ public interface Response {
*
* @see HttpServletResponse#setDateHeader(String, long)
*/
void setDateHeader(String header, DateTime timestamp);
void setDateHeader(String header, Instant timestamp);
/**
* Adds a cookie to the response
@@ -20,7 +20,7 @@ import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import org.joda.time.DateTime;
import java.time.Instant;
/** HTTP response object. */
public final class ResponseImpl implements Response {
@@ -62,8 +62,8 @@ public final class ResponseImpl implements Response {
}
@Override
public void setDateHeader(String header, DateTime timestamp) {
rsp.setDateHeader(header, timestamp.getMillis());
public void setDateHeader(String header, Instant timestamp) {
rsp.setDateHeader(header, timestamp.toEpochMilli());
}
@Override
@@ -17,7 +17,6 @@ package google.registry.security;
import static com.google.common.io.BaseEncoding.base64Url;
import static google.registry.util.PreconditionsUtils.checkArgumentNotNull;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.joda.time.DateTimeZone.UTC;
import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
@@ -26,9 +25,9 @@ import com.google.common.hash.Hashing;
import google.registry.model.server.ServerSecret;
import google.registry.util.Clock;
import jakarta.inject.Inject;
import java.time.Duration;
import java.time.Instant;
import java.util.List;
import org.joda.time.DateTime;
import org.joda.time.Duration;
/** Helper class for generating and validate XSRF tokens. */
public final class XsrfTokenManager {
@@ -40,7 +39,7 @@ public final class XsrfTokenManager {
public static final String P_CSRF_TOKEN = "xsrfToken";
/** Maximum age of an acceptable XSRF token. */
private static final Duration XSRF_VALIDITY = Duration.standardDays(1);
private static final Duration XSRF_VALIDITY = Duration.ofDays(1);
/** Token version identifier for version 1. */
private static final String VERSION_1 = "1";
@@ -57,7 +56,7 @@ public final class XsrfTokenManager {
/** Generates an XSRF token for a given user based on email address. */
public String generateToken(String email) {
checkArgumentNotNull(email);
long timestampMillis = clock.nowUtc().getMillis();
long timestampMillis = clock.now().toEpochMilli();
return encodeToken(ServerSecret.get().asBytes(), email, timestampMillis);
}
@@ -97,7 +96,7 @@ public final class XsrfTokenManager {
logger.atWarning().log("Bad timestamp in XSRF token: %s", token);
return false;
}
if (new DateTime(timestampMillis, UTC).plus(XSRF_VALIDITY).isBefore(clock.nowUtc())) {
if (Instant.ofEpochMilli(timestampMillis).plus(XSRF_VALIDITY).isBefore(clock.now())) {
logger.atInfo().log("Expired timestamp in XSRF token: %s", token);
return false;
}
@@ -34,7 +34,7 @@ import java.security.GeneralSecurityException;
import java.security.cert.CertificateParsingException;
import java.security.cert.X509CRL;
import java.security.cert.X509Certificate;
import java.sql.Timestamp;
import java.util.Date;
import java.util.Optional;
import javax.annotation.concurrent.Immutable;
import javax.annotation.concurrent.ThreadSafe;
@@ -128,7 +128,7 @@ public final class TmchCertificateAuthority {
*/
public void verify(X509Certificate cert) throws GeneralSecurityException {
synchronized (TmchCertificateAuthority.class) {
X509Utils.verifyCertificate(getAndValidateRoot(), getCrl(), cert, clock.nowUtc());
X509Utils.verifyCertificate(getAndValidateRoot(), getCrl(), cert, clock.now());
}
}
@@ -152,7 +152,7 @@ public final class TmchCertificateAuthority {
} catch (Exception e) {
logger.atWarning().withCause(e).log("Old CRL is invalid, ignored during CRL update.");
}
X509Utils.verifyCrl(getAndValidateRoot(), oldCrl, newCrl, clock.nowUtc());
X509Utils.verifyCrl(getAndValidateRoot(), oldCrl, newCrl, clock.now());
TmchCrl.set(asciiCrl, url);
}
@@ -162,7 +162,7 @@ public final class TmchCertificateAuthority {
// The current production certificate expires on 2023-07-23. Future code monkey be reminded,
// if you are looking at this code because the next line throws an exception, ask ICANN for a
// new root certificate! (preferably before the current one expires...)
root.checkValidity(Timestamp.from(clock.now()));
root.checkValidity(Date.from(clock.now()));
return root;
} catch (Exception e) {
if (e instanceof GeneralSecurityException generalSecurityException) {
@@ -20,7 +20,7 @@ import google.registry.model.ForeignKeyUtils;
import google.registry.model.domain.Domain;
import google.registry.model.host.Host;
import google.registry.persistence.VKey;
import org.joda.time.DateTime;
import java.time.Instant;
/** Container class for static utility methods. */
class CommandUtilities {
@@ -36,7 +36,7 @@ class CommandUtilities {
this.clazz = clazz;
}
public VKey<? extends EppResource> getKey(String uniqueId, DateTime now) {
public VKey<? extends EppResource> getKey(String uniqueId, Instant now) {
return ForeignKeyUtils.loadKey(clazz, uniqueId, now)
.orElseThrow(
() ->
@@ -48,10 +48,7 @@ public class ConfigureFeatureFlagCommand extends MutatingCommand {
for (FeatureName name : mainParameters) {
Optional<FeatureFlag> oldFlag = FeatureFlag.getUncached(name);
FeatureFlag.Builder newFlagBuilder =
new FeatureFlag()
.asBuilder()
.setFeatureName(name)
.setStatusMapInstant(featureStatusTransitions);
new FeatureFlag().asBuilder().setFeatureName(name).setStatusMap(featureStatusTransitions);
stageEntityChange(oldFlag.orElse(null), newFlagBuilder.build());
}
}
@@ -40,6 +40,7 @@ import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Instant;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Map;
@@ -48,7 +49,6 @@ import java.util.Set;
import java.util.stream.Collectors;
import org.joda.money.CurrencyUnit;
import org.joda.money.Money;
import org.joda.time.DateTime;
import org.yaml.snakeyaml.Yaml;
/** Command to create or update a {@link Tld} using a YAML file. */
@@ -152,7 +152,7 @@ public class ConfigureTldCommand extends MutatingCommand {
checkCurrency(newTld);
// bsaEnrollStartTime only exists in DB. Need to carry it over to the updated copy. See Tld.java
// for more information.
Optional<DateTime> bsaEnrollTime =
Optional<Instant> bsaEnrollTime =
Optional.ofNullable(oldTld).flatMap(Tld::getBsaEnrollStartTime);
if (bsaEnrollTime.isPresent()) {
newTld = newTld.asBuilder().setBsaEnrollStartTime(bsaEnrollTime).build();
@@ -19,7 +19,6 @@ import static com.google.common.base.Strings.isNullOrEmpty;
import static com.google.common.base.Verify.verify;
import static com.google.common.collect.ImmutableList.toImmutableList;
import static com.google.common.collect.ImmutableSet.toImmutableSet;
import static google.registry.util.DateTimeUtils.toInstant;
import static google.registry.util.RegistrarUtils.normalizeRegistrarName;
import static java.nio.charset.StandardCharsets.US_ASCII;
@@ -41,6 +40,7 @@ import google.registry.util.Clock;
import jakarta.inject.Inject;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedHashMap;
@@ -50,7 +50,6 @@ import java.util.Objects;
import java.util.Optional;
import javax.annotation.Nullable;
import org.joda.money.CurrencyUnit;
import org.joda.time.DateTime;
/** Shared base class for commands to create or update a {@link Registrar}. */
abstract class CreateOrUpdateRegistrarCommand extends MutatingCommand {
@@ -275,7 +274,7 @@ abstract class CreateOrUpdateRegistrarCommand extends MutatingCommand {
@Override
protected final void init() throws Exception {
initRegistrarCommand();
DateTime now = clock.nowUtc();
Instant now = clock.now();
for (String clientId : mainParameters) {
Registrar oldRegistrar = getOldRegistrar(clientId);
Registrar.Builder builder =
@@ -339,10 +338,9 @@ abstract class CreateOrUpdateRegistrarCommand extends MutatingCommand {
verify(
oldRegistrar.getClientCertificate().isPresent(),
"Primary cert is absent. Rotation may remove a failover certificate still in use.");
builder.setFailoverClientCertificate(
oldRegistrar.getClientCertificate().get(), toInstant(now));
builder.setFailoverClientCertificate(oldRegistrar.getClientCertificate().get(), now);
}
builder.setClientCertificate(asciiCert, toInstant(now));
builder.setClientCertificate(asciiCert, now);
}
if (rotatePrimaryCert && clientCertificateFilename == null) {
throw new IllegalArgumentException("--rotate_primary_cert must be used with --cert_file.");
@@ -353,7 +351,7 @@ abstract class CreateOrUpdateRegistrarCommand extends MutatingCommand {
if (!asciiCert.equals("")) {
certificateChecker.validateCertificate(asciiCert);
}
builder.setFailoverClientCertificate(asciiCert, toInstant(now));
builder.setFailoverClientCertificate(asciiCert, now);
}
Optional.ofNullable(ianaId).ifPresent(i -> builder.setIanaIdentifier(i.orElse(null)));
Optional.ofNullable(poNumber).ifPresent(builder::setPoNumber);
@@ -26,8 +26,8 @@ import com.google.common.base.Splitter;
import com.google.common.base.Strings;
import google.registry.model.tld.label.ReservedList;
import java.nio.file.Files;
import java.time.Instant;
import java.util.List;
import org.joda.time.DateTime;
/** Command to create a {@link ReservedList}. */
@Parameters(separators = " =", commandDescription = "Create a ReservedList.")
@@ -50,7 +50,7 @@ final class CreateReservedListCommand extends CreateOrUpdateReservedListCommand
if (!override) {
validateListName(name);
}
DateTime now = clock.nowUtc();
Instant now = clock.now();
List<String> allLines = Files.readAllLines(input, UTF_8);
reservedList =
new ReservedList.Builder()
@@ -18,8 +18,6 @@ import static com.google.common.base.Preconditions.checkArgument;
import static google.registry.batch.AsyncTaskEnqueuer.QUEUE_ASYNC_ACTIONS;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.tools.LockOrUnlockDomainCommand.REGISTRY_LOCK_STATUSES;
import static google.registry.util.DateTimeUtils.toInstant;
import static google.registry.util.DateTimeUtils.toJavaDuration;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.ImmutableSet;
@@ -40,10 +38,10 @@ import google.registry.request.Action;
import google.registry.util.StringGenerator;
import jakarta.inject.Inject;
import jakarta.inject.Named;
import java.time.Duration;
import java.time.Instant;
import java.util.Optional;
import javax.annotation.Nullable;
import org.joda.time.DateTime;
import org.joda.time.Duration;
/**
* Utility functions for validating and applying {@link RegistryLock}s.
@@ -135,11 +133,11 @@ public final class DomainLockUtils {
String domainName, String registrarId, @Nullable String registryLockEmail, boolean isAdmin) {
return tm().transact(
() -> {
DateTime now = tm().getTransactionTime();
Instant now = tm().getTxTime();
RegistryLock newLock =
RegistryLockDao.save(
createLockBuilder(domainName, registrarId, registryLockEmail, isAdmin)
.setLockCompletionTime(toInstant(now))
.setLockCompletionTime(now)
.build());
applyLockStatuses(newLock, now, isAdmin);
setAsRelock(newLock);
@@ -157,11 +155,11 @@ public final class DomainLockUtils {
RegistryLock lock =
tm().transact(
() -> {
DateTime now = tm().getTransactionTime();
Instant now = tm().getTxTime();
RegistryLock result =
RegistryLockDao.save(
createUnlockBuilder(domainName, registrarId, isAdmin, relockDuration)
.setUnlockCompletionTime(toInstant(now))
.setUnlockCompletionTime(now)
.build());
removeLockStatuses(result, isAdmin, now);
return result;
@@ -202,34 +200,32 @@ public final class DomainLockUtils {
String.valueOf(lockRevisionId),
RelockDomainAction.PREVIOUS_ATTEMPTS_PARAM,
String.valueOf(previousAttempts)),
toJavaDuration(countdown)));
countdown));
}
private RegistryLock verifyAndApplyLock(RegistryLock lock, boolean isAdmin) {
DateTime now = tm().getTransactionTime();
Instant now = tm().getTxTime();
checkArgument(
!lock.isLockRequestExpired(toInstant(now)),
"The pending lock has expired; please try again");
!lock.isLockRequestExpired(now), "The pending lock has expired; please try again");
checkArgument(!lock.isSuperuser() || isAdmin, "Non-admin user cannot complete admin lock");
RegistryLock newLock =
RegistryLockDao.save(lock.asBuilder().setLockCompletionTime(toInstant(now)).build());
RegistryLockDao.save(lock.asBuilder().setLockCompletionTime(now).build());
setAsRelock(newLock);
applyLockStatuses(newLock, now, isAdmin);
return newLock;
}
private RegistryLock verifyAndApplyUnlock(RegistryLock lock, boolean isAdmin) {
DateTime now = tm().getTransactionTime();
Instant now = tm().getTxTime();
checkArgument(
!lock.isUnlockRequestExpired(toInstant(now)),
"The pending unlock has expired; please try again");
!lock.isUnlockRequestExpired(now), "The pending unlock has expired; please try again");
checkArgument(isAdmin || !lock.isSuperuser(), "Non-admin user cannot complete admin unlock");
RegistryLock newLock =
RegistryLockDao.save(lock.asBuilder().setUnlockCompletionTime(toInstant(now)).build());
RegistryLockDao.save(lock.asBuilder().setUnlockCompletionTime(now).build());
removeLockStatuses(newLock, isAdmin, now);
return newLock;
}
@@ -241,7 +237,7 @@ public final class DomainLockUtils {
private RegistryLock.Builder createLockBuilder(
String domainName, String registrarId, @Nullable String registryLockEmail, boolean isAdmin) {
DateTime now = tm().getTransactionTime();
Instant now = tm().getTxTime();
Domain domain = getDomain(domainName, registrarId, now);
verifyDomainNotLocked(domain, isAdmin);
@@ -250,7 +246,7 @@ public final class DomainLockUtils {
.ifPresent(
previousLock ->
checkArgument(
previousLock.isLockRequestExpired(toInstant(now))
previousLock.isLockRequestExpired(now)
|| previousLock.getUnlockCompletionTime().isPresent()
|| isAdmin,
"A pending or completed lock action already exists for %s",
@@ -266,7 +262,7 @@ public final class DomainLockUtils {
private RegistryLock.Builder createUnlockBuilder(
String domainName, String registrarId, boolean isAdmin, Optional<Duration> relockDuration) {
DateTime now = tm().getTransactionTime();
Instant now = tm().getTxTime();
Domain domain = getDomain(domainName, registrarId, now);
Optional<RegistryLock> lockOptional =
RegistryLockDao.getMostRecentVerifiedLockByRepoId(domain.getRepoId());
@@ -285,7 +281,7 @@ public final class DomainLockUtils {
new RegistryLock.Builder()
.setRepoId(domain.getRepoId())
.setDomainName(domainName)
.setLockCompletionTime(toInstant(now))
.setLockCompletionTime(now)
.setRegistrarId(registrarId));
} else {
RegistryLock lock =
@@ -296,7 +292,7 @@ public final class DomainLockUtils {
checkArgument(
lock.isLocked(), "Lock object for domain %s is not currently locked", domainName);
checkArgument(
lock.getUnlockRequestTime().isEmpty() || lock.isUnlockRequestExpired(toInstant(now)),
lock.getUnlockRequestTime().isEmpty() || lock.isUnlockRequestExpired(now),
"A pending unlock action already exists for %s",
domainName);
checkArgument(
@@ -311,7 +307,7 @@ public final class DomainLockUtils {
return newLockBuilder
.setVerificationCode(stringGenerator.createString(VERIFICATION_CODE_LENGTH))
.isSuperuser(isAdmin)
.setUnlockRequestTime(toInstant(now))
.setUnlockRequestTime(now)
.setRegistrarId(registrarId);
}
@@ -329,7 +325,7 @@ public final class DomainLockUtils {
domain.getDomainName());
}
private Domain getDomain(String domainName, String registrarId, DateTime now) {
private Domain getDomain(String domainName, String registrarId, Instant now) {
Domain domain =
ForeignKeyUtils.loadResource(Domain.class, domainName, now)
.orElseThrow(() -> new IllegalArgumentException("Domain doesn't exist"));
@@ -351,7 +347,7 @@ public final class DomainLockUtils {
String.format("Invalid verification code \"%s\"", verificationCode)));
}
private void applyLockStatuses(RegistryLock lock, DateTime lockTime, boolean isAdmin) {
private void applyLockStatuses(RegistryLock lock, Instant lockTime, boolean isAdmin) {
Domain domain = getDomain(lock.getDomainName(), lock.getRegistrarId(), lockTime);
verifyDomainNotLocked(domain, isAdmin);
@@ -364,7 +360,7 @@ public final class DomainLockUtils {
saveEntities(newDomain, lock, lockTime, true);
}
private void removeLockStatuses(RegistryLock lock, boolean isAdmin, DateTime unlockTime) {
private void removeLockStatuses(RegistryLock lock, boolean isAdmin, Instant unlockTime) {
Domain domain = getDomain(lock.getDomainName(), lock.getRegistrarId(), unlockTime);
verifyDomainLocked(domain, isAdmin);
@@ -378,7 +374,7 @@ public final class DomainLockUtils {
saveEntities(newDomain, lock, unlockTime, false);
}
private static void saveEntities(Domain domain, RegistryLock lock, DateTime now, boolean isLock) {
private static void saveEntities(Domain domain, RegistryLock lock, Instant now, boolean isLock) {
String reason =
String.format(
"%s of a domain through a RegistryLock operation", isLock ? "Lock" : "Unlock");
@@ -388,7 +384,7 @@ public final class DomainLockUtils {
.setBySuperuser(lock.isSuperuser())
.setRequestedByRegistrar(!lock.isSuperuser())
.setType(HistoryEntry.Type.DOMAIN_UPDATE)
.setModificationTime(toInstant(now))
.setModificationTime(now)
.setDomain(domain)
.setReason(reason)
.build();
@@ -401,8 +397,8 @@ public final class DomainLockUtils {
.setTargetId(domain.getForeignKey())
.setRegistrarId(domain.getCurrentSponsorRegistrarId())
.setCost(Tld.get(domain.getTld()).getRegistryLockOrUnlockBillingCost())
.setEventTime(toInstant(now))
.setBillingTime(toInstant(now))
.setEventTime(now)
.setBillingTime(now)
.setDomainHistory(domainHistory)
.build();
tm().insert(billingEvent);
@@ -19,7 +19,6 @@ import static com.google.common.io.BaseEncoding.base16;
import static google.registry.model.tld.Tlds.assertTldExists;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.util.DateTimeUtils.isBeforeOrAt;
import static google.registry.util.DateTimeUtils.toInstant;
import static java.nio.charset.StandardCharsets.US_ASCII;
import com.beust.jcommander.Parameter;
@@ -36,9 +35,9 @@ import java.net.InetAddress;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.Instant;
import java.util.List;
import java.util.Map;
import org.joda.time.DateTime;
import org.json.simple.JSONValue;
/** Command to generate a report of all DNS data. */
@@ -66,7 +65,7 @@ final class GenerateDnsReportCommand implements Command {
}
private class Generator {
private final DateTime now = clock.nowUtc();
private final Instant now = clock.now();
private final StringBuilder result = new StringBuilder();
private boolean first = true;
@@ -81,8 +80,7 @@ final class GenerateDnsReportCommand implements Command {
.list());
for (Domain domain : domains) {
// Skip deleted domains and domains that don't get published to DNS.
if (isBeforeOrAt(domain.getDeletionTime(), toInstant(now))
|| !domain.shouldPublishToDns()) {
if (isBeforeOrAt(domain.getDeletionTime(), now) || !domain.shouldPublishToDns()) {
continue;
}
write(domain);
@@ -91,7 +89,7 @@ final class GenerateDnsReportCommand implements Command {
Iterable<Host> nameservers = tm().transact(() -> tm().loadAllOf(Host.class));
for (Host nameserver : nameservers) {
// Skip deleted hosts and external hosts.
if (isBeforeOrAt(nameserver.getDeletionTime(), toInstant(now))
if (isBeforeOrAt(nameserver.getDeletionTime(), now)
|| nameserver.getInetAddresses().isEmpty()) {
continue;
}
@@ -29,7 +29,8 @@ import jakarta.inject.Inject;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import org.joda.time.DateTime;
import java.time.Duration;
import java.time.Instant;
/** Command to generate a LORDN CSV file for an entire TLD. */
@Parameters(separators = " =", commandDescription = "Generate LORDN CSV file")
@@ -59,7 +60,7 @@ final class GenerateLordnCommand implements Command {
@Override
public void run() throws IOException {
DateTime now = clock.nowUtc();
Instant now = clock.now();
ImmutableList.Builder<String> claimsCsv = new ImmutableList.Builder<>();
ImmutableList.Builder<String> sunriseCsv = new ImmutableList.Builder<>();
tm().transact(
@@ -80,7 +81,7 @@ final class GenerateLordnCommand implements Command {
ImmutableList<String> sunriseRows = sunriseCsv.build();
ImmutableList<String> sunriseAll =
new ImmutableList.Builder<String>()
.add(String.format("1,%s,%d", now.plusMillis(1), sunriseRows.size()))
.add(String.format("1,%s,%d", now.plus(Duration.ofMillis(1)), sunriseRows.size()))
.add(LordnTaskUtils.COLUMNS_SUNRISE)
.addAll(sunriseRows)
.build();
@@ -15,7 +15,8 @@
package google.registry.tools;
import static google.registry.model.tld.Tlds.assertTldsExist;
import static org.joda.time.Duration.standardMinutes;
import static google.registry.util.DateTimeUtils.toLocalDate;
import static java.time.ZoneOffset.UTC;
import com.beust.jcommander.Parameter;
import com.beust.jcommander.Parameters;
@@ -25,9 +26,10 @@ import google.registry.tools.server.GenerateZoneFilesAction;
import google.registry.util.Clock;
import jakarta.inject.Inject;
import java.io.IOException;
import java.time.Duration;
import java.time.Instant;
import java.util.List;
import java.util.Map;
import org.joda.time.DateTime;
/** Command to generate zone files. */
@Parameters(separators = " =", commandDescription = "Generate zone files")
@@ -45,7 +47,7 @@ final class GenerateZoneFilesCommand implements CommandWithConnection {
"The date to generate the file for (defaults to today, or yesterday if run "
+ "before 00:02).",
validateWith = DateParameter.class)
private DateTime exportDate;
private Instant exportDate;
@Inject Clock clock;
@@ -59,7 +61,8 @@ final class GenerateZoneFilesCommand implements CommandWithConnection {
@Override
public void run() throws IOException {
if (exportDate == null) {
exportDate = clock.nowUtc().minus(standardMinutes(2)).withTimeAtStartOfDay();
exportDate =
toLocalDate(clock.now().minus(Duration.ofMinutes(2))).atStartOfDay(UTC).toInstant();
}
assertTldsExist(mainParameters);
ImmutableMap<String, Object> params = ImmutableMap.of(
@@ -19,10 +19,11 @@ import static com.google.common.base.Preconditions.checkArgument;
import com.beust.jcommander.Parameter;
import com.beust.jcommander.Parameters;
import google.registry.model.EppResource;
import google.registry.tools.params.InstantParameter;
import google.registry.util.Clock;
import jakarta.inject.Inject;
import java.time.Instant;
import java.util.Optional;
import org.joda.time.DateTime;
/** Abstract command to print one or more resources to stdout. */
@Parameters(separators = " =")
@@ -30,8 +31,9 @@ abstract class GetEppResourceCommand implements Command {
@Parameter(
names = "--read_timestamp",
description = "Timestamp to use when reading. May not be in the past.")
protected DateTime readTimestamp;
description = "Timestamp to use when reading. May not be in the past.",
converter = InstantParameter.class)
protected Instant readTimestamp;
@Parameter(
names = "--expand",
@@ -60,7 +62,7 @@ abstract class GetEppResourceCommand implements Command {
@Override
public void run() {
DateTime now = clock.nowUtc();
Instant now = clock.now();
if (readTimestamp == null) {
readTimestamp = now;
}
@@ -64,7 +64,7 @@ final class GetHistoryEntriesCommand implements Command {
checkArgument(
type != null && uniqueId != null,
"If either of 'type' or 'id' are set then both must be");
VKey<? extends EppResource> parentKey = type.getKey(uniqueId, clock.nowUtc());
VKey<? extends EppResource> parentKey = type.getKey(uniqueId, clock.now());
historyEntries = HistoryEntryDao.loadHistoryObjectsForResource(parentKey, after, before);
} else {
historyEntries = HistoryEntryDao.loadAllHistoryObjects(after, before);
@@ -27,9 +27,11 @@ import google.registry.model.adapters.SerializableJsonTypeAdapter;
import google.registry.util.CidrAddressBlock;
import google.registry.util.CidrAddressBlock.CidrAddressBlockAdapter;
import google.registry.util.DateTimeTypeAdapter;
import google.registry.util.DurationTypeAdapter;
import google.registry.util.InstantTypeAdapter;
import java.io.IOException;
import java.io.Serializable;
import java.time.Duration;
import java.time.Instant;
import org.joda.money.CurrencyUnit;
import org.joda.time.DateTime;
@@ -77,6 +79,7 @@ public class GsonUtils {
.registerTypeAdapter(CidrAddressBlock.class, new CidrAddressBlockAdapter())
.registerTypeAdapter(CurrencyUnit.class, new CurrencyJsonAdapter())
.registerTypeAdapter(DateTime.class, new DateTimeTypeAdapter())
.registerTypeAdapter(Duration.class, new DurationTypeAdapter())
.registerTypeAdapter(Instant.class, new InstantTypeAdapter())
.registerTypeAdapter(Serializable.class, new SerializableJsonTypeAdapter())
.registerTypeAdapterFactory(new ClassProcessingTypeAdapterFactory())
@@ -17,8 +17,6 @@ package google.registry.tools;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Strings.isNullOrEmpty;
import static google.registry.util.CollectionUtils.findDuplicates;
import static google.registry.util.DateTimeUtils.toDateTime;
import static google.registry.util.DateTimeUtils.toInstant;
import static google.registry.util.PreconditionsUtils.checkArgumentNotNull;
import com.beust.jcommander.Parameter;
@@ -28,10 +26,10 @@ import com.google.template.soy.data.SoyMapData;
import google.registry.flows.ResourceFlowUtils;
import google.registry.model.domain.Domain;
import google.registry.tools.soy.DomainRenewSoyInfo;
import java.time.Instant;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.List;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
/** A command to renew domain(s) via EPP. */
@Parameters(separators = " =", commandDescription = "Renew domain(s) via EPP.")
@@ -63,7 +61,8 @@ final class RenewDomainCommand extends MutatingEppToolCommand {
arity = 1)
Boolean requestedByRegistrar;
private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormat.forPattern("YYYY-MM-dd");
private static final DateTimeFormatter DATE_FORMATTER =
DateTimeFormatter.ofPattern("yyyy-MM-dd").withZone(ZoneOffset.UTC);
@Override
protected void initMutatingEppToolCommand()
@@ -71,16 +70,14 @@ final class RenewDomainCommand extends MutatingEppToolCommand {
String duplicates = Joiner.on(", ").join(findDuplicates(mainParameters));
checkArgument(duplicates.isEmpty(), "Duplicate domain arguments found: '%s'", duplicates);
checkArgument(period < 10, "Cannot renew domains for 10 or more years");
DateTime now = clock.nowUtc();
Instant now = clock.now();
for (String domainName : mainParameters) {
Domain domain =
ResourceFlowUtils.loadAndVerifyExistence(Domain.class, domainName, toInstant(now));
Domain domain = ResourceFlowUtils.loadAndVerifyExistence(Domain.class, domainName, now);
setSoyTemplate(DomainRenewSoyInfo.getInstance(), DomainRenewSoyInfo.RENEWDOMAIN);
SoyMapData soyMapData =
new SoyMapData(
"domainName", domain.getDomainName(),
"expirationDate",
DATE_FORMATTER.print(toDateTime(domain.getRegistrationExpirationTime())),
"expirationDate", DATE_FORMATTER.format(domain.getRegistrationExpirationTime()),
"period", String.valueOf(period));
if (requestedByRegistrar != null) {
@@ -105,7 +105,7 @@ final class SetupOteCommand extends ConfirmingCommand {
String asciiCert = MoreFiles.asCharSource(certFile, US_ASCII).read();
// Don't wait for create_registrar to fail if it's a bad certificate file.
loadCertificate(asciiCert);
oteAccountBuilder.setCertificate(asciiCert, clock.nowUtc());
oteAccountBuilder.setCertificate(asciiCert, clock.now());
}
@Override
@@ -124,11 +124,12 @@ final class SetupOteCommand extends ConfirmingCommand {
&& RegistryEnvironment.get() != RegistryEnvironment.UNITTEST) {
builder.append(
String.format(
"""
"""
WARNING: Running against %s environment. Are \
you sure you didn't mean to run this against sandbox (e.g. "-e SANDBOX")?""",
you sure you didn't mean to run this against sandbox (e.g. "-e SANDBOX")?\
""",
RegistryEnvironment.get()));
}

Some files were not shown because too many files have changed in this diff Show More