mirror of
https://github.com/google/nomulus
synced 2026-08-20 14:16:19 +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:
@@ -33,7 +33,6 @@ dependencies {
|
||||
implementation deps['io.netty:netty-handler']
|
||||
implementation deps['io.netty:netty-transport']
|
||||
implementation deps['jakarta.inject:jakarta.inject-api']
|
||||
implementation deps['joda-time:joda-time']
|
||||
implementation deps['org.bouncycastle:bcpkix-jdk18on']
|
||||
implementation deps['org.bouncycastle:bcprov-jdk18on']
|
||||
implementation deps['xerces:xmlParserAPIs']
|
||||
|
||||
@@ -113,7 +113,6 @@ jakarta.mail:jakarta.mail-api:2.2.0-M1=deploy_jar,runtimeClasspath,testRuntimeCl
|
||||
jakarta.xml.bind:jakarta.xml.bind-api:4.1.0-M1=deploy_jar,runtimeClasspath,testRuntimeClasspath
|
||||
javax.annotation:javax.annotation-api:1.3.2=deploy_jar,runtimeClasspath,testRuntimeClasspath
|
||||
javax.inject:javax.inject:1=annotationProcessor,compileClasspath,deploy_jar,runtimeClasspath,testAnnotationProcessor,testCompileClasspath,testRuntimeClasspath
|
||||
joda-time:joda-time:2.14.2=compileClasspath,deploy_jar,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
junit:junit:4.13.2=testCompileClasspath,testRuntimeClasspath
|
||||
net.bytebuddy:byte-buddy-agent:1.17.7=testCompileClasspath,testRuntimeClasspath
|
||||
net.bytebuddy:byte-buddy:1.17.7=testCompileClasspath,testRuntimeClasspath
|
||||
|
||||
@@ -31,8 +31,8 @@ import io.netty.channel.socket.nio.NioSocketChannel;
|
||||
import io.netty.handler.ssl.OpenSsl;
|
||||
import io.netty.handler.ssl.SslProvider;
|
||||
import jakarta.inject.Singleton;
|
||||
import java.time.Duration;
|
||||
import java.util.Set;
|
||||
import org.joda.time.Duration;
|
||||
|
||||
/**
|
||||
* Dagger main module, which {@link Provides} all objects that are shared between sequences and
|
||||
@@ -43,7 +43,7 @@ import org.joda.time.Duration;
|
||||
public class ProberModule {
|
||||
|
||||
/** Default {@link Duration} chosen to be time between each {@link ProbingAction} call. */
|
||||
private static final Duration DEFAULT_PROBER_INTERVAL = Duration.standardSeconds(4);
|
||||
private static final Duration DEFAULT_PROBER_INTERVAL = Duration.ofSeconds(4);
|
||||
|
||||
/** {@link Provides} the {@link SslProvider} used by instances of {@link SslClientInitializer} */
|
||||
@Provides
|
||||
|
||||
@@ -111,7 +111,7 @@ public class ProbingSequence extends CircularList<ProbingStep> {
|
||||
* get().generateAction}.
|
||||
*/
|
||||
private void runStep(Token token) {
|
||||
long start = clock.now().toEpochMilli();
|
||||
long start = clock.nowMillis();
|
||||
|
||||
ProbingAction currentAction;
|
||||
ChannelFuture future;
|
||||
@@ -133,7 +133,7 @@ public class ProbingSequence extends CircularList<ProbingStep> {
|
||||
get().messageTemplate().name(),
|
||||
get().messageTemplate().responseName(),
|
||||
MetricsCollector.ResponseType.ERROR,
|
||||
clock.now().toEpochMilli() - start);
|
||||
clock.nowMillis() - start);
|
||||
return;
|
||||
|
||||
} catch (Exception e) {
|
||||
@@ -146,7 +146,7 @@ public class ProbingSequence extends CircularList<ProbingStep> {
|
||||
get().messageTemplate().name(),
|
||||
get().messageTemplate().responseName(),
|
||||
MetricsCollector.ResponseType.ERROR,
|
||||
clock.now().toEpochMilli() - start);
|
||||
clock.nowMillis() - start);
|
||||
|
||||
// Restart the sequence at the very first step.
|
||||
restartSequence();
|
||||
@@ -165,7 +165,7 @@ public class ProbingSequence extends CircularList<ProbingStep> {
|
||||
get().messageTemplate().name(),
|
||||
get().messageTemplate().responseName(),
|
||||
MetricsCollector.ResponseType.SUCCESS,
|
||||
clock.now().toEpochMilli() - start);
|
||||
clock.nowMillis() - start);
|
||||
} else {
|
||||
// On a failed result, we log the failure and note either a failure or error.
|
||||
logger.atSevere().withCause(f.cause()).log("Did not result in future success");
|
||||
@@ -177,14 +177,14 @@ public class ProbingSequence extends CircularList<ProbingStep> {
|
||||
get().messageTemplate().name(),
|
||||
get().messageTemplate().responseName(),
|
||||
MetricsCollector.ResponseType.FAILURE,
|
||||
clock.now().toEpochMilli() - start);
|
||||
clock.nowMillis() - start);
|
||||
} else {
|
||||
metrics.recordResult(
|
||||
get().protocol().name(),
|
||||
get().messageTemplate().name(),
|
||||
get().messageTemplate().responseName(),
|
||||
MetricsCollector.ResponseType.ERROR,
|
||||
clock.now().toEpochMilli() - start);
|
||||
clock.nowMillis() - start);
|
||||
}
|
||||
|
||||
// If not unrecoverable, we restart the sequence.
|
||||
|
||||
@@ -22,7 +22,7 @@ import google.registry.monitoring.blackbox.exception.UndeterminedStateException;
|
||||
import google.registry.monitoring.blackbox.message.OutboundMessageType;
|
||||
import google.registry.monitoring.blackbox.token.Token;
|
||||
import io.netty.bootstrap.Bootstrap;
|
||||
import org.joda.time.Duration;
|
||||
import java.time.Duration;
|
||||
|
||||
/**
|
||||
* {@link AutoValue} class that represents generator of actions performed at each step in {@link
|
||||
@@ -75,9 +75,9 @@ public record ProbingStep(
|
||||
public String toString() {
|
||||
return String.format(
|
||||
"""
|
||||
ProbingStep with Protocol: %s
|
||||
OutboundMessage: %s
|
||||
""",
|
||||
ProbingStep with Protocol: %s
|
||||
OutboundMessage: %s
|
||||
""",
|
||||
protocol(), messageTemplate().getClass().getName());
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -40,9 +40,9 @@ import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.SocketAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.time.Duration;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import org.joda.time.Duration;
|
||||
|
||||
/**
|
||||
* AutoValue class that represents action generated by {@link ProbingStep}
|
||||
@@ -186,7 +186,7 @@ public abstract class ProbingAction implements Callable<ChannelFuture> {
|
||||
}
|
||||
});
|
||||
},
|
||||
delay().getStandardSeconds(),
|
||||
delay().toSeconds(),
|
||||
TimeUnit.SECONDS);
|
||||
} else {
|
||||
// if we receive a failure, log the failure, and close the channel
|
||||
@@ -208,7 +208,7 @@ public abstract class ProbingAction implements Callable<ChannelFuture> {
|
||||
protocol: %s
|
||||
host: %s
|
||||
""",
|
||||
delay().getStandardSeconds(), outboundMessage(), protocol(), host());
|
||||
delay().toSeconds(), outboundMessage(), protocol(), host());
|
||||
}
|
||||
|
||||
/** {@link AutoValue.Builder} that does work of creating connection when not already present. */
|
||||
|
||||
+4
-6
@@ -30,9 +30,9 @@ import java.security.GeneralSecurityException;
|
||||
import java.security.KeyStore;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.time.Duration;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.Supplier;
|
||||
import org.joda.time.Duration;
|
||||
|
||||
/**
|
||||
* Dagger module that provides bindings needed to inject server certificate chain and private key.
|
||||
@@ -63,7 +63,7 @@ public class CertificateModule {
|
||||
@Provides
|
||||
@LocalSecrets
|
||||
static Duration provideCacheDuration() {
|
||||
return Duration.standardSeconds(2);
|
||||
return Duration.ofSeconds(2);
|
||||
}
|
||||
|
||||
@Singleton
|
||||
@@ -111,8 +111,7 @@ public class CertificateModule {
|
||||
@LocalSecrets
|
||||
static Supplier<PrivateKey> providePrivatekeySupplier(
|
||||
@LocalSecrets Provider<PrivateKey> privateKeyProvider, @LocalSecrets Duration duration) {
|
||||
return memoizeWithExpiration(
|
||||
privateKeyProvider::get, duration.getStandardSeconds(), TimeUnit.SECONDS);
|
||||
return memoizeWithExpiration(privateKeyProvider::get, duration.toSeconds(), TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
@Singleton
|
||||
@@ -121,7 +120,6 @@ public class CertificateModule {
|
||||
static Supplier<ImmutableList<X509Certificate>> provideCertificatesSupplier(
|
||||
@LocalSecrets Provider<ImmutableList<X509Certificate>> certificatesProvider,
|
||||
@LocalSecrets Duration duration) {
|
||||
return memoizeWithExpiration(
|
||||
certificatesProvider::get, duration.getStandardSeconds(), TimeUnit.SECONDS);
|
||||
return memoizeWithExpiration(certificatesProvider::get, duration.toSeconds(), TimeUnit.SECONDS);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,8 +52,8 @@ import jakarta.inject.Qualifier;
|
||||
import jakarta.inject.Singleton;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.time.Duration;
|
||||
import java.util.function.Supplier;
|
||||
import org.joda.time.Duration;
|
||||
|
||||
/**
|
||||
* A module that provides the components necessary for and the overall {@link ProbingSequence} to
|
||||
|
||||
@@ -81,8 +81,7 @@ public abstract class EppToken extends Token {
|
||||
*/
|
||||
private String getNewTRID() {
|
||||
return String.format(
|
||||
"prober-%s-%d-%d",
|
||||
"localhost", clock.now().toEpochMilli(), clientIdSuffix.incrementAndGet());
|
||||
"prober-%s-%d-%d", "localhost", clock.nowMillis(), clientIdSuffix.incrementAndGet());
|
||||
}
|
||||
|
||||
/** Return a fully qualified domain label to use, derived from the client transaction ID. */
|
||||
|
||||
@@ -36,7 +36,7 @@ import google.registry.util.Clock;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelPromise;
|
||||
import io.netty.channel.embedded.EmbeddedChannel;
|
||||
import org.joda.time.Duration;
|
||||
import java.time.Duration;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.Mockito;
|
||||
@@ -60,7 +60,7 @@ class ProbingSequenceTest {
|
||||
private static final String PROTOCOL_NAME = "PROTOCOL";
|
||||
private static final String MESSAGE_NAME = "MESSAGE";
|
||||
private static final String RESPONSE_NAME = "RESPONSE";
|
||||
private static final Duration LATENCY = Duration.millis(2L);
|
||||
private static final Duration LATENCY = Duration.ofMillis(2L);
|
||||
|
||||
/** Default mock {@link ProbingAction} returned when generating an action with a mockStep. */
|
||||
private ProbingAction mockAction = Mockito.mock(ProbingAction.class);
|
||||
@@ -223,7 +223,7 @@ class ProbingSequenceTest {
|
||||
// name and message name).
|
||||
verify(metrics)
|
||||
.recordResult(
|
||||
PROTOCOL_NAME, MESSAGE_NAME, RESPONSE_NAME, ResponseType.SUCCESS, LATENCY.getMillis());
|
||||
PROTOCOL_NAME, MESSAGE_NAME, RESPONSE_NAME, ResponseType.SUCCESS, LATENCY.toMillis());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -305,7 +305,7 @@ class ProbingSequenceTest {
|
||||
// name and message name) two times: once for mockStep and once for secondStep.
|
||||
verify(metrics, times(2))
|
||||
.recordResult(
|
||||
PROTOCOL_NAME, MESSAGE_NAME, RESPONSE_NAME, ResponseType.SUCCESS, LATENCY.getMillis());
|
||||
PROTOCOL_NAME, MESSAGE_NAME, RESPONSE_NAME, ResponseType.SUCCESS, LATENCY.toMillis());
|
||||
|
||||
// Verify that on second pass, since we purposely throw UnrecoverableStateException, we
|
||||
// record the ERROR. Also, we haven't had any time pass in the fake clock, so recorded
|
||||
@@ -390,13 +390,13 @@ class ProbingSequenceTest {
|
||||
// name and message name).
|
||||
verify(metrics)
|
||||
.recordResult(
|
||||
PROTOCOL_NAME, MESSAGE_NAME, RESPONSE_NAME, ResponseType.FAILURE, LATENCY.getMillis());
|
||||
PROTOCOL_NAME, MESSAGE_NAME, RESPONSE_NAME, ResponseType.FAILURE, LATENCY.toMillis());
|
||||
|
||||
// Verify that on second pass, since we purposely throw UnrecoverableStateException, we
|
||||
// record the ERROR. We also should make sure LATENCY seconds have passed.
|
||||
verify(metrics)
|
||||
.recordResult(
|
||||
PROTOCOL_NAME, MESSAGE_NAME, RESPONSE_NAME, ResponseType.ERROR, LATENCY.getMillis());
|
||||
PROTOCOL_NAME, MESSAGE_NAME, RESPONSE_NAME, ResponseType.ERROR, LATENCY.toMillis());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -421,6 +421,6 @@ class ProbingSequenceTest {
|
||||
// for terminating the sequence.
|
||||
verify(metrics, times(2))
|
||||
.recordResult(
|
||||
PROTOCOL_NAME, MESSAGE_NAME, RESPONSE_NAME, ResponseType.ERROR, LATENCY.getMillis());
|
||||
PROTOCOL_NAME, MESSAGE_NAME, RESPONSE_NAME, ResponseType.ERROR, LATENCY.toMillis());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ import io.netty.channel.embedded.EmbeddedChannel;
|
||||
import io.netty.channel.local.LocalAddress;
|
||||
import io.netty.channel.local.LocalChannel;
|
||||
import io.netty.channel.nio.NioEventLoopGroup;
|
||||
import org.joda.time.Duration;
|
||||
import java.time.Duration;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
+1
-1
@@ -33,7 +33,7 @@ import io.netty.channel.ChannelHandler;
|
||||
import io.netty.channel.embedded.EmbeddedChannel;
|
||||
import io.netty.channel.local.LocalAddress;
|
||||
import io.netty.channel.local.LocalChannel;
|
||||
import org.joda.time.Duration;
|
||||
import java.time.Duration;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||
|
||||
Reference in New Issue
Block a user