This only applies to the CacheModule-provided caches because we don't
want to have to deal with all the various other caches. We'll want to
know the various ratios between types of cache hits/misses when
evaluating the usefulness of the remote caching.
* Migrates core classes (Clock, Sleeper, TransactionManager) and extensive domain models from Joda-Time to java.time.
* Restores original public API method names while substituting parameters/return values with `java.time.Instant`.
* Updates JAXB XJC `bindings.xjb` to natively generate `java.time.Instant` and `java.time.LocalDate`, eliminating `toDateTime` wrapper methods.
* Fixes XML serializers (`DateAdapter`) to robustly convert OffsetDateTime timezone strings to UTC.
* Cleans up redundant imports and Checkstyle failures across the codebase.
Remaining Joda-Time surface area to migrate in future tasks:
* Command-line parameters (e.g. `DateTimeParameter`, `DateParameter`, `IntervalParameter`) in `google.registry.tools.params`.
* EPP/RDAP flow testing infrastructure (`EppTestCase`, `RdapActionBaseTestCase`, `FlowTestCase`).
* Beam pipelines and Load Testing modules (`Spec11PipelineTest`, `RdePipelineTest`, `RegistryJpaReadTest`, `EppClient`).
* Utility bridges and converters (`DateTimeUtils.toDateTime/toInstant`, `DateTimeConverter`, `UtcDateTimeAdapter`).
* Remaining UI Console tests and Actions.
Created a smoke test to cover unit test gaps wrt BEAM:
- The Java and SDK compatibility in the pipeline container image
- The JPA setup in the pipelines
Both issues above can only be tested in a real pipeline.
This PR defines a new pipeline that performs a lightweight SQL
query and minimal processing. The build process can launch it
in a test environment to verify that the pipelines in the build
can run. The run script is also provided.
Found this out while testing metrics. In hindsight, not the best idea to
handle prefixing outside of the client itself. Instead, we'll enforce
the prefixing closer to Valkey, all in one place.
This commit migrates the BSA, DNS, batch, and reporting packages from Joda-Time
to java.time. Key changes include:
- Updated Sleeper, Clock, and BigqueryUtils to use java.time types natively.
- Refactored models like RdeRevision and Tld to eliminate redundant Joda
conversions, utilizing new DateTimeUtils static utilities for LocalDate.
- Improved test safety by replacing dynamic Instant.now() calls with static
parsed constants.
- Migrated temporal arithmetic in test suites to use DateTimeUtils convenience
methods (plusDays, minusDays).
- Updated BigqueryUtils serialization to preserve millisecond precision and
formatting for large years, ensuring consistency with previous Joda behavior.
- Enhanced code readability by converting long concatenated strings to Java
text blocks in LordnLogTest.
- Resolved environmental test failures in SyncRegistrarsSheetTest by
synchronizing the FakeClock with the JPA extension.
- Updated project engineering standards (GEMINI.md) to prefer Truth's
.hasValue() for Optional assertions.
Verified with a clean full build and all relevant test suites passing.
This uses two cursors (one for hosts and one for domains) to track our
progress in "catching up", or syncing recent changes to the database,
using the update-timestamp field. When the cache is in use and fully
caught up, these
cursors should be kept relatively up-to-date to the actual time, i.e.
less than one hour behind
Migrates the massive DomainBase, DomainHistory, and Registrar models to use java.time.Instant natively, removing all deprecated DateTime accessors and fixing their associated JPA converters.
Migrates the Tld entity and its entire JSON/YAML testing ecosystem, including implementing an InstantKeySerializer to preserve millisecond precision in Jackson.
Migrates the entire Epp Flow ecosystem (Create, Update, Delete, Renew, Transfer for Domains/Hosts/Contacts) to use native Instant parameters and operations.
Migrates EppTestCase and EppLifecycleDomainTest to use Instant natively instead of constantly double-wrapping timestamps.
Rebases against upstream and standardizes all Duration and DateTimeUtils static imports across the test suites.
Migrated core EppResource and Token models from Joda-Time DateTime to java.time.Instant.
Specific migrations include:
- `DomainBase` and `Domain`: Migrated `registrationExpirationTime` and various other timestamps to use `Instant` directly.
- `Registrar`: Migrated `lastPocVerificationDate` and certificate dates to `Instant`.
- `BulkPricingPackage`: Migrated `nextBillingDate` and `lastNotificationSent`.
- `AllocationToken`: Migrated `tokenStatusTransitions` map keys to `Instant`.
- `LaunchNotice`: Migrated `acceptedTime` and `expirationTime`.
Updated all associated EPP flows (e.g., DomainCreateFlow, DomainRenewFlow), batch actions (e.g., CheckBulkComplianceAction, DeleteExpiredDomainsAction), command-line tools (e.g., UnrenewDomainCommand, UpdateBulkPricingPackageCommand), and tests to handle `Instant` directly.
Migrated core entity primitives (GracePeriod, RegistryLock, TimeOfYear), transfer objects (BaseTransferObject, DomainTransferData, TransferResponse), and HostBase from Joda-Time DateTime to java.time.Instant as Phases 5 and 7.
Migrated the Billing Ecosystem (BillingBase, BillingEvent, BillingRecurrence, BillingCancellation) and associated Beam pipelines (ExpandBillingRecurrencesPipeline, InvoicingPipeline) to java.time.Instant as Phase 6.
Migrated PollMessage event times and all associated Poll flow utilities (PollAckFlow, PollRequestFlow) to use Instant natively.
Migrated core timestamp tracking on EppResource (creationTime, lastEppUpdateTime, deletionTime) as well as CreateAutoTimestamp and UpdateAutoTimestamp to Instant, shedding deprecated DateTime accessors.
Migrated the entire HistoryEntry reporting ecosystem (HistoryEntry, DomainTransactionRecord, HistoryEntryDao) completely to java.time.Instant.
Updated all associated EPP flows, tools, and testing helpers to handle Instants directly where supported.
We add optional Valkey caching of hosts and domains for future use. Eventually, this will allow us to pre-warm large amounts of data in Valkey for quick retrieval during actions like RDAP.
Note: this doesn't actually use the caches yet.
We use Jedis instead of Redisson for speed purposes
(https://www.instaclustr.com/blog/redis-java-clients-and-client-side-caching/)
which means that we have to implement our own multilayer cache but
that's not the worst thing in the world.
Tested on crash with logging and RDAP code that's not included in this
PR -- it behaves as you'd expect, where the local cache works for
immediate re-lookups and the remote cache works after a restart.
Continues the project-wide migration from Joda-Time's DateTime to java.time.Instant, focusing on Trademark Clearinghouse (TMCH), Signed Mark Data (SMD), and Fee extension models.
Key updates:
- TMCH & SMD: Updated SmdRevocationList and domain check/create flows to use Instant for sunrise validations and revocation checks.
- Fee Extension Ecosystem: Refactored FeeCheckRequest, FeeCreateCommandExtension, and BaseFee to use Instant for effective dates and period calculations.
- EPP Objects: Updated DomainInfoData, TransferResponse, and PollMessage objects to use Instant for event timestamps.
- Pricing Logic: DomainPricingLogic methods now accept Instant for cost calculations.
Additionally, DateTimeUtils was enhanced with Instant compatibility methods for plusMonths and minusMonths to safely handle leap years.
Redundant conversions between DateTime and Instant were eliminated throughout the flows and tests. DomainFlowUtils leverages Instant natively to avoid inline casting, and test assertions now utilize Truth's Instant subjects for cleaner validation.
We no longer need this now that all domain contacts have been successfully
removed in sandbox and production, and additionally, we are removing all
contacts entirely soon enough.
This comprehensive refactor continues the migration from Joda-Time to java.time (Instant), focusing on core timestamp models, transition properties, and their integration across the codebase.
Key changes:
- Migrated CreateAutoTimestamp and UpdateAutoTimestamp to use Instant internally, providing Joda-Time bridge methods for backward compatibility.
- Updated TimedTransitionProperty to handle Instant-based transition maps and updated corresponding Hibernate UserTypes (TimedTransitionBaseUserType).
- Migrated GracePeriod, BillingBase, BillingEvent, PollMessage, and PendingActionNotificationResponse fields (e.g., expirationTime, eventTime) to Instant.
- Migrated additional core entities (DomainBase, Registrar, HostBase, LaunchNotice, BsaLabel, DomainTransactionRecord) to use Instant for registrationExpirationTime, lastTransferTime, creationTime, etc.
- Updated Tld and FeatureFlag models to use Instant for claimsPeriodEnd, bsaEnrollStartTime, and status transitions.
- Enhanced CLI tools and parameters (TransitionListParameter, InstantParameter, RequestParameters) to support Instant-based input and output.
- Updated EntityYamlUtils with custom Instant serializers/deserializers to maintain format consistency (e.g., .SSSZ precision) required for YAML-based tests.
- Implemented UtcInstantAdapter to ensure JAXB XML serialization maintains millisecond accuracy, matching legacy Joda-Time behavior.
- Resolved Hibernate 6 type mismatches in JPQL and Native queries by ensuring consistent use of Instant for comparisons.
- Updated GEMINI.md with project-specific engineering standards, including the 'one commit per PR' mandate, full-build validation requirement, and commit message style rules.
- Cleaned up unnecessary @JsonIgnore and @JsonProperty annotations that were previously added to methods with parameters or redundant fields.
- Refactored DateTimeUtils to use strongly-typed overloads and standardized naming (earliestOf, latestOf) while avoiding type erasure clashes.
- Cleaned up fully qualified calls to toDateTime and toInstant by adding static imports across core model and flow files.
- Refactored test suites to use clock.now() (Instant) instead of nowUtc() (DateTime) and removed custom Truth subjects in favor of standard assertions.
We want to make sure that we use the same XML factories no matter what,
so we use "newDefaultFactory" instead of "newFactory" (to avoid picking
up some random thing on the classpath).
This also fixes an exception that occurs if you haven't synced the
internal repo with the public repo.
PR 2930 forbids adding statuses that already exist on a domain.
This PR updates the uniform_rapid_suspension command to conform.
PR 2930 also forbids removing non-existent statuses, but it does
not apply to this command.
Add the Fee-1.0 schema in production, allowing the requests with this
extension to be parsed. This allows us to test this extension before hand.
The announcement of this extension in greeting is controlled by a
feature flag in ProtocolDefinition.java. As long as it is not announced,
we do not expect real customers to use this extension.
I think this may have been introduced as part of Gradle 9? Not sure why
it's not showing up in the remote builds but without this, I can't run
any "devTool" commands.
Note: the fixes were suggested by gemini-cli
Our existing precision is milliseconds so we want to stick with that for
Instants. If we want to increase the precision globally after that we can do so
all in one go post-migration, but for now, it would be a bad thing to have mixed
precision going on just depending on whether a class happens to be migrated yet
or not.
This PR also migrates all existing DateTime.nowUtc() calls to use the Clock
interface, so that when they are migrated they will get the benefit of this
precision-setting as well.
BUG= http://b/496985355
Error-prone introduced many more checks in Java 25. We fixed a few
and suppressed most. A follow-up bug is opened to clean this up.
An ai agent should be able to clean up most of it.
This PR is created with gemini-cli. Summary of experience:
* The good: AI caught most compatibility issues, and with permission,
suppressed them through compiler flags and errorprone options.
It also caught many versio references in scripts.
* Where it didn't shine:
- It did not find and update the target version spec in the custome
VKey annotation processor source file.
- It did not flag eclipse-temurin:21 docker image for upgrade.
- When running into failure, its first instinct is to disable checks
e.g., -Werror instead of fixing them.
We don't need these, so there's no point in adding database load (but we
leave the option to include them in the future). Note that these are,
and were, only ever included for domains so we don't need to worry about
hosts.
java.time has been around since Java 8 and was based on joda DateTime, so this
is an overdue migration. We're migrating specifically to Instant in most places
rather than ZonedDateTime because we were always using DateTimes in UTC to
reference a specific instant, which is exactly what Instants are
for. ZonedDateTime set to UTC may still be useful in some places that are heavy
on date math (especially in tests).
There is a lot more work to be done after this, but I wanted to put together a
manual PR showing my overall approach for how to do the migration that I can
then hopefully follow along with AI to continue making these changes throughout
the codebase. The basic approach is to migrate a small number of methods at a
time, marking the old methods as @Deprecated when possible (not always possible
because of @InlineMe restrictions). This PR doesn't yet migrate any DateTime
fields in the model classes, so that's the one remaining type of refactor to
figure out after this. We won't be changing how any of the data is actually
stored in the database.
BUG= http://b/496985355
Previously we would just use the first one we found. This is a valid
behavior, but we want to change it so that we apply the cheapest default
if multiple are available (this way we avoid having to go back after the
fact and give refunds).
* More Gradle 9 preparations
Fix additional compatibility warnings after upgrading to Gradle 8.14.3
from 8.13.
* More Gradle 9 compatibility fix
More fixes after upgrading Gradle from 8.13 to 8.14.3.
Upgraded the gradle-license-report plugin, and handled config leaking
issues.
Researched using gemini web and manually applied the fixes. Gemini-cli
could not find the right solution.
This ended up being wayyyy more complicated than expected due to
issues with Hibernate, various dependencies having conflicts with the
proto dependency version, and other breaking changes.
Notes:
- Hibernate 7 switches up the user type / converter system and for us,
this means we must be / want to be more explicit with how we convert
and store things. For example, we need to add Postgres types to @Column
definitions.
- Hibernate 7.3 has an issue with generic MappedSuperclasses -- we have
issues with BaseDomainLabelList. I'll investigate that, but for now
let's stick with 7.2.x
- H7 is more strict with annotations and prevents us from storing mapped
superclasses embedded within other objects. This kinda makes sense but
makes the History objects a bit more difficult. We had to add "concrete"
embeddable DomainBase and HostBase objects that we can store/retrieve
from the DB.
- We convert some of the calls to "Query" to "TypedQuery" -- in
Hibernate 8 / JPA 4.0 these will be super-deprecated and we'll need to
shift everything over, so this is necessary.
- You aren't supposed to put callback listeners on embedded entities
(because it can be not obvious what's happening). We don't like that,
so we add our own annotations that are processed recursively for
embedded entities, so we get things like the update / create
timestamps.
- Hibernate doesn't allow for multiple converters to be auto-applied to
the same "type" and it counts all VKey converters as one type.
Unfortunately, this means we have to explicitly mark each one.
- A bunch of other dependency changes were required to keep from having
the proto 3/4 conflict
Previously we omit the fee class in responses if the class is standard.
After a rereading of Section 3.7 of RFC 8748, we determined that the fee
class element should be included in all cases.
Note: the `collison` class now becomes `standard-collision`.
Refactor Gradle scripts to replace usages incompatible with Gradle 9.
PR prepared mostly with gemini-cli, with one issue (project.exec)
researched with gemini web and manually applied.
The actual upgrade to Gradle 9 will be in another PR.
Verified: none of the issues reported in build/reports/problems/problems-report.html
is related to Gradle 9.
PR 2917 added two `get(tld)` methods to ClaimsListDao and
SignedMarkRevocationList so that RST test TLDs can have separate claims
and smdr lists.
RST tests are completed and this functionality is no longer needed. we
are replaceing all invocations of the above to `get()`.
The JDK version of SSL has long supported TLS v1.3 (since version 11) so
fortunately we can use TLS v1.3 regardless if which implementation of
SSL we're using.
We prefer OpenSSL in general so I'm not entirely sure why we were using
the JDK version of SSL on the proxy before, but this should work and be
a good idea regardless.
Tested on alpha by running
```
$ openssl s_client -connect epp.registryalpha.foo:700 -tls1_3 -ciphersuites "TLS_AES_128_GCM_SHA256"
```
Previously we'd get a failure, now it returns the proper cert data.