1
0
mirror of https://github.com/google/nomulus synced 2026-05-22 15:51:49 +00:00

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 12:07:19 -04:00
committed by GitHub
parent b33c2f4874
commit 56fe588b56
218 changed files with 589 additions and 1390 deletions

View File

@@ -15,7 +15,6 @@ package google.registry.client;
import static com.google.common.io.Resources.getResource;
import static java.nio.charset.StandardCharsets.UTF_8;
import static java.time.ZoneOffset.UTC;
import com.beust.jcommander.IStringConverter;
import com.beust.jcommander.JCommander;
@@ -54,7 +53,7 @@ import java.security.Security;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.time.Duration;
import java.time.ZonedDateTime;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedHashSet;
@@ -69,8 +68,6 @@ import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.openssl.PEMKeyPair;
import org.bouncycastle.openssl.PEMParser;
import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
/** A simple EPP client that can be used for load testing. */
@Parameters(separators = " =")
@@ -90,9 +87,8 @@ public class EppClient implements Runnable {
private static final String DOMAIN_CREATE_FILE = "domain_create.xml";
static final AttributeKey<ArrayList<ZonedDateTime>> REQUEST_SENT =
AttributeKey.valueOf("REQUEST_SENT");
static final AttributeKey<ArrayList<ZonedDateTime>> RESPONSE_RECEIVED =
static final AttributeKey<ArrayList<Instant>> REQUEST_SENT = AttributeKey.valueOf("REQUEST_SENT");
static final AttributeKey<ArrayList<Instant>> RESPONSE_RECEIVED =
AttributeKey.valueOf("RESPONSE_RECEIVED");
static final AttributeKey<Integer> CHANNEL_NUMBER = AttributeKey.valueOf("CHANNEL_NUMBER");
static final AttributeKey<Path> LOGGING_LOCATION = AttributeKey.valueOf("LOGGING_LOCATION");
@@ -192,7 +188,7 @@ public class EppClient implements Runnable {
return BaseEncoding.base32().encode(buffer).toLowerCase(Locale.US);
}
private ImmutableList<String> makeInputList(ZonedDateTime now) {
private ImmutableList<String> makeInputList(Instant now) {
ImmutableList.Builder<String> templatesList = ImmutableList.builder();
ImmutableList.Builder<String> inputList = ImmutableList.builder();
templatesList.add(readStringFromFile(LOGIN_FILE));
@@ -261,7 +257,7 @@ public class EppClient implements Runnable {
String outputFolder, ImmutableList<ExecutorService> loggingExecutors) throws IOException {
return new ChannelInitializer<>() {
private final ImmutableList<String> inputList = makeInputList(ZonedDateTime.now(UTC));
private final ImmutableList<String> inputList = makeInputList(Instant.now());
private final KeyPair key = getKeyPair(keyFileName);
private final X509Certificate cert = getCertificate(certFileName);
private final LoggingHandler loggingHandler = new LoggingHandler(LogLevel.INFO);
@@ -316,8 +312,7 @@ public class EppClient implements Runnable {
@Override
public void run() {
String outputFolder =
createOutputFolder(String.format("load-tests/%s", DateTime.now(DateTimeZone.UTC)));
String outputFolder = createOutputFolder(String.format("load-tests/%s", Instant.now()));
ImmutableList.Builder<ExecutorService> builder = ImmutableList.builderWithExpectedSize(5);
for (int i = 0; i < 5; ++i) {
builder.add(Executors.newSingleThreadExecutor());
@@ -360,8 +355,8 @@ public class EppClient implements Runnable {
LinkedHashSet<Integer> killedConnections = new LinkedHashSet<>();
LinkedHashSet<Integer> incompleteConnections = new LinkedHashSet<>();
List<Long> requestDurations = new ArrayList<>();
ZonedDateTime startTime = null;
ZonedDateTime endTime = null;
Instant startTime = null;
Instant endTime = null;
int failedRequests = 0;
// Wait for all channels to close.
@@ -372,8 +367,7 @@ public class EppClient implements Runnable {
.closeFuture()
.awaitUninterruptibly(
TIMEOUT_SECONDS * 1000
- Duration.between(
channel.attr(REQUEST_SENT).get().getFirst(), ZonedDateTime.now(UTC))
- Duration.between(channel.attr(REQUEST_SENT).get().getFirst(), Instant.now())
.toMillis())) {
channel.close().syncUninterruptibly();
killedConnections.add(channelNumber);
@@ -442,9 +436,9 @@ public class EppClient implements Runnable {
}
}
private ZonedDateTime updateStartTime(
List<ChannelFuture> channelFutures, int channelNumber, ZonedDateTime startTime) {
ZonedDateTime channelStartTime =
private Instant updateStartTime(
List<ChannelFuture> channelFutures, int channelNumber, Instant startTime) {
Instant channelStartTime =
channelFutures.get(channelNumber).channel().attr(REQUEST_SENT).get().getFirst();
if (startTime == null || startTime.isAfter(channelStartTime)) {
return channelStartTime;
@@ -452,9 +446,9 @@ public class EppClient implements Runnable {
return startTime;
}
private ZonedDateTime updateEndTime(
List<ChannelFuture> channelFutures, int channelNumber, ZonedDateTime endTime) {
ZonedDateTime channelEndTime =
private Instant updateEndTime(
List<ChannelFuture> channelFutures, int channelNumber, Instant endTime) {
Instant channelEndTime =
channelFutures.get(channelNumber).channel().attr(RESPONSE_RECEIVED).get().getLast();
if (endTime == null || endTime.isBefore(channelEndTime)) {

View File

@@ -23,7 +23,6 @@ import static google.registry.client.EppClient.LOGGING_REQUEST_COMPLETE;
import static google.registry.client.EppClient.REQUEST_SENT;
import static google.registry.client.EppClient.RESPONSE_RECEIVED;
import static java.nio.file.StandardOpenOption.APPEND;
import static java.time.ZoneOffset.UTC;
import com.google.common.flogger.FluentLogger;
import io.netty.buffer.ByteBuf;
@@ -38,7 +37,7 @@ import io.netty.util.concurrent.Promise;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.ZonedDateTime;
import java.time.Instant;
/** Handler that sends EPP requests and receives EPP responses. */
@SuppressWarnings("FutureReturnValueIgnored")
@@ -51,9 +50,9 @@ public class EppClientHandler extends ChannelDuplexHandler {
private final Path loggingLocation;
private final byte[] contents;
private final ZonedDateTime time;
private final Instant time;
FileWriter(Path loggingLocation, byte[] contents, ZonedDateTime time) {
FileWriter(Path loggingLocation, byte[] contents, Instant time) {
this.loggingLocation = loggingLocation;
this.contents = contents;
this.time = time;
@@ -75,7 +74,7 @@ public class EppClientHandler extends ChannelDuplexHandler {
@Override
public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
ZonedDateTime now = ZonedDateTime.now(UTC);
Instant now = Instant.now();
ctx.channel().attr(REQUEST_SENT).get().add(now);
ctx.channel().attr(LOGGING_REQUEST_COMPLETE).set(ctx.executor().newPromise());
super.channelRegistered(ctx);
@@ -93,7 +92,7 @@ public class EppClientHandler extends ChannelDuplexHandler {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) {
ZonedDateTime now = ZonedDateTime.now(UTC);
Instant now = Instant.now();
Channel ch = ctx.channel();
ctx.channel().attr(RESPONSE_RECEIVED).get().add(now);
if (msg instanceof ByteBuf buffer) {
@@ -118,7 +117,7 @@ public class EppClientHandler extends ChannelDuplexHandler {
@Override
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) {
ZonedDateTime now = ZonedDateTime.now(UTC);
Instant now = Instant.now();
Channel ch = ctx.channel();
ctx.channel().attr(REQUEST_SENT).get().add(now);
if (msg instanceof byte[] outputBytes) {