Skip to content

Migrate EPP XML generation from Soy to JAXB and emails to FreeMarker#3038

Merged
CydeWeys merged 1 commit into
google:masterfrom
CydeWeys:freemarker
May 22, 2026
Merged

Migrate EPP XML generation from Soy to JAXB and emails to FreeMarker#3038
CydeWeys merged 1 commit into
google:masterfrom
CydeWeys:freemarker

Conversation

@CydeWeys
Copy link
Copy Markdown
Member

@CydeWeys CydeWeys commented May 8, 2026

This CL eliminates the deprecated Closure Template (Soy) engine from the Nomulus codebase.

Key changes:

  • Migrated all EPP tool commands (CreateDomain, UpdateDomain, etc.) from Soy templates to type-safe JAXB models using EppInput.
  • Migrated Spec11 emails to Apache FreeMarker using a new TemplateRenderer utility.
  • Updated EppInput and related models to support all necessary extensions (Fee, SecDNS, Metadata, AllocationToken, etc.).
  • Refactored DsRecord to remove Soy dependencies.
  • Updated tool test data XML files to match JAXB output (standardizing headers, removing redundant lang="en" attributes, and using self-closing tags).
  • Removed Soy dependencies and associated Gradle tasks from the build system.
  • Consolidated EPP exception classes to improve code health and remove circular dependencies.

Verified with ./gradlew :core:test and specialized tool command tests.


This change is Reviewable

@CydeWeys CydeWeys force-pushed the freemarker branch 4 times, most recently from 1268bcc to d9d1130 Compare May 11, 2026 14:37
Comment thread core/src/main/java/google/registry/model/domain/secdns/SecDnsUpdateExtension.java Dismissed
Comment thread core/src/main/java/google/registry/model/eppinput/ResourceCommand.java Dismissed
@CydeWeys CydeWeys force-pushed the freemarker branch 3 times, most recently from dcec4a2 to 9258e15 Compare May 11, 2026 19:17
Comment thread dependencies.gradle Outdated
'com.google.template:soy:[2024-02-26,)',
'com.google.truth:truth:[1.1.2,)',
'com.googlecode.json-simple:json-simple:[1.1.1,)',
'org.freemarker:freemarker:2.3.32',
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't lock this to this specific revision. Use the open-ended [ ) syntax.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Comment thread README.md Outdated
and is written primarily in Java. It is the software that
[Google Registry](https://www.registry.google/) uses to operate TLDs such as .google,
.app, .how, .soy, and .みんな. It can run any number of TLDs in a single shared registry
.app, .how, and .みんな. It can run any number of TLDs in a single shared registry
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did this change?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@CydeWeys CydeWeys force-pushed the freemarker branch 2 times, most recently from 5f0a007 to 0b20767 Compare May 12, 2026 01:49
Comment thread core/src/main/java/google/registry/model/domain/DomainCommand.java Dismissed
Comment thread core/src/main/java/google/registry/model/host/HostCommand.java Dismissed
@CydeWeys CydeWeys force-pushed the freemarker branch 3 times, most recently from a4a0fc1 to cd82ada Compare May 12, 2026 15:22
Comment thread core/src/main/java/google/registry/model/domain/DomainCommand.java Dismissed
Comment thread core/src/main/java/google/registry/model/host/HostCommand.java Dismissed
Copy link
Copy Markdown
Collaborator

@weiminyu weiminyu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@weiminyu reviewed 58 files and made 1 comment.
Reviewable status: 58 of 104 files reviewed, 10 unresolved discussions (waiting on CydeWeys).


common/src/main/java/google/registry/util/TemplateRenderer.java line 57 at r5 (raw file):

   * @throws RuntimeException if the template cannot be found, parsed, or processed
   */
  public String render(String templatePath, ImmutableMap<String, Object> dataModel) {

If template variables and dataModel map keys do not match, missing or unused data keys, will the render throw an error?

Copy link
Copy Markdown
Member Author

@CydeWeys CydeWeys left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@CydeWeys made 2 comments and resolved 2 discussions.
Reviewable status: 58 of 104 files reviewed, 8 unresolved discussions (waiting on weiminyu).

Comment thread dependencies.gradle Outdated
'com.google.template:soy:[2024-02-26,)',
'com.google.truth:truth:[1.1.2,)',
'com.googlecode.json-simple:json-simple:[1.1.1,)',
'org.freemarker:freemarker:2.3.32',
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Comment thread README.md Outdated
and is written primarily in Java. It is the software that
[Google Registry](https://www.registry.google/) uses to operate TLDs such as .google,
.app, .how, .soy, and .みんな. It can run any number of TLDs in a single shared registry
.app, .how, and .みんな. It can run any number of TLDs in a single shared registry
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@CydeWeys
Copy link
Copy Markdown
Member Author

Yes, FreeMarker strictly throws an exception for missing variables. Unused variables in the data model are safely ignored. I have added explicit tests for both of these behaviors in TemplateRendererTest.java.

Copy link
Copy Markdown

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Attention Required: Lockfile Detected

This pull request contains modifications to one or more *.lockfile files. Please confirm that you have run update_dependency.sh to push new dependencies to the private repo.

Someone with Admin role must manually dismiss this review before merging.

Comment thread core/src/main/java/google/registry/model/domain/DomainCommand.java Dismissed
@XmlRootElement
public static class Create extends HostCreateOrChange
implements ResourceCreateOrChange<Host.Builder> {
public static class Create extends HostCreateOrChange {
Comment thread core/src/main/java/google/registry/model/host/HostCommand.java Dismissed
Comment thread core/src/main/java/google/registry/model/host/HostCommand.java Dismissed
Copy link
Copy Markdown
Member Author

@CydeWeys CydeWeys left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@CydeWeys made 1 comment.
Reviewable status: 19 of 114 files reviewed, 11 unresolved discussions (waiting on weiminyu).


common/src/main/java/google/registry/util/TemplateRenderer.java line 57 at r5 (raw file):

Previously, weiminyu (Weimin Yu) wrote…

If template variables and dataModel map keys do not match, missing or unused data keys, will the render throw an error?

Yes, and added a test.

Copy link
Copy Markdown

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Attention Required: Lockfile Detected

This pull request contains modifications to one or more *.lockfile files. Please confirm that you have run update_dependency.sh to push new dependencies to the private repo.

Someone with Admin role must manually dismiss this review before merging.

@CydeWeys
Copy link
Copy Markdown
Member Author

PTAL

- Replace deprecated Soy templates for EPP XML with JAXB models and a refined Fluent DSL.
- Migrate Spec11 and administrative emails to FreeMarker with HTML auto-escaping.
- Remove Soy compiler, Gradle tasks, and library dependencies.
- Address PR feedback regarding shadowing, version locking, and security warnings.
- Enhance tests with comprehensive XML equality assertions using Java 15 text blocks.
- Improve Javadocs and maintain strict temporal consistency using java.time.

FreeMarker replaces Soy for email templating, providing native HTML auto-escaping and allowing the removal of the complex 'soyToJava' compilation step from the build process. This significantly simplifies the build system and reduces maintenance overhead. For EPP XML, migrating to JAXB allows tool-generated commands to use the same model classes as the server-side EPP flows. This ensures that tool-generated XML is always schema-compliant and eliminates the risk of divergence between tool templates and actual server-side implementation. This unified approach provides compile-time type safety and improves developer ergonomics via a refined fluent DSL.

The base ImmutableObject class now provides a public clone() override that correctly resets the cached hashCode to null. This centralizes the custom cloning logic previously handled by a static helper and ensures that all subclasses—including the newly added JAXB models—satisfy CodeQL security requirements without needing redundant per-class overrides. The legacy static clone(T) helper has been updated to delegate to this instance method to maintain compatibility and architectural consistency.
Copy link
Copy Markdown

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Attention Required: Lockfile Detected

This pull request contains modifications to one or more *.lockfile files. Please confirm that you have run update_dependency.sh to push new dependencies to the private repo.

Someone with Admin role must manually dismiss this review before merging.

Copy link
Copy Markdown
Collaborator

@weiminyu weiminyu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@weiminyu reviewed 100 files and all commit messages, and resolved 1 discussion.
Reviewable status: all files reviewed, 10 unresolved discussions (waiting on CydeWeys).

Copy link
Copy Markdown
Collaborator

@weiminyu weiminyu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:lgtm:

@weiminyu made 1 comment.
Reviewable status: all files reviewed, 10 unresolved discussions (waiting on CydeWeys).

@weiminyu weiminyu dismissed github-actions[bot]’s stale review May 22, 2026 19:33

Update_dependency ran out of band.

@CydeWeys CydeWeys added this pull request to the merge queue May 22, 2026
Merged via the queue into google:master with commit 53b92d6 May 22, 2026
13 of 15 checks passed
@CydeWeys CydeWeys deleted the freemarker branch May 22, 2026 20:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants