Complete Joda-Time to java.time migration (#3039)

This completes the exhaustive refactoring of foundational temporal types from Joda-Time to the native java.time API across the entire codebase.

- Replaced org.joda.time.DateTime, Instant, LocalDate, and Duration with java.time equivalents.
- Audited and updated Clock implementations (FakeClock, SystemClock). Added nowMillis(), nowDate(), and nowDateTime() to eliminate repetitive conversions and maintain parallel naming.
- Replaced ZonedDateTime with OffsetDateTime globally per go/avoid-zdt. OffsetDateTime is a better fit as we use a hardcoded ZoneOffset.UTC throughout the system, making geographical time zone rules (like daylight saving time) irrelevant and preventing serialization ambiguities. Added a presubmit check.
- Completely removed all transitional bridge methods from DateTimeUtils and deleted obsolete converters (e.g., DateTimeConverter).
- Updated testing infrastructure, Apache Beam pipelines, custom JCommander parameters, and networking modules to solely rely on java.time primitives.
- Retained the lone necessary org.joda.time.Instant usage in SafeBrowsingTransforms required by the Apache Beam API.
- Cleared Gradle lockfiles and removed the joda-time dependency entirely from the build configuration.
This commit is contained in:
Ben McIlwain
2026-05-13 16:07:19 +00:00
committed by GitHub
parent b33c2f4874
commit 56fe588b56
218 changed files with 589 additions and 1390 deletions
-3
View File
@@ -198,7 +198,6 @@ dependencies {
implementation deps['jakarta.persistence:jakarta.persistence-api']
implementation deps['jakarta.servlet:jakarta.servlet-api']
implementation deps['jakarta.xml.bind:jakarta.xml.bind-api']
implementation deps['joda-time:joda-time']
implementation deps['org.antlr:antlr4']
implementation deps['org.antlr:antlr4-runtime']
implementation deps['org.apache.avro:avro']
@@ -479,7 +478,6 @@ Optional<List<String>> getToolArgsList() {
return Optional.empty()
}
// To run the nomulus tools with these command line tokens:
// "--foo", "bar baz", "--qux=quz"
// gradle core:registryTool --args="--foo 'bar baz' --qux=quz"
@@ -819,7 +817,6 @@ test {
// TODO(weiminyu): Remove dependency on sqlIntegrationTest
}.dependsOn(fragileTest, standardTest, registryToolIntegrationTest, sqlIntegrationTest)
// When we override tests, we also break the cleanTest command.
cleanTest.dependsOn(cleanFragileTest, cleanStandardTest,
cleanRegistryToolIntegrationTest, cleanSqlIntegrationTest)
+30 -30
View File
@@ -321,26 +321,26 @@ io.opentelemetry.instrumentation:opentelemetry-instrumentation-api-incubator:2.1
io.opentelemetry.instrumentation:opentelemetry-instrumentation-api:2.1.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
io.opentelemetry.semconv:opentelemetry-semconv:1.29.0-alpha=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
io.opentelemetry:opentelemetry-api:1.51.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath
io.opentelemetry:opentelemetry-api:1.60.1=testCompileClasspath,testRuntimeClasspath
io.opentelemetry:opentelemetry-api:1.62.0=testCompileClasspath,testRuntimeClasspath
io.opentelemetry:opentelemetry-bom:1.42.1=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
io.opentelemetry:opentelemetry-common:1.60.1=testCompileClasspath,testRuntimeClasspath
io.opentelemetry:opentelemetry-common:1.62.0=testCompileClasspath,testRuntimeClasspath
io.opentelemetry:opentelemetry-context:1.51.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath
io.opentelemetry:opentelemetry-context:1.60.1=testCompileClasspath,testRuntimeClasspath
io.opentelemetry:opentelemetry-exporter-logging:1.60.1=testCompileClasspath,testRuntimeClasspath
io.opentelemetry:opentelemetry-context:1.62.0=testCompileClasspath,testRuntimeClasspath
io.opentelemetry:opentelemetry-exporter-logging:1.62.0=testCompileClasspath,testRuntimeClasspath
io.opentelemetry:opentelemetry-extension-incubator:1.35.0-alpha=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
io.opentelemetry:opentelemetry-sdk-common:1.51.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath
io.opentelemetry:opentelemetry-sdk-common:1.60.1=testCompileClasspath,testRuntimeClasspath
io.opentelemetry:opentelemetry-sdk-common:1.62.0=testCompileClasspath,testRuntimeClasspath
io.opentelemetry:opentelemetry-sdk-extension-autoconfigure-spi:1.47.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath
io.opentelemetry:opentelemetry-sdk-extension-autoconfigure-spi:1.60.1=testCompileClasspath,testRuntimeClasspath
io.opentelemetry:opentelemetry-sdk-extension-autoconfigure:1.60.1=testCompileClasspath,testRuntimeClasspath
io.opentelemetry:opentelemetry-sdk-extension-autoconfigure-spi:1.62.0=testCompileClasspath,testRuntimeClasspath
io.opentelemetry:opentelemetry-sdk-extension-autoconfigure:1.62.0=testCompileClasspath,testRuntimeClasspath
io.opentelemetry:opentelemetry-sdk-logs:1.51.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath
io.opentelemetry:opentelemetry-sdk-logs:1.60.1=testCompileClasspath,testRuntimeClasspath
io.opentelemetry:opentelemetry-sdk-logs:1.62.0=testCompileClasspath,testRuntimeClasspath
io.opentelemetry:opentelemetry-sdk-metrics:1.51.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath
io.opentelemetry:opentelemetry-sdk-metrics:1.60.1=testCompileClasspath,testRuntimeClasspath
io.opentelemetry:opentelemetry-sdk-metrics:1.62.0=testCompileClasspath,testRuntimeClasspath
io.opentelemetry:opentelemetry-sdk-trace:1.51.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath
io.opentelemetry:opentelemetry-sdk-trace:1.60.1=testCompileClasspath,testRuntimeClasspath
io.opentelemetry:opentelemetry-sdk-trace:1.62.0=testCompileClasspath,testRuntimeClasspath
io.opentelemetry:opentelemetry-sdk:1.51.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath
io.opentelemetry:opentelemetry-sdk:1.60.1=testCompileClasspath,testRuntimeClasspath
io.opentelemetry:opentelemetry-sdk:1.62.0=testCompileClasspath,testRuntimeClasspath
io.outfoxx:swiftpoet:1.3.1=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
io.perfmark:perfmark-api:0.27.0=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
io.protostuff:protostuff-api:1.8.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
@@ -465,8 +465,8 @@ org.eclipse.jetty:jetty-server:12.1.9=testCompileClasspath,testRuntimeClasspath
org.eclipse.jetty:jetty-session:12.1.9=testCompileClasspath,testRuntimeClasspath
org.eclipse.jetty:jetty-util:12.1.9=testCompileClasspath,testRuntimeClasspath
org.eclipse.jetty:jetty-xml:12.1.9=testCompileClasspath,testRuntimeClasspath
org.flywaydb:flyway-core:12.6.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.flywaydb:flyway-database-postgresql:12.6.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.flywaydb:flyway-core:12.6.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.flywaydb:flyway-database-postgresql:12.6.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.glassfish.jaxb:codemodel:4.0.8=jaxb
org.glassfish.jaxb:jaxb-core:4.0.6=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
org.glassfish.jaxb:jaxb-core:4.0.8=jaxb
@@ -553,23 +553,23 @@ org.pcollections:pcollections:4.0.1=annotationProcessor,nonprodAnnotationProcess
org.postgresql:postgresql:42.7.11=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.reflections:reflections:0.10.2=checkstyle
org.rnorth.duct-tape:duct-tape:1.0.8=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.seleniumhq.selenium:selenium-api:4.43.0=testCompileClasspath,testRuntimeClasspath
org.seleniumhq.selenium:selenium-chrome-driver:4.43.0=testCompileClasspath,testRuntimeClasspath
org.seleniumhq.selenium:selenium-chromium-driver:4.43.0=testCompileClasspath,testRuntimeClasspath
org.seleniumhq.selenium:selenium-devtools-v145:4.43.0=testCompileClasspath,testRuntimeClasspath
org.seleniumhq.selenium:selenium-devtools-v146:4.43.0=testCompileClasspath,testRuntimeClasspath
org.seleniumhq.selenium:selenium-devtools-v147:4.43.0=testCompileClasspath,testRuntimeClasspath
org.seleniumhq.selenium:selenium-edge-driver:4.43.0=testCompileClasspath,testRuntimeClasspath
org.seleniumhq.selenium:selenium-firefox-driver:4.43.0=testCompileClasspath,testRuntimeClasspath
org.seleniumhq.selenium:selenium-http:4.43.0=testCompileClasspath,testRuntimeClasspath
org.seleniumhq.selenium:selenium-ie-driver:4.43.0=testCompileClasspath,testRuntimeClasspath
org.seleniumhq.selenium:selenium-java:4.43.0=testCompileClasspath,testRuntimeClasspath
org.seleniumhq.selenium:selenium-json:4.43.0=testCompileClasspath,testRuntimeClasspath
org.seleniumhq.selenium:selenium-manager:4.43.0=testCompileClasspath,testRuntimeClasspath
org.seleniumhq.selenium:selenium-os:4.43.0=testCompileClasspath,testRuntimeClasspath
org.seleniumhq.selenium:selenium-remote-driver:4.43.0=testCompileClasspath,testRuntimeClasspath
org.seleniumhq.selenium:selenium-safari-driver:4.43.0=testCompileClasspath,testRuntimeClasspath
org.seleniumhq.selenium:selenium-support:4.43.0=testCompileClasspath,testRuntimeClasspath
org.seleniumhq.selenium:selenium-api:4.44.0=testCompileClasspath,testRuntimeClasspath
org.seleniumhq.selenium:selenium-chrome-driver:4.44.0=testCompileClasspath,testRuntimeClasspath
org.seleniumhq.selenium:selenium-chromium-driver:4.44.0=testCompileClasspath,testRuntimeClasspath
org.seleniumhq.selenium:selenium-devtools-v146:4.44.0=testCompileClasspath,testRuntimeClasspath
org.seleniumhq.selenium:selenium-devtools-v147:4.44.0=testCompileClasspath,testRuntimeClasspath
org.seleniumhq.selenium:selenium-devtools-v148:4.44.0=testCompileClasspath,testRuntimeClasspath
org.seleniumhq.selenium:selenium-edge-driver:4.44.0=testCompileClasspath,testRuntimeClasspath
org.seleniumhq.selenium:selenium-firefox-driver:4.44.0=testCompileClasspath,testRuntimeClasspath
org.seleniumhq.selenium:selenium-http:4.44.0=testCompileClasspath,testRuntimeClasspath
org.seleniumhq.selenium:selenium-ie-driver:4.44.0=testCompileClasspath,testRuntimeClasspath
org.seleniumhq.selenium:selenium-java:4.44.0=testCompileClasspath,testRuntimeClasspath
org.seleniumhq.selenium:selenium-json:4.44.0=testCompileClasspath,testRuntimeClasspath
org.seleniumhq.selenium:selenium-manager:4.44.0=testCompileClasspath,testRuntimeClasspath
org.seleniumhq.selenium:selenium-os:4.44.0=testCompileClasspath,testRuntimeClasspath
org.seleniumhq.selenium:selenium-remote-driver:4.44.0=testCompileClasspath,testRuntimeClasspath
org.seleniumhq.selenium:selenium-safari-driver:4.44.0=testCompileClasspath,testRuntimeClasspath
org.seleniumhq.selenium:selenium-support:4.44.0=testCompileClasspath,testRuntimeClasspath
org.slf4j:jcl-over-slf4j:1.7.36=testCompileClasspath,testRuntimeClasspath
org.slf4j:jul-to-slf4j:1.7.30=testRuntimeClasspath
org.slf4j:slf4j-api:2.0.17=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
@@ -92,7 +92,7 @@ public class DeleteProberDataAction implements Runnable {
// prevents accidental double-map with the same key from immediately deleting active domains)
//
// Note: creationTime must be compared to a Java object (CreateAutoTimestamp) but deletionTime can
// be compared directly to the SQL timestamp (it's a DateTime)
// be compared directly to the SQL timestamp (it's an Instant)
private static final String DOMAIN_QUERY_STRING =
"FROM Domain d WHERE d.tld IN :tlds AND d.domainName NOT LIKE 'nic.%%' AND"
+ " (d.subordinateHosts IS NULL OR array_length(d.subordinateHosts) = 0) AND"
@@ -39,8 +39,8 @@ import org.jetbrains.annotations.NotNull;
* A record representing a single billable event, parsed from a {@code SchemaAndRecord}.
*
* @param id The unique ID for the {@code BillingEvent} associated with this event.
* @param billingTime The DateTime (in UTC) this event becomes billable.
* @param eventTime The DateTime (in UTC) this event was generated.
* @param billingTime The Instant (in UTC) this event becomes billable.
* @param eventTime The Instant (in UTC) this event was generated.
* @param registrarId The billed registrar's name.
* @param billingId The billed registrar's billing account key.
* @param poNumber The Purchase Order number.
@@ -225,7 +225,6 @@ public record BillingEvent(
"UnitPriceCurrency",
"PONumber");
/** Generates the CSV header for the overall invoice. */
static String invoiceHeader() {
return Joiner.on(",").join(INVOICE_HEADERS);
@@ -22,12 +22,10 @@ import jakarta.persistence.Query;
import jakarta.persistence.TypedQuery;
import jakarta.persistence.criteria.CriteriaQuery;
import java.io.Serializable;
import java.time.Instant;
import java.util.Map;
import java.util.function.Supplier;
import java.util.stream.Stream;
import javax.annotation.Nullable;
import org.joda.time.DateTime;
/** Interface for query instances used by {@link RegistryJpaIO.Read}. */
public interface RegistryQuery<T> extends Serializable {
@@ -61,11 +59,7 @@ public interface RegistryQuery<T> extends Serializable {
if (parameters != null) {
parameters.forEach(
(key, value) -> {
if (value instanceof DateTime dt) {
query.setParameter(key, Instant.ofEpochMilli(dt.getMillis()));
} else {
query.setParameter(key, value);
}
query.setParameter(key, value);
});
}
JpaTransactionManager.setQueryFetchSize(query, QUERY_FETCH_SIZE);
@@ -14,7 +14,6 @@
package google.registry.beam.spec11;
import static google.registry.util.DateTimeUtils.toJodaInstant;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.apache.http.HttpStatus.SC_OK;
@@ -132,7 +131,13 @@ public class SafeBrowsingTransforms {
if (!domainNameInfoBuffer.isEmpty()) {
ImmutableSet<KV<DomainNameInfo, ThreatMatch>> results = evaluateAndFlush();
results.forEach(
(kv) -> context.output(kv, toJodaInstant(clock.now()), GlobalWindow.INSTANCE));
kv -> {
// The Apache Beam API requires org.joda.time.Instant here.
@SuppressWarnings("UnnecessarilyFullyQualified")
org.joda.time.Instant timestamp =
org.joda.time.Instant.ofEpochMilli(clock.nowMillis());
context.output(kv, timestamp, GlobalWindow.INSTANCE);
});
}
}
@@ -114,11 +114,7 @@ public final class DownloadScheduler {
}
private boolean isTimeAgain(BsaDownload mostRecent, Duration interval) {
return mostRecent
.getCreationTime()
.plusMillis(interval.toMillis())
.minusMillis(CRON_JITTER.toMillis())
.isBefore(clock.now());
return mostRecent.getCreationTime().plus(interval).minus(CRON_JITTER).isBefore(clock.now());
}
/**
@@ -155,7 +155,7 @@ public class DelegatedCredentials extends GoogleCredentials {
@Override
public AccessToken refreshAccessToken() throws IOException {
JsonFactory jsonFactory = JSON_FACTORY;
long currentTime = clock.now().toEpochMilli();
long currentTime = clock.nowMillis();
String assertion = createAssertion(jsonFactory, currentTime);
GenericData tokenRequest = new GenericData();
@@ -50,6 +50,7 @@ import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.net.URI;
import java.net.URL;
import java.time.DayOfWeek;
import java.time.Duration;
import java.time.Instant;
import java.util.Map.Entry;
@@ -57,7 +58,6 @@ import java.util.Optional;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import javax.annotation.Nullable;
import org.joda.time.DateTimeConstants;
/**
* Central clearing-house for all configuration.
@@ -271,7 +271,7 @@ public final class RegistryConfig {
@Provides
@Config("brdaDayOfWeek")
public static int provideBrdaDayOfWeek() {
return DateTimeConstants.TUESDAY;
return DayOfWeek.TUESDAY.getValue();
}
/**
@@ -1637,7 +1637,6 @@ public final class RegistryConfig {
return CONFIG_SETTINGS.get().registryPolicy.contactAndHostRoidSuffix;
}
/** A discount for all sunrise domain creates, between 0.0 (no discount) and 1.0 (free). */
public static double getSunriseDomainCreateDiscount() {
return CONFIG_SETTINGS.get().registryPolicy.sunriseDomainCreateDiscount;
@@ -71,7 +71,6 @@
<max-backoff>180s</max-backoff>
</queue>
<!-- Queue for tasks that communicate with TMCH MarksDB webserver. -->
<queue>
<name>marksdb</name>
@@ -49,4 +49,3 @@ public class EppTlsAction implements Runnable {
inputXmlBytes);
}
}
@@ -71,6 +71,4 @@ public class StatelessRequestSessionMetadata extends SessionMetadata {
throw new UnsupportedOperationException();
}
}
@@ -14,7 +14,6 @@
package google.registry.flows.contact;
import google.registry.flows.annotations.ReportingSpec;
import google.registry.flows.exceptions.ContactsProhibitedException;
import google.registry.model.reporting.IcannReportingTypes.ActivityReportField;
@@ -14,7 +14,6 @@
package google.registry.flows.contact;
import google.registry.flows.annotations.ReportingSpec;
import google.registry.flows.exceptions.ContactsProhibitedException;
import google.registry.model.reporting.IcannReportingTypes.ActivityReportField;
@@ -14,7 +14,6 @@
package google.registry.flows.contact;
import google.registry.flows.annotations.ReportingSpec;
import google.registry.flows.exceptions.ContactsProhibitedException;
import google.registry.model.reporting.IcannReportingTypes.ActivityReportField;
@@ -14,7 +14,6 @@
package google.registry.flows.contact;
import google.registry.flows.annotations.ReportingSpec;
import google.registry.flows.exceptions.ContactsProhibitedException;
import google.registry.model.reporting.IcannReportingTypes.ActivityReportField;
@@ -14,7 +14,6 @@
package google.registry.flows.contact;
import google.registry.flows.annotations.ReportingSpec;
import google.registry.flows.exceptions.ContactsProhibitedException;
import google.registry.model.reporting.IcannReportingTypes.ActivityReportField;
@@ -14,7 +14,6 @@
package google.registry.flows.contact;
import google.registry.flows.annotations.ReportingSpec;
import google.registry.flows.exceptions.ContactsProhibitedException;
import google.registry.model.reporting.IcannReportingTypes.ActivityReportField;
@@ -14,7 +14,6 @@
package google.registry.flows.contact;
import google.registry.flows.annotations.ReportingSpec;
import google.registry.flows.exceptions.ContactsProhibitedException;
import google.registry.model.reporting.IcannReportingTypes.ActivityReportField;
@@ -14,7 +14,6 @@
package google.registry.flows.contact;
import google.registry.flows.annotations.ReportingSpec;
import google.registry.flows.exceptions.ContactsProhibitedException;
import google.registry.model.reporting.IcannReportingTypes.ActivityReportField;
@@ -14,7 +14,6 @@
package google.registry.flows.contact;
import google.registry.flows.annotations.ReportingSpec;
import google.registry.flows.exceptions.ContactsProhibitedException;
import google.registry.model.reporting.IcannReportingTypes.ActivityReportField;
@@ -14,7 +14,6 @@
package google.registry.flows.contact;
import google.registry.flows.annotations.ReportingSpec;
import google.registry.flows.exceptions.ContactsProhibitedException;
import google.registry.model.reporting.IcannReportingTypes.ActivityReportField;
@@ -41,7 +41,6 @@ import org.bouncycastle.openpgp.operator.jcajce.JcaPGPDigestCalculatorProviderBu
*/
public final class KeySerializer {
private KeySerializer() {}
/**
@@ -21,7 +21,6 @@ import dagger.Module;
import dagger.Provides;
import google.registry.request.Parameter;
import jakarta.servlet.http.HttpServletRequest;
import org.joda.time.Minutes;
/**
* Dagger module for loadtest package.
@@ -42,15 +41,13 @@ public final class LoadTestModule {
@Provides
@Parameter("delaySeconds")
static int provideDelaySeconds(HttpServletRequest req) {
return extractOptionalIntParameter(req, "delaySeconds")
.orElse(Minutes.ONE.toStandardSeconds().getSeconds());
return extractOptionalIntParameter(req, "delaySeconds").orElse(60);
}
@Provides
@Parameter("runSeconds")
static int provideRunSeconds(HttpServletRequest req) {
return extractOptionalIntParameter(req, "runSeconds")
.orElse(Minutes.ONE.toStandardSeconds().getSeconds());
return extractOptionalIntParameter(req, "runSeconds").orElse(60);
}
@Provides
@@ -90,9 +90,9 @@ public class Cursor extends UpdateAutoTimestampEntity {
RECURRING_BILLING(false),
/**
* Cursor for {@link google.registry.export.sheet.SyncRegistrarsSheetAction}. The DateTime
* stored is the last time that registrar changes were successfully synced to the sheet. If
* there were no changes since the last time the action run, the cursor is not updated.
* Cursor for {@link google.registry.export.sheet.SyncRegistrarsSheetAction}. The Instant stored
* is the last time that registrar changes were successfully synced to the sheet. If there were
* no changes since the last time the action run, the cursor is not updated.
*/
SYNC_REGISTRAR_SHEET(false),
@@ -33,7 +33,7 @@ import jakarta.persistence.Embeddable;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.ZonedDateTime;
import java.time.OffsetDateTime;
import java.util.List;
/**
@@ -63,7 +63,7 @@ public class TimeOfYear extends ImmutableObject implements UnsafeSerializable {
* February 28. It is impossible to construct a {@link TimeOfYear} for February 29th.
*/
public static TimeOfYear fromInstant(Instant instant) {
ZonedDateTime zdt = ZonedDateTime.ofInstant(instant, UTC);
OffsetDateTime zdt = OffsetDateTime.ofInstant(instant, UTC);
int month = zdt.getMonthValue();
int day = zdt.getDayOfMonth();
if (month == 2 && day == 29) {
@@ -88,8 +88,8 @@ public class TimeOfYear extends ImmutableObject implements UnsafeSerializable {
Range<Instant> normalizedRange = range.intersection(Range.closed(START_INSTANT, END_INSTANT));
Range<Integer> yearRange =
Range.closed(
ZonedDateTime.ofInstant(normalizedRange.lowerEndpoint(), UTC).getYear(),
ZonedDateTime.ofInstant(normalizedRange.upperEndpoint(), UTC).getYear());
OffsetDateTime.ofInstant(normalizedRange.lowerEndpoint(), UTC).getYear(),
OffsetDateTime.ofInstant(normalizedRange.upperEndpoint(), UTC).getYear());
return ContiguousSet.create(yearRange, integers()).stream()
.map(this::toInstantWithYear)
.filter(normalizedRange)
@@ -112,13 +112,13 @@ public class TimeOfYear extends ImmutableObject implements UnsafeSerializable {
/** Get the first {@link Instant} with this month/day/millis that is at or after the start. */
public Instant getNextInstanceAtOrAfter(Instant start) {
Instant withSameYear = toInstantWithYear(ZonedDateTime.ofInstant(start, UTC).getYear());
Instant withSameYear = toInstantWithYear(OffsetDateTime.ofInstant(start, UTC).getYear());
return isAtOrAfter(withSameYear, start) ? withSameYear : plusYears(withSameYear, 1);
}
/** Get the first {@link Instant} with this month/day/millis that is at or before the end. */
public Instant getLastInstanceBeforeOrAt(Instant end) {
Instant withSameYear = toInstantWithYear(ZonedDateTime.ofInstant(end, UTC).getYear());
Instant withSameYear = toInstantWithYear(OffsetDateTime.ofInstant(end, UTC).getYear());
return isBeforeOrAt(withSameYear, end) ? withSameYear : minusYears(withSameYear, 1);
}
@@ -17,9 +17,7 @@
xmlns = @XmlNs(prefix = "contact", namespaceURI = "urn:ietf:params:xml:ns:contact-1.0"),
elementFormDefault = XmlNsForm.QUALIFIED)
@XmlAccessorType(XmlAccessType.FIELD)
@XmlJavaTypeAdapters({
@XmlJavaTypeAdapter(UtcInstantAdapter.class)
})
@XmlJavaTypeAdapters({@XmlJavaTypeAdapter(UtcInstantAdapter.class)})
package google.registry.model.contact;
import google.registry.xml.UtcInstantAdapter;
@@ -14,7 +14,6 @@
package google.registry.model.domain;
import google.registry.model.EppResource;
import google.registry.model.EppResource.ForeignKeyedEppResource;
import google.registry.model.annotations.ExternalMessagingName;
@@ -246,7 +246,7 @@ public class DomainBase extends EppResource {
*
* <p>When a domain is scheduled to not autorenew, this field is set to the current value of its
* {@link #registrationExpirationTime}, after which point the next invocation of a periodic
* cronjob will explicitly delete the domain. This field is a DateTime and not a boolean because
* cronjob will explicitly delete the domain. This field is an Instant and not a boolean because
* of edge cases that occur during the autorenew grace period. We need to be able to tell the
* difference domains that have reached their life and must be deleted now, and domains that
* happen to be in the autorenew grace period now but should be deleted in roughly a year.
@@ -14,7 +14,6 @@
package google.registry.model.domain;
import google.registry.model.eppoutput.EppResponse.ResponseData;
import google.registry.xml.UtcInstantAdapter;
import jakarta.xml.bind.annotation.XmlElement;
@@ -14,7 +14,6 @@
package google.registry.model.domain;
import google.registry.model.ImmutableObject;
import google.registry.model.UnsafeSerializable;
import google.registry.model.billing.BillingEvent;
@@ -31,8 +31,8 @@ import jakarta.xml.bind.annotation.XmlValue;
import jakarta.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import java.math.BigDecimal;
import java.time.Instant;
import java.time.Period;
import java.util.stream.Stream;
import org.joda.time.Period;
/** Base class for the fee and credit types. */
@XmlTransient
@@ -34,4 +34,3 @@ public abstract class FeeCheckResponseExtensionItem extends FeeQueryResponseExte
}
}
}
@@ -69,4 +69,3 @@ public class FeeInfoCommandExtensionV06
return Optional.empty();
}
}
@@ -36,7 +36,6 @@ public class FeeInfoResponseExtensionV06
/** The command that was checked. */
FeeExtensionCommandDescriptor command;
/** Builder for {@link FeeInfoResponseExtensionV06}. */
public static class Builder
extends FeeQueryResponseExtensionItem.Builder<FeeInfoResponseExtensionV06, Builder> {
@@ -34,7 +34,6 @@ public class FeeCheckResponseExtensionV11
@XmlElement(name = "cd")
ImmutableList<FeeCheckResponseExtensionItemV11> items;
@Override
public void setCurrencyIfSupported(CurrencyUnit currency) {}
@@ -17,9 +17,7 @@
xmlns = @XmlNs(prefix = "launch", namespaceURI = "urn:ietf:params:xml:ns:launch-1.0"),
elementFormDefault = XmlNsForm.QUALIFIED)
@XmlAccessorType(XmlAccessType.FIELD)
@XmlJavaTypeAdapters({
@XmlJavaTypeAdapter(UtcInstantAdapter.class)
})
@XmlJavaTypeAdapters({@XmlJavaTypeAdapter(UtcInstantAdapter.class)})
package google.registry.model.domain.launch;
import google.registry.xml.UtcInstantAdapter;
@@ -335,8 +335,6 @@ public class AllocationToken extends UpdateAutoTimestampEntity implements Builda
return tokenType;
}
@JsonIgnore
public TimedTransitionProperty<TokenStatus> getTokenStatusTransitions() {
return tokenStatusTransitions;
@@ -17,9 +17,7 @@
xmlns = @XmlNs(prefix = "", namespaceURI = "urn:ietf:params:xml:ns:epp-1.0"),
elementFormDefault = XmlNsForm.QUALIFIED)
@XmlAccessorType(XmlAccessType.FIELD)
@XmlJavaTypeAdapters({
@XmlJavaTypeAdapter(UtcInstantAdapter.class)
})
@XmlJavaTypeAdapters({@XmlJavaTypeAdapter(UtcInstantAdapter.class)})
package google.registry.model.eppinput;
import google.registry.xml.UtcInstantAdapter;
@@ -17,9 +17,7 @@
xmlns = @XmlNs(prefix = "", namespaceURI = "urn:ietf:params:xml:ns:epp-1.0"),
elementFormDefault = XmlNsForm.QUALIFIED)
@XmlAccessorType(XmlAccessType.FIELD)
@XmlJavaTypeAdapters({
@XmlJavaTypeAdapter(UtcInstantAdapter.class)
})
@XmlJavaTypeAdapters({@XmlJavaTypeAdapter(UtcInstantAdapter.class)})
package google.registry.model.eppoutput;
import google.registry.xml.UtcInstantAdapter;
@@ -18,7 +18,7 @@ import static java.time.ZoneOffset.UTC;
import com.google.common.base.Splitter;
import google.registry.persistence.VKey;
import java.time.ZonedDateTime;
import java.time.OffsetDateTime;
import java.util.List;
/**
@@ -46,7 +46,7 @@ public final class PollMessageExternalKeyConverter {
public static String makePollMessageExternalId(PollMessage pollMessage) {
return String.format(
"%d-%d",
pollMessage.getId(), ZonedDateTime.ofInstant(pollMessage.getEventTime(), UTC).getYear());
pollMessage.getId(), OffsetDateTime.ofInstant(pollMessage.getEventTime(), UTC).getYear());
}
/**
@@ -17,9 +17,7 @@
xmlns = @XmlNs(prefix = "", namespaceURI = "urn:ietf:params:xml:ns:epp-1.0"),
elementFormDefault = XmlNsForm.QUALIFIED)
@XmlAccessorType(XmlAccessType.FIELD)
@XmlJavaTypeAdapters({
@XmlJavaTypeAdapter(UtcInstantAdapter.class)
})
@XmlJavaTypeAdapters({@XmlJavaTypeAdapter(UtcInstantAdapter.class)})
package google.registry.model.poll;
import google.registry.xml.UtcInstantAdapter;
@@ -14,7 +14,6 @@
package google.registry.model.transfer;
import google.registry.model.Buildable.GenericBuilder;
import google.registry.model.ImmutableObject;
import google.registry.model.UnsafeSerializable;
@@ -14,7 +14,6 @@
package google.registry.model.transfer;
import google.registry.model.EppResource;
import google.registry.model.eppoutput.EppResponse.ResponseData;
import google.registry.xml.UtcInstantAdapter;
@@ -17,9 +17,7 @@
xmlns = @XmlNs(prefix = "", namespaceURI = "urn:ietf:params:xml:ns:epp-1.0"),
elementFormDefault = XmlNsForm.QUALIFIED)
@XmlAccessorType(XmlAccessType.FIELD)
@XmlJavaTypeAdapters({
@XmlJavaTypeAdapter(UtcInstantAdapter.class)
})
@XmlJavaTypeAdapters({@XmlJavaTypeAdapter(UtcInstantAdapter.class)})
package google.registry.model.transfer;
import google.registry.xml.UtcInstantAdapter;
@@ -81,7 +81,6 @@ public record CheckApiMetric(
}
}
public static Builder builder(Clock clock) {
return new AutoBuilder_CheckApiMetric_Builder().startTimestamp(clock.now()).setClock(clock);
}
@@ -1,43 +0,0 @@
// Copyright 2019 The Nomulus Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package google.registry.persistence.converter;
import static org.joda.time.DateTimeZone.UTC;
import jakarta.persistence.AttributeConverter;
import jakarta.persistence.Converter;
import java.time.Instant;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import javax.annotation.Nullable;
import org.joda.time.DateTime;
/** JPA converter to for storing/retrieving {@link org.joda.time.DateTime} objects. */
@Converter(autoApply = true)
public class DateTimeConverter implements AttributeConverter<DateTime, ZonedDateTime> {
@Override
@Nullable
public ZonedDateTime convertToDatabaseColumn(@Nullable DateTime attribute) {
return attribute == null
? null
: ZonedDateTime.ofInstant(Instant.ofEpochMilli(attribute.getMillis()), ZoneOffset.UTC);
}
@Override
@Nullable
public DateTime convertToEntityAttribute(@Nullable ZonedDateTime dbData) {
return (dbData == null) ? null : new DateTime(dbData.toInstant().toEpochMilli(), UTC);
}
}
@@ -14,7 +14,6 @@
package google.registry.persistence.converter;
import java.io.Serializable;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
@@ -14,7 +14,6 @@
package google.registry.privileges.secretmanager;
import com.google.cloud.secretmanager.v1.SecretManagerServiceClient;
import com.google.cloud.secretmanager.v1.SecretManagerServiceSettings;
import dagger.Module;
@@ -40,7 +40,6 @@ import java.util.HashSet;
import java.util.Map;
import java.util.Optional;
import javax.annotation.Nullable;
import org.joda.time.DateTime;
/**
* An Jsonable that can turn itself into a JSON object using reflection.
@@ -53,16 +52,12 @@ import org.joda.time.DateTime;
* will be "JSONified" and added to the generated JSON object.
*
* <p>This implementation is geared towards RDAP replies, and hence has RDAP-specific quirks.
* Specifically:
* - Fields with empty arrays are not shown at all
* - VCards are a built-in special case (Not implemented yet)
* - DateTime conversion is specifically supported as if it were a primitive
* - Arrays are considered to be SETS rather than lists, meaning repeated values are removed and the
* order isn't guaranteed
* Specifically: - Fields with empty arrays are not shown at all - VCards are a built-in special
* case (Not implemented yet) - Instant conversion is specifically supported as if it were a
* primitive - Arrays are considered to be SETS rather than lists, meaning repeated values are
* removed and the order isn't guaranteed
*
* Usage:
* {@link JsonableElement}
* -----------------------
* <p>Usage: {@link JsonableElement} -----------------------
*
* <pre>
* - JsonableElement annotates Members that become JSON object fields:
@@ -90,7 +85,7 @@ import org.joda.time.DateTime;
* "b": "value1"
* }
*
* - the supported object types are String, Boolean, Number, DateTime, Jsonable. In addition,
* - the supported object types are String, Boolean, Number, Instant, Jsonable. In addition,
* Iterable and Optional are respected.
*
* - An Optional that's empty is skipped, while a present Optional acts exactly like the object it
@@ -134,8 +129,7 @@ import org.joda.time.DateTime;
* }
* </pre>
*
* {@link RestrictJsonNames}
* -------------------------
* {@link RestrictJsonNames} -------------------------
*
* <pre>
* - RestrictJsonNames is a way to prevent typos in the JsonableElement names.
@@ -334,12 +328,6 @@ abstract class AbstractJsonableObject implements Jsonable {
if (object instanceof Boolean b) {
return new JsonPrimitive(b);
}
if (object instanceof DateTime) {
// According to RFC 9083 section 3, the syntax of dates and times is defined in RFC3339.
//
// According to RFC3339, we should use ISO8601, which is what DateTime.toString does!
return new JsonPrimitive(object.toString());
}
if (object instanceof Instant instant) {
// According to RFC 9083 section 3, the syntax of dates and times is defined in RFC3339.
//
@@ -244,7 +244,6 @@ final class RdapDataStructures {
@JsonableElement abstract ImmutableList<Link> links();
abstract static class Builder<B extends Builder<?>> {
abstract B setEventAction(EventAction eventAction);
@@ -304,7 +303,6 @@ final class RdapDataStructures {
return new AutoValue_RdapDataStructures_EventWithoutActor.Builder();
}
@AutoValue.Builder
abstract static class Builder extends EventBase.Builder<Builder> {
abstract EventWithoutActor build();
@@ -321,7 +319,6 @@ final class RdapDataStructures {
return new AutoValue_RdapDataStructures_Event.Builder();
}
@AutoValue.Builder
abstract static class Builder extends EventBase.Builder<Builder> {
abstract Builder setEventActor(String eventActor);
@@ -272,7 +272,6 @@ public class RdapMetrics {
RdapMetricInformation build();
}
static Builder builder() {
return new AutoBuilder_RdapMetrics_RdapMetricInformation_Builder()
.setSearchType(SearchType.NONE)
@@ -235,7 +235,6 @@ final class RdapObjectClasses {
this.objectClassName = objectClassName;
}
abstract static class Builder<B extends Builder<?>> {
abstract B setHandle(String handle);
abstract ImmutableList.Builder<PublicId> publicIdsBuilder();
@@ -14,7 +14,6 @@
package google.registry.rdap;
import com.google.common.base.Strings;
import google.registry.request.HttpException.BadRequestException;
import google.registry.request.HttpException.UnprocessableEntityException;
@@ -14,7 +14,6 @@
package google.registry.rde;
import static google.registry.model.common.Cursor.CursorType.BRDA;
import static google.registry.model.common.Cursor.getCursorTimeOrStartOfTime;
import static google.registry.model.rde.RdeMode.THIN;
@@ -14,7 +14,6 @@
package google.registry.rde;
import google.registry.model.common.Cursor.CursorType;
import google.registry.model.rde.RdeMode;
import java.io.IOException;
@@ -14,7 +14,6 @@
package google.registry.rde;
import static com.google.common.base.Verify.verify;
import static com.google.common.net.MediaType.PLAIN_TEXT_UTF_8;
import static google.registry.model.common.Cursor.getCursorTimeOrStartOfTime;
@@ -14,7 +14,6 @@
package google.registry.rde;
import static com.google.common.base.Verify.verify;
import static com.google.common.net.MediaType.PLAIN_TEXT_UTF_8;
import static com.jcraft.jsch.ChannelSftp.OVERWRITE;
@@ -16,8 +16,6 @@ package google.registry.rde;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkState;
import static google.registry.util.DateTimeUtils.toDateTime;
import static google.registry.util.DateTimeUtils.toInstant;
import com.google.common.io.ByteStreams;
import google.registry.util.ImprovedInputStream;
@@ -53,7 +51,7 @@ final class RydeTar {
new PosixTarHeader.Builder()
.setName(filename)
.setSize(expectedSize)
.setMtime(toDateTime(modified))
.setMtime(modified)
.build()
.getBytes());
return new ImprovedOutputStream("RydeTarWriter", os) {
@@ -96,7 +94,7 @@ final class RydeTar {
/** Returns the creation/modification time of the file archived in this TAR. */
Instant getModified() {
return toInstant(header.getMtime());
return header.getMtime();
}
}
@@ -17,7 +17,6 @@ package google.registry.reporting;
import static google.registry.request.RequestParameters.extractOptionalBooleanParameter;
import static google.registry.request.RequestParameters.extractOptionalParameter;
import static google.registry.request.RequestParameters.extractRequiredParameter;
import static java.time.ZoneOffset.UTC;
import com.google.api.services.dataflow.Dataflow;
import dagger.Module;
@@ -129,7 +128,7 @@ public class ReportingModule {
@Provides
@Parameter(PARAM_DATE)
static LocalDate provideDate(HttpServletRequest req, Clock clock) {
return provideDateOptional(req).orElseGet(() -> LocalDate.ofInstant(clock.now(), UTC));
return provideDateOptional(req).orElseGet(() -> clock.nowDate());
}
/** Constructs a {@link Dataflow} API client with default settings. */
@@ -37,7 +37,6 @@ public final class BillingModule {
static final String PARAM_SHOULD_PUBLISH = "shouldPublish";
static final String CRON_QUEUE = "retryable-cron-tasks";
@Provides
@Parameter(PARAM_SHOULD_PUBLISH)
static boolean provideShouldPublish(
@@ -100,7 +100,7 @@ public final class IcannReportingUploadAction implements Runnable {
IcannReportingUploadAction() {}
/**
* Get the scheduled time for the next month of the given {@link DateTime}.
* Get the scheduled time for the next month of the given {@link Instant}.
*
* <p>The scheduled time is always the second day of next month at 10AM UTC. This is because the
* staging action is scheduled to run at 9AM UTC on that day, and there is no reason to run the
@@ -14,7 +14,6 @@
package google.registry.request;
import google.registry.config.RegistryConfig;
import google.registry.request.auth.Auth;
import java.lang.annotation.ElementType;
@@ -30,7 +30,6 @@ import java.time.Instant;
import java.time.format.DateTimeParseException;
import java.util.Optional;
import javax.annotation.Nullable;
import org.joda.time.DateTime;
/** Utilities for extracting parameters from HTTP requests. */
public final class RequestParameters {
@@ -298,33 +297,6 @@ public final class RequestParameters {
* @throws BadRequestException if request parameter named {@code name} is absent, empty, or could
* not be parsed as an ISO 8601 timestamp
*/
public static DateTime extractRequiredDatetimeParameter(HttpServletRequest req, String name) {
String stringValue = extractRequiredParameter(req, name);
try {
return DateTime.parse(stringValue);
} catch (IllegalArgumentException e) {
throw new BadRequestException("Bad ISO 8601 timestamp: " + name);
}
}
/**
* Returns first request parameter associated with {@code name} parsed as an <a
* href="https://goo.gl/pk5Q2k">ISO 8601</a> timestamp, e.g. {@code 1984-12-18TZ}, {@code
* 2000-01-01T16:20:00Z}.
*
* @throws BadRequestException if request parameter is present but not a valid {@link DateTime}.
*/
public static Optional<DateTime> extractOptionalDatetimeParameter(
HttpServletRequest req, String name) {
String stringParam = req.getParameter(name);
try {
return isNullOrEmpty(stringParam)
? Optional.empty()
: Optional.of(DateTime.parse(stringParam));
} catch (IllegalArgumentException e) {
throw new BadRequestException("Bad ISO 8601 timestamp: " + name);
}
}
public static ImmutableSet<Instant> extractSetOfInstantParameters(
HttpServletRequest req, String name) {
@@ -338,26 +310,6 @@ public final class RequestParameters {
}
}
/**
* Returns all GET or POST date parameters associated with {@code name}, or an empty set if none.
*
* <p>Dates are parsed as an <a href="https://goo.gl/pk5Q2k">ISO 8601</a> timestamp, e.g. {@code
* 1984-12-18TZ}, {@code 2000-01-01T16:20:00Z}.
*
* @throws BadRequestException if one of the parameter values is not a valid {@link DateTime}.
*/
public static ImmutableSet<DateTime> extractSetOfDatetimeParameters(
HttpServletRequest req, String name) {
try {
return extractSetOfParameters(req, name).stream()
.filter(not(String::isEmpty))
.map(DateTime::parse)
.collect(toImmutableSet());
} catch (IllegalArgumentException e) {
throw new BadRequestException("Bad ISO 8601 timestamp: " + name);
}
}
private static boolean equalsFalse(@Nullable String value) {
return nullToEmpty(value).equalsIgnoreCase("false");
}
@@ -56,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.now().toEpochMilli();
long timestampMillis = clock.nowMillis();
return encodeToken(ServerSecret.get().asBytes(), email, timestampMillis);
}
@@ -16,20 +16,18 @@ package google.registry.tools;
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.beust.jcommander.Parameter;
import google.registry.model.domain.token.AllocationToken;
import google.registry.model.domain.token.AllocationToken.TokenType;
import google.registry.model.domain.token.BulkPricingPackage;
import google.registry.persistence.VKey;
import google.registry.tools.params.DateTimeParameter;
import google.registry.tools.params.InstantParameter;
import java.time.Instant;
import java.util.List;
import java.util.Optional;
import javax.annotation.Nullable;
import org.joda.money.Money;
import org.joda.time.DateTime;
/** Shared base class for commands to create or update a {@link BulkPricingPackage} object. */
abstract class CreateOrUpdateBulkPricingPackageCommand extends MutatingCommand {
@@ -58,10 +56,10 @@ abstract class CreateOrUpdateBulkPricingPackageCommand extends MutatingCommand {
@Nullable
@Parameter(
names = "--next_billing_date",
validateWith = DateTimeParameter.class,
validateWith = InstantParameter.class,
description =
"The next date that the bulk pricing package should be billed for its annual fee")
DateTime nextBillingDate;
Instant nextBillingDate;
/** Returns the existing BulkPricingPackage or null if it does not exist. */
@Nullable
@@ -108,8 +106,7 @@ abstract class CreateOrUpdateBulkPricingPackageCommand extends MutatingCommand {
Optional.ofNullable(maxCreates).ifPresent(builder::setMaxCreates);
Optional.ofNullable(price).ifPresent(builder::setBulkPrice);
Optional.ofNullable(nextBillingDate)
.ifPresent(
nextBillingDate -> builder.setNextBillingDate(toInstant(nextBillingDate)));
.ifPresent(nextBillingDate -> builder.setNextBillingDate(nextBillingDate));
if (clearLastNotificationSent()) {
builder.setLastNotificationSent((Instant) null);
}
@@ -88,4 +88,3 @@ public class CreateRegistrarGroupsCommand extends ConfirmingCommand
return "Success!";
}
}
@@ -32,10 +32,12 @@ import com.google.common.collect.ImmutableMultimap;
import google.registry.batch.CloudTasksUtils;
import google.registry.model.rde.RdeMode;
import google.registry.rde.RdeStagingAction;
import google.registry.util.DateTimeUtils;
import jakarta.inject.Inject;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.List;
import java.util.stream.Collectors;
import org.joda.time.DateTime;
/**
* Command to kick off the server-side generation of an XML RDE or BRDA escrow deposit, which will
@@ -54,7 +56,7 @@ final class GenerateEscrowDepositCommand implements Command {
names = {"-w", "--watermark"},
description = "Point-in-time timestamp(s) for which time the deposit should be generated",
required = true)
private List<DateTime> watermarks;
private List<Instant> watermarks;
@Parameter(
names = {"-m", "--mode"},
@@ -88,14 +90,14 @@ final class GenerateEscrowDepositCommand implements Command {
}
// We need to test for cases where "--watermark=" is passed in as a parameter, because it would
// first be converted to an empty list, and as such the DateTime converter would not be called.
// first be converted to an empty list, and as such the Instant converter would not be called.
if (tlds.isEmpty()) {
throw new ParameterException("At least one TLD must be specified");
}
assertTldsExist(tlds);
for (DateTime watermark : watermarks) {
if (!watermark.withTimeAtStartOfDay().equals(watermark)) {
for (Instant watermark : watermarks) {
if (!watermark.truncatedTo(ChronoUnit.DAYS).equals(watermark)) {
throw new ParameterException("Each watermark date must be the start of a day");
}
}
@@ -117,7 +119,9 @@ final class GenerateEscrowDepositCommand implements Command {
.put(PARAM_TLDS, tlds.stream().collect(Collectors.joining(",")))
.put(
PARAM_WATERMARKS,
watermarks.stream().map(DateTime::toString).collect(Collectors.joining(",")));
watermarks.stream()
.map(DateTimeUtils::formatInstant)
.collect(Collectors.joining(",")));
if (revision != null) {
paramsBuilder.put(PARAM_REVISION, String.valueOf(revision));
@@ -126,5 +130,4 @@ final class GenerateEscrowDepositCommand implements Command {
RDE_REPORT_QUEUE,
cloudTasksUtils.createTask(RdeStagingAction.class, POST, paramsBuilder.build()));
}
}
@@ -15,8 +15,6 @@
package google.registry.tools;
import static google.registry.model.tld.Tlds.assertTldsExist;
import static google.registry.util.DateTimeUtils.toLocalDate;
import static java.time.ZoneOffset.UTC;
import com.beust.jcommander.Parameter;
import com.beust.jcommander.Parameters;
@@ -28,6 +26,7 @@ import jakarta.inject.Inject;
import java.io.IOException;
import java.time.Duration;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.List;
import java.util.Map;
@@ -61,8 +60,7 @@ final class GenerateZoneFilesCommand implements CommandWithConnection {
@Override
public void run() throws IOException {
if (exportDate == null) {
exportDate =
toLocalDate(clock.now().minus(Duration.ofMinutes(2))).atStartOfDay(UTC).toInstant();
exportDate = clock.now().minus(Duration.ofMinutes(2)).truncatedTo(ChronoUnit.DAYS);
}
assertTldsExist(mainParameters);
ImmutableMap<String, Object> params = ImmutableMap.of(
@@ -14,7 +14,6 @@
package google.registry.tools;
import com.beust.jcommander.Parameter;
import com.beust.jcommander.Parameters;
import google.registry.keyring.api.KeySerializer;
@@ -26,7 +26,6 @@ import google.registry.model.adapters.CurrencyJsonAdapter;
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;
@@ -34,7 +33,6 @@ import java.io.Serializable;
import java.time.Duration;
import java.time.Instant;
import org.joda.money.CurrencyUnit;
import org.joda.time.DateTime;
/** Utility class for methods related to GSON and necessary GSON processing. */
public class GsonUtils {
@@ -78,7 +76,7 @@ public class GsonUtils {
return new GsonBuilder()
.registerTypeAdapter(CidrAddressBlock.class, new CidrAddressBlockAdapter())
.registerTypeAdapter(CurrencyUnit.class, new CurrencyJsonAdapter())
.registerTypeAdapter(DateTime.class, new DateTimeTypeAdapter())
.registerTypeAdapter(Instant.class, new InstantTypeAdapter())
.registerTypeAdapter(Duration.class, new DurationTypeAdapter())
.registerTypeAdapter(Instant.class, new InstantTypeAdapter())
.registerTypeAdapter(Serializable.class, new SerializableJsonTypeAdapter())
@@ -126,7 +126,6 @@ final class SetupOteCommand extends ConfirmingCommand {
String.format(
"""
WARNING: Running against %s environment. Are \
you sure you didn't mean to run this against sandbox (e.g. "-e SANDBOX")?\
""",
@@ -107,4 +107,3 @@ final class UpdateKeyringSecretCommand implements Command {
secretManagerKeyringUpdater.update();
}
}
@@ -13,32 +13,32 @@
// limitations under the License.
package google.registry.tools.params;
import static org.joda.time.DateTimeZone.UTC;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.joda.time.format.DateTimeFormatter;
import org.joda.time.format.ISODateTimeFormat;
import static java.time.ZoneOffset.UTC;
import java.time.Instant;
import java.time.LocalDate;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
/**
* {@link DateTime} CLI parameter converter/validator restricted to dates. The {@link DateTime}s
* produced by this class will always have a time zone of {@link DateTimeZone#UTC}.
* {@link Instant} CLI parameter converter/validator restricted to dates. The {@link Instant}s
* produced by this class will always have a time zone of {@link ZoneOffset#UTC}.
*/
public final class DateParameter extends ParameterConverterValidator<DateTime> {
public final class DateParameter extends ParameterConverterValidator<Instant> {
public DateParameter() {
super("not an ISO-8601 date");
}
/**
* Parser for DateTimes that permits only a restricted subset of ISO 8601 datetime syntax.
* The supported format is "YYYY-MM-DD", i.e. there must only be a complete date.
* Parser for Instants that permits only a restricted subset of ISO 8601 datetime syntax. The
* supported format is "YYYY-MM-DD", i.e. there must only be a complete date.
*/
private static final DateTimeFormatter STRICT_DATE_PARSER =
new DateTimeFormatter(null, ISODateTimeFormat.date().getParser());
private static final DateTimeFormatter STRICT_DATE_PARSER = DateTimeFormatter.ISO_LOCAL_DATE;
@Override
public DateTime convert(String value) {
return DateTime.parse(value, STRICT_DATE_PARSER).withZoneRetainFields(UTC);
public Instant convert(String value) {
return LocalDate.parse(value, STRICT_DATE_PARSER).atStartOfDay(UTC).toInstant();
}
}
@@ -1,56 +0,0 @@
// Copyright 2017 The Nomulus Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package google.registry.tools.params;
import static org.joda.time.DateTimeZone.UTC;
import com.google.common.primitives.Longs;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormatter;
import org.joda.time.format.DateTimeFormatterBuilder;
import org.joda.time.format.DateTimeParser;
import org.joda.time.format.ISODateTimeFormat;
/** {@linkplain DateTime} CLI parameter converter/validator. Can be ISO or millis from epoch. */
public final class DateTimeParameter extends ParameterConverterValidator<DateTime> {
public DateTimeParameter() {
super("not an ISO-8601 timestamp (or millis from epoch)");
}
/**
* Parser for DateTimes that permits only a restricted subset of ISO 8601 datetime syntax.
* The supported format is "YYYY-MM-DD'T'HH:MM:SS[.SSS]ZZ", i.e. there must be a complete date
* and at least hours, minutes, seconds, and time zone; milliseconds are optional.
*
* <p>We use this instead of the default {@link ISODateTimeFormat#dateTimeParser()} because that
* parser is very flexible and accepts date times with missing dates, missing dates, and various
* other unspecified fields that can lead to confusion and ambiguity.
*/
private static final DateTimeFormatter STRICT_DATE_TIME_PARSER = new DateTimeFormatterBuilder()
.append(null, new DateTimeParser[] {
// The formatter will try the following parsers in order until one succeeds.
ISODateTimeFormat.dateTime().getParser(),
ISODateTimeFormat.dateTimeNoMillis().getParser()})
.toFormatter();
@Override
public DateTime convert(String value) {
Long millis = Longs.tryParse(value);
if (millis != null) {
return new DateTime(millis.longValue(), UTC);
}
return DateTime.parse(value, STRICT_DATE_TIME_PARSER).withZone(UTC);
}
}
@@ -14,8 +14,7 @@
package google.registry.tools.params;
import org.joda.time.Duration;
import org.joda.time.Period;
import java.time.Duration;
/** Duration CLI parameter converter/validator. */
public final class DurationParameter extends ParameterConverterValidator<Duration> {
@@ -26,6 +25,6 @@ public final class DurationParameter extends ParameterConverterValidator<Duratio
@Override
public Duration convert(String value) {
return Period.parse(value).toStandardDuration();
return Duration.parse(value);
}
}
@@ -14,26 +14,23 @@
package google.registry.tools.params;
import static google.registry.util.DateTimeUtils.toInstant;
import com.google.common.primitives.Longs;
import java.time.Instant;
import java.time.OffsetDateTime;
/** {@linkplain Instant} CLI parameter converter/validator. Can be ISO or millis from epoch. */
public final class InstantParameter extends ParameterConverterValidator<Instant> {
private static final DateTimeParameter DATE_TIME_CONVERTER = new DateTimeParameter();
public InstantParameter() {
super("not an ISO-8601 timestamp (or millis from epoch)");
}
/**
* Converts the given string to an {@link Instant}.
*
* <p>Delegates to {@link DateTimeParameter} for parsing, then converts to {@link Instant}.
*/
@Override
public Instant convert(String value) {
return toInstant(DATE_TIME_CONVERTER.convert(value));
Long millis = Longs.tryParse(value);
if (millis != null) {
return Instant.ofEpochMilli(millis);
}
return OffsetDateTime.parse(value).toInstant();
}
}
@@ -1,41 +0,0 @@
// Copyright 2017 The Nomulus Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package google.registry.tools.params;
import org.joda.time.DateTimeZone;
import org.joda.time.Interval;
/** Interval CLI parameter converter/validator. */
public final class IntervalParameter extends ParameterConverterValidator<Interval> {
public IntervalParameter() {
super("not an ISO-8601 interval (e.g. 2004-06-09T12:30:00Z/2004-07-10T13:30:00Z)");
}
@Override
public Interval convert(String value) {
// Interval.parse(null) creates an interval with both start and end times set to now.
// Do something a little more reasonable.
if (value == null) {
throw new NullPointerException();
}
Interval interval = Interval.parse(value);
// Interval does not have a way to set the time zone, so create a new interval with the
// start and end times of the parsed interval converted to UTC.
return new Interval(
interval.getStart().withZone(DateTimeZone.UTC),
interval.getEnd().withZone(DateTimeZone.UTC));
}
}
@@ -14,8 +14,8 @@
package google.registry.tools.params;
import org.joda.time.LocalDate;
import org.joda.time.format.ISODateTimeFormat;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
/** {@linkplain LocalDate} CLI parameter converter/validator. */
public final class LocalDateParameter extends ParameterConverterValidator<LocalDate> {
@@ -26,6 +26,6 @@ public final class LocalDateParameter extends ParameterConverterValidator<LocalD
@Override
public LocalDate convert(String value) {
return LocalDate.parse(value, ISODateTimeFormat.date());
return LocalDate.parse(value, DateTimeFormatter.ISO_LOCAL_DATE);
}
}
@@ -1,21 +0,0 @@
// Copyright 2017 The Nomulus Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package google.registry.tools.params;
import org.joda.time.Interval;
/** Optional wrapper for IntervalParameter. */
public final class OptionalIntervalParameter
extends OptionalParameterConverterValidator<Interval, IntervalParameter> {}
@@ -17,6 +17,7 @@ package google.registry.tools.params;
import com.beust.jcommander.IParameterValidator;
import com.beust.jcommander.IStringConverter;
import com.beust.jcommander.ParameterException;
import java.time.DateTimeException;
/** Base class for parameters that do both conversion and validation (reduces boilerplate). */
public abstract class ParameterConverterValidator<T>
@@ -39,7 +40,7 @@ public abstract class ParameterConverterValidator<T>
public void validate(String name, String value) throws ParameterException {
try {
convert(value);
} catch (IllegalArgumentException e) {
} catch (IllegalArgumentException | DateTimeException e) {
throw new ParameterException(String.format("%s=%s %s", name, value, messageForInvalid), e);
}
}
@@ -20,14 +20,13 @@ import com.google.common.collect.ImmutableMap;
import com.google.common.net.HostAndPort;
import com.google.common.net.InternetDomainName;
import java.nio.file.Path;
import java.time.Duration;
import java.time.Instant;
import java.time.LocalDate;
import java.time.YearMonth;
import java.util.logging.Level;
import javax.annotation.Nullable;
import org.joda.money.Money;
import org.joda.time.DateTime;
import org.joda.time.Duration;
import org.joda.time.Interval;
import org.joda.time.LocalDate;
import org.joda.time.YearMonth;
/** JCommander converter factory that works for non-internal converters. */
public final class ParameterFactory implements IStringConverterFactory {
@@ -41,17 +40,14 @@ public final class ParameterFactory implements IStringConverterFactory {
private static final ImmutableMap<Class<?>, Class<? extends IStringConverter<?>>> CONVERTERS =
new ImmutableMap.Builder<Class<?>, Class<? extends IStringConverter<?>>>()
.put(DateTime.class, DateTimeParameter.class)
.put(Instant.class, InstantParameter.class)
.put(Duration.class, DurationParameter.class)
.put(HostAndPort.class, HostAndPortParameter.class)
.put(InternetDomainName.class, InternetDomainNameParameter.class)
.put(Interval.class, IntervalParameter.class)
.put(Level.class, LoggingLevelParameter.class)
.put(LocalDate.class, LocalDateParameter.class)
.put(Money.class, MoneyParameter.class)
.put(Path.class, PathParameter.class)
.put(YearMonth.class, YearMonthParameter.class)
.build();
}
@@ -29,7 +29,7 @@ import org.joda.money.Money;
// TODO(b/19031334): Investigate making this complex generic type work with the factory.
public abstract class TransitionListParameter<V> extends KeyValueMapParameter<Instant, V> {
private static final InstantParameter DATE_TIME_CONVERTER = new InstantParameter();
private static final InstantParameter INSTANT_CONVERTER = new InstantParameter();
public TransitionListParameter() {
// This is not sentence-capitalized like most exception messages because it is appended to the
@@ -39,7 +39,7 @@ public abstract class TransitionListParameter<V> extends KeyValueMapParameter<In
@Override
protected final Instant parseKey(String rawKey) {
return DATE_TIME_CONVERTER.convert(rawKey);
return INSTANT_CONVERTER.convert(rawKey);
}
@Override
@@ -14,8 +14,7 @@
package google.registry.tools.params;
import org.joda.time.YearMonth;
import org.joda.time.format.ISODateTimeFormat;
import java.time.YearMonth;
/** {@linkplain YearMonth} CLI parameter converter/validator (e.g. 1984-12) */
public final class YearMonthParameter extends ParameterConverterValidator<YearMonth> {
@@ -26,6 +25,6 @@ public final class YearMonthParameter extends ParameterConverterValidator<YearMo
@Override
public YearMonth convert(String value) {
return YearMonth.parse(value, ISODateTimeFormat.yearMonth());
return YearMonth.parse(value);
}
}
@@ -127,7 +127,7 @@ public class GenerateZoneFilesAction implements Runnable, JsonActionRunner.JsonA
if (exportTime.isAfter(minusMinutes(now, 2))) {
throw new BadRequestException("Invalid export time: must be > 2 minutes ago");
}
if (exportTime.isBefore(now.minusMillis(databaseRetention.toMillis()))) {
if (exportTime.isBefore(now.minus(databaseRetention))) {
throw new BadRequestException(
String.format("Invalid export time: must be < %d days ago", databaseRetention.toDays()));
}
@@ -16,7 +16,6 @@ package google.registry.ui.server.console;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.request.Action.Method.GET;
import static google.registry.util.DateTimeUtils.toLocalDate;
import static java.time.ZoneOffset.UTC;
import com.google.common.collect.ImmutableList;
@@ -86,8 +85,7 @@ public class ConsoleDumDownloadAction extends ConsoleApiAction {
.setHeader("Cache-Control", "max-age=86400"); // 86400 seconds = 1 day
consoleApiParams
.response()
.setDateHeader(
"Expires", toLocalDate(clock.now()).atStartOfDay(UTC).plusDays(1).toInstant());
.setDateHeader("Expires", clock.nowDate().atStartOfDay(UTC).plusDays(1).toInstant());
try (var writer = consoleApiParams.response().getWriter()) {
CSVPrinter csvPrinter = new CSVPrinter(writer, CSVFormat.DEFAULT);
@@ -17,8 +17,8 @@ package google.registry.xml;
import static com.google.common.base.Strings.isNullOrEmpty;
import jakarta.xml.bind.annotation.adapters.XmlAdapter;
import java.time.Period;
import javax.annotation.Nullable;
import org.joda.time.Period;
/** Adapter to use Joda {@link Period} when marshalling XML. */
public class PeriodAdapter extends XmlAdapter<String, Period> {
@@ -1,68 +0,0 @@
// Copyright 2017 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.xml;
import static com.google.common.base.Strings.isNullOrEmpty;
import static org.joda.time.DateTimeZone.UTC;
import jakarta.xml.bind.annotation.adapters.XmlAdapter;
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormatter;
import org.joda.time.format.ISODateTimeFormat;
/**
* Adapter to use Joda {@link DateTime} when marshalling XML timestamps.
*
* <p>These fields shall contain timestamps indicating the date and time in UTC as specified in
* RFC3339, with no offset from the zero meridian. For example: {@code 2010-10-17T00:00:00Z}.
*/
public class UtcDateTimeAdapter extends XmlAdapter<String, DateTime> {
/** @see ISODateTimeFormat#dateTimeNoMillis */
private static final DateTimeFormatter MARSHAL_FORMAT = ISODateTimeFormat.dateTimeNoMillis();
/** @see ISODateTimeFormat#dateTimeParser */
private static final DateTimeFormatter UNMARSHAL_FORMAT = ISODateTimeFormat.dateTimeParser();
/** Same as {@link #marshal(DateTime)}, but in a convenient static format. */
public static String getFormattedString(@Nullable DateTime timestamp) {
return (timestamp == null) ? "" : MARSHAL_FORMAT.print(timestamp.toDateTime(UTC));
}
/**
* Parses an ISO timestamp string into a UTC {@link DateTime} object, converting timezones if
* necessary. If {@code timestamp} is empty or {@code null} then {@code null} is returned.
*/
@Nullable
@CheckForNull
@Override
public DateTime unmarshal(@Nullable String timestamp) {
if (isNullOrEmpty(timestamp)) {
return null;
}
return UNMARSHAL_FORMAT.parseDateTime(timestamp).withZone(UTC);
}
/**
* Converts {@link DateTime} to UTC and returns it as an RFC3339 string. If {@code timestamp} is
* {@code null} then an empty string is returned.
*/
@Override
public String marshal(@Nullable DateTime timestamp) {
return getFormattedString(timestamp);
}
}
@@ -1,4 +1,4 @@
// Copyright 2026 The Nomulus Authors. All Rights Reserved.
// Copyright 2017 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.
@@ -15,41 +15,34 @@
package google.registry.xml;
import static com.google.common.base.Strings.isNullOrEmpty;
import static google.registry.util.DateTimeUtils.formatInstant;
import static google.registry.util.DateTimeUtils.parseInstant;
import static java.time.ZoneOffset.UTC;
import jakarta.xml.bind.annotation.adapters.XmlAdapter;
import java.time.Instant;
import java.time.format.DateTimeFormatter;
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
/**
* Adapter to use java.time {@link Instant} when marshalling XML timestamps.
* Adapter to use an {@link Instant} when marshalling XML timestamps.
*
* <p>These fields shall contain timestamps indicating the date and time in UTC as specified in
* RFC3339, with no offset from the zero meridian. For example: {@code 2010-10-17T00:00:00Z}.
* RFC3339.
*
* @see <a href="http://tools.ietf.org/html/rfc3339">RFC3339</a>
*/
public class UtcInstantAdapter extends XmlAdapter<String, Instant> {
private static final DateTimeFormatter MARSHAL_FORMAT =
DateTimeFormatter.ofPattern("u-MM-dd'T'HH:mm:ss'Z'").withZone(UTC);
/** Same as {@link #marshal(Instant)}, but in a convenient static format. */
public static String getFormattedString(@Nullable Instant timestamp) {
if (timestamp == null) {
return "";
}
return MARSHAL_FORMAT.format(timestamp);
return (timestamp == null) ? "" : formatInstant(timestamp);
}
/**
* Parses an ISO timestamp string into a UTC {@link Instant} object. If {@code timestamp} is empty
* or {@code null} then {@code null} is returned.
* Parses an ISO timestamp string into a UTC {@link Instant} object, converting timezones if
* necessary. If {@code timestamp} is empty or {@code null} then {@code null} is returned.
*/
@Nullable
@CheckForNull
@Override
@CheckForNull
public Instant unmarshal(@Nullable String timestamp) {
if (isNullOrEmpty(timestamp)) {
return null;
@@ -83,7 +83,6 @@
<!-- Customized type converters -->
<class>google.registry.persistence.converter.BloomFilterConverter</class>
<class>google.registry.persistence.converter.CurrencyUnitConverter</class>
<class>google.registry.persistence.converter.DateTimeConverter</class>
<!-- Generated converters for VKey -->
<class>google.registry.model.billing.VKeyConverter_BillingCancellation</class>
@@ -216,8 +216,8 @@ public class CloudTasksUtilsTest {
assertThat(task.getScheduleTime().getSeconds()).isNotEqualTo(0);
Instant scheduleTime = Instant.ofEpochSecond(task.getScheduleTime().getSeconds());
Instant lowerBoundTime = Instant.ofEpochMilli(clock.now().toEpochMilli());
Instant upperBound = Instant.ofEpochMilli(clock.now().plusSeconds(100).toEpochMilli());
Instant lowerBoundTime = clock.now();
Instant upperBound = clock.now().plusSeconds(100);
assertThat(scheduleTime.isBefore(lowerBoundTime)).isFalse();
assertThat(upperBound.isBefore(scheduleTime)).isFalse();
@@ -253,7 +253,7 @@ public class CloudTasksUtilsTest {
.isEqualTo("https://backend.registry.test/the/path?key1=val1&key2=val2&key1=val3");
verifyOidcToken(task);
assertThat(Instant.ofEpochSecond(task.getScheduleTime().getSeconds()))
.isEqualTo(Instant.ofEpochMilli(clock.now().plus(Duration.ofMinutes(10)).toEpochMilli()));
.isEqualTo(clock.now().plus(Duration.ofMinutes(10)));
}
@Test
@@ -25,7 +25,6 @@ import static google.registry.testing.DatabaseHelper.persistDomainWithDependentR
import static google.registry.testing.DatabaseHelper.persistDomainWithPendingTransfer;
import static google.registry.testing.DatabaseHelper.persistResource;
import static google.registry.util.DateTimeUtils.plusDays;
import static org.joda.time.Duration.standardDays;
import static org.mockito.Mockito.verify;
import com.google.cloud.tasks.v2.HttpMethod;
@@ -41,6 +40,7 @@ import google.registry.request.Response;
import google.registry.testing.CloudTasksHelper;
import google.registry.testing.CloudTasksHelper.TaskMatcher;
import google.registry.testing.FakeClock;
import java.time.Duration;
import java.time.Instant;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -121,7 +121,7 @@ public class ResaveEntityActionTest {
plusDays(clock.now(), 30),
"TheRegistrar")))
.build());
clock.advanceBy(standardDays(30));
clock.advanceBy(Duration.ofDays(30));
Instant requestedTime = clock.now();
assertThat(domain.getGracePeriods()).isNotEmpty();
@@ -44,10 +44,10 @@ import google.registry.persistence.transaction.CriteriaQueryBuilder;
import google.registry.persistence.transaction.JpaTestExtensions;
import google.registry.persistence.transaction.JpaTestExtensions.JpaIntegrationTestExtension;
import google.registry.testing.FakeClock;
import java.time.Instant;
import org.apache.beam.sdk.coders.StringUtf8Coder;
import org.apache.beam.sdk.testing.PAssert;
import org.apache.beam.sdk.values.PCollection;
import org.joda.time.DateTime;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
@@ -55,7 +55,7 @@ import org.junit.jupiter.api.extension.RegisterExtension;
/** Unit tests for {@link RegistryJpaIO.Read}. */
public class RegistryJpaReadTest {
private static final DateTime START_TIME = DateTime.parse("2000-01-01T00:00:00.0Z");
private static final Instant START_TIME = Instant.parse("2000-01-01T00:00:00.0Z");
private final FakeClock fakeClock = new FakeClock(START_TIME);
@@ -28,15 +28,15 @@ import google.registry.persistence.transaction.JpaTestExtensions.JpaIntegrationT
import google.registry.persistence.transaction.JpaTransactionManagerExtension;
import google.registry.testing.FakeClock;
import java.io.Serializable;
import java.time.Instant;
import org.apache.beam.sdk.transforms.Create;
import org.joda.time.DateTime;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
/** Unit test for {@link RegistryJpaIO.Write}. */
class RegistryJpaWriteTest implements Serializable {
private final FakeClock fakeClock = new FakeClock(DateTime.parse("2000-01-01T00:00:00.0Z"));
private final FakeClock fakeClock = new FakeClock(Instant.parse("2000-01-01T00:00:00.0Z"));
@RegisterExtension
final transient JpaIntegrationTestExtension jpa =
@@ -96,7 +96,6 @@ import org.apache.beam.sdk.values.KV;
import org.apache.beam.sdk.values.PCollection;
import org.bouncycastle.openpgp.PGPPrivateKey;
import org.bouncycastle.openpgp.PGPPublicKey;
import org.joda.time.DateTime;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
@@ -113,9 +112,9 @@ public class RdePipelineTest {
private static final String HOST_NAME_PATTERN = "<rdeHost:name>(.*)</rdeHost:name>";
// This is the default creation time for test data.
private final FakeClock clock = new FakeClock(DateTime.parse("1999-12-31TZ"));
private final FakeClock clock = new FakeClock(Instant.parse("1999-12-31T00:00:00Z"));
// This is teh default as-of time the RDE/BRDA job.
// This is the default as-of time the RDE/BRDA job.
private final Instant now = Instant.parse("2000-01-01T00:00:00.000Z");
private final ImmutableSet<PendingDeposit> pendings =
@@ -352,8 +351,8 @@ public class RdePipelineTest {
</rdeDomain:ns>
<rdeDomain:clID>TheRegistrar</rdeDomain:clID>
<rdeDomain:crRr>TheRegistrar</rdeDomain:crRr>
<rdeDomain:crDate>1970-01-01T00:00:00Z</rdeDomain:crDate>
<rdeDomain:exDate>294247-01-10T04:00:54Z</rdeDomain:exDate>
<rdeDomain:crDate>1970-01-01T00:00:00.000Z</rdeDomain:crDate>
<rdeDomain:exDate>294247-01-10T04:00:54.775Z</rdeDomain:exDate>
</rdeDomain:domain>\
""");
}
@@ -381,8 +380,8 @@ public class RdePipelineTest {
</rdeDomain:ns>
<rdeDomain:clID>TheRegistrar</rdeDomain:clID>
<rdeDomain:crRr>TheRegistrar</rdeDomain:crRr>
<rdeDomain:crDate>1970-01-01T00:00:00Z</rdeDomain:crDate>
<rdeDomain:exDate>294247-01-10T04:00:54Z</rdeDomain:exDate>
<rdeDomain:crDate>1970-01-01T00:00:00.000Z</rdeDomain:crDate>
<rdeDomain:exDate>294247-01-10T04:00:54.775Z</rdeDomain:exDate>
</rdeDomain:domain>\
""");
} else {
@@ -415,8 +414,8 @@ public class RdePipelineTest {
</rdeDomain:ns>
<rdeDomain:clID>TheRegistrar</rdeDomain:clID>
<rdeDomain:crRr>TheRegistrar</rdeDomain:crRr>
<rdeDomain:crDate>1970-01-01T00:00:00Z</rdeDomain:crDate>
<rdeDomain:exDate>294247-01-10T04:00:54Z</rdeDomain:exDate>
<rdeDomain:crDate>1970-01-01T00:00:00.000Z</rdeDomain:crDate>
<rdeDomain:exDate>294247-01-10T04:00:54.775Z</rdeDomain:exDate>
</rdeDomain:domain>\
""");
}
@@ -53,6 +53,7 @@ import google.registry.util.Retrier;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Instant;
import java.time.LocalDate;
import org.apache.beam.sdk.coders.KvCoder;
import org.apache.beam.sdk.coders.SerializableCoder;
@@ -64,7 +65,6 @@ import org.apache.beam.sdk.values.PCollection;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.joda.time.DateTime;
import org.json.JSONObject;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -80,7 +80,7 @@ import org.junit.jupiter.api.io.TempDir;
*/
class Spec11PipelineTest {
private static final DateTime START_TIME = DateTime.parse("2020-01-27T00:00:00.0Z");
private static final Instant START_TIME = Instant.parse("2020-01-27T00:00:00.0Z");
private final FakeClock fakeClock = new FakeClock(START_TIME);
private static final String DATE = "2020-01-27";
@@ -28,7 +28,6 @@ import static google.registry.util.DateTimeUtils.minusHours;
import static google.registry.util.DateTimeUtils.plusHours;
import static org.joda.money.CurrencyUnit.JPY;
import static org.joda.money.CurrencyUnit.USD;
import static org.joda.time.Duration.standardMinutes;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.verify;
@@ -43,6 +42,7 @@ import google.registry.persistence.transaction.JpaTestExtensions;
import google.registry.persistence.transaction.JpaTestExtensions.JpaIntegrationTestExtension;
import google.registry.testing.DatabaseHelper;
import google.registry.testing.FakeClock;
import java.time.Duration;
import java.time.Instant;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -182,7 +182,7 @@ public class SyncRegistrarsSheetTest {
Instant registrarCreationTime = persistResource(registrar).getCreationTime();
persistResources(contacts);
clock.advanceBy(standardMinutes(1));
clock.advanceBy(Duration.ofMinutes(1));
newSyncRegistrarsSheet().run("foobar");
verify(sheetSynchronizer).synchronize(eq("foobar"), rowsCaptor.capture());
@@ -45,11 +45,11 @@ import google.registry.persistence.transaction.JpaTestExtensions.JpaIntegrationT
import google.registry.testing.FakeClock;
import google.registry.util.Clock;
import google.registry.xml.ValidationMode;
import java.time.Instant;
import java.util.List;
import java.util.Map;
import java.util.logging.LogRecord;
import java.util.logging.Logger;
import org.joda.time.DateTime;
import org.json.simple.JSONValue;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
@@ -81,7 +81,7 @@ class EppControllerTest {
@Mock EppResponse eppResponse;
@Mock Result result;
private static final DateTime START_TIME = DateTime.parse("2016-09-01T00:00:00Z");
private static final Instant START_TIME = Instant.parse("2016-09-01T00:00:00Z");
private final Clock clock = new FakeClock(START_TIME);
private final TestLogHandler logHandler = new TestLogHandler();
@@ -14,7 +14,6 @@
package google.registry.flows;
import com.google.common.collect.ImmutableMap;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
@@ -150,4 +150,3 @@ public interface EppTestComponent {
FlowComponent.Builder flowComponentBuilder();
}
}

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