Skip to content

Conversation

@weiminyu
Copy link
Collaborator

@weiminyu weiminyu commented Feb 3, 2026

Nomulus currently supports multiple versions of the Fee extensions. Our current tooling requires that each version must use a unique namespace tag, e.g., fee11, fee12, etc.

Some client registrars are sensitive to the tag literal used by the version of the extension they use. For example, a few registrars currently using v0.6 have requested that the fee literal be used on the versions they currently use. With registrars upgrading at their own schedule, this kind of requests are impossible to satisfy.

This PR instroduces a namespace normalizer class for EPP responses. The key optimization is that each EPP response never mixes multiple versions of a service extension. Therefore we can define a canonical tag for each extension, and change the tag of the extension in use in a response to that. This normalizer only handles Fee extensions right now, but the idea can be extended to others if use cases come up.

This normalizer will be applied to all flows in a future PR.

See b/478848482


This change is Reviewable

@weiminyu weiminyu requested review from CydeWeys and gbrodman February 3, 2026 16:57
@weiminyu weiminyu force-pushed the epp-namespace-norm branch 2 times, most recently from 168443b to d1f9e95 Compare February 3, 2026 18:25
Copy link
Collaborator Author

@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 resolved 2 discussions.
Reviewable status: 0 of 10 files reviewed, all discussions resolved (waiting on @CydeWeys and @gbrodman).

Copy link
Member

@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.
Reviewable status: 0 of 10 files reviewed, 2 unresolved discussions (waiting on @gbrodman and @weiminyu).


core/src/main/java/google/registry/flows/FeeExtensionXmlTagNormalizer.java line 55 at r2 (raw file):

 *
 * <p>Some registrars are not XML namespace-aware and rely on the XML tags being specific literals.
 * This makes it impossible to perform seamless rollout of new versions. Nomulus and the all

Grammar error here


core/src/main/java/google/registry/flows/FeeExtensionXmlTagNormalizer.java line 63 at r2 (raw file):

 * versions from the message, thus freeing up the canonical tag ('fee') for the active version.
 */
public class FeeExtensionXmlTagNormalizer {

What are the performance implications of this approach? This is running a nontrivial amount of XML parsing code for each command response we return, right?

Copy link
Collaborator Author

@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 made 2 comments.
Reviewable status: 0 of 13 files reviewed, 2 unresolved discussions (waiting on @CydeWeys and @gbrodman).


core/src/main/java/google/registry/flows/FeeExtensionXmlTagNormalizer.java line 55 at r2 (raw file):

Previously, CydeWeys (Ben McIlwain) wrote…

Grammar error here

Done.


core/src/main/java/google/registry/flows/FeeExtensionXmlTagNormalizer.java line 63 at r2 (raw file):

Previously, CydeWeys (Ben McIlwain) wrote…

What are the performance implications of this approach? This is running a nontrivial amount of XML parsing code for each command response we return, right?

This is on par with the XmlSanitier that masks passwords: actions range between a few milliseconds to 10s of milliseconds.

Since the input is produced by our EppXmlTransformer, we know the format and can use regex. Rewrote it and processing is pretty consistent at 1 - 2 milliseconds per call, and it scales well with larger messages.

Copy link
Collaborator Author

@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 made 1 comment.
Reviewable status: 0 of 13 files reviewed, 3 unresolved discussions (waiting on @CydeWeys and @gbrodman).

Copy link
Collaborator Author

@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 resolved 1 discussion.
Reviewable status: 0 of 13 files reviewed, 2 unresolved discussions (waiting on @CydeWeys and @gbrodman).

Nomulus currently supports multiple versions of the Fee extensions. Our
current tooling requires that each version must use a unique namespace
tag, e.g., fee11, fee12, etc.

Some client registrars are sensitive to the tag literal used by the
version of the extension they use. For example, a few registrars
currently using v0.6 have requested that the `fee` literal be used
on the versions they currently use. With registrars upgrading at their
own schedule, this kind of requests are impossible to satisfy.

This PR instroduces a namespace normalizer class for EPP responses. The
key optimization is that each EPP response never mixes multiple versions
of a service extension. Therefore we can define a canonical tag for each
extension, and change the tag of the extension in use in a response to
that. This normalizer only handles Fee extensions right now, but the
idea can be extended to others if use cases come up.

This normalizer will be applied to all flows in a future PR.
Copy link
Member

@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 resolved 2 discussions.
Reviewable status: 0 of 13 files reviewed, all discussions resolved (waiting on @gbrodman).

@weiminyu weiminyu requested a review from CydeWeys February 11, 2026 20:15
Copy link
Member

@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: 0 of 13 files reviewed, 1 unresolved discussion (waiting on @gbrodman and @weiminyu).


core/src/main/java/google/registry/flows/FeeExtensionXmlTagNormalizer.java line 76 at r4 (raw file):

   * than XML stream parsers.
   */
  public static String normalize(String xml) {

Is this being called on every single XML response we're returning? If so, is there an easy way to only call it when we know the fee extension is already in use? Inside the relevant flows they definitely know when the fee extension is being used at least (and also, which version).

Copy link
Member

@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: 0 of 13 files reviewed, 1 unresolved discussion (waiting on @gbrodman and @weiminyu).


core/src/main/java/google/registry/flows/FeeExtensionXmlTagNormalizer.java line 76 at r4 (raw file):

Previously, CydeWeys (Ben McIlwain) wrote…

Is this being called on every single XML response we're returning? If so, is there an easy way to only call it when we know the fee extension is already in use? Inside the relevant flows they definitely know when the fee extension is being used at least (and also, which version).

And also, this definitely never needs to be called on host flows; is it?

Copy link
Collaborator Author

@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 made 1 comment.
Reviewable status: 0 of 13 files reviewed, 1 unresolved discussion (waiting on @CydeWeys and @gbrodman).


core/src/main/java/google/registry/flows/FeeExtensionXmlTagNormalizer.java line 76 at r4 (raw file):

Previously, CydeWeys (Ben McIlwain) wrote…

And also, this definitely never needs to be called on host flows; is it?

Yeah, Host flows don't need them. And we can make sure this is only applied to responses that include fee extensions.

On the other hand, it is takes just a simple pattern match to discover if fee extension is in use in a response. The cost is tiny when compared with marshalling.

Copy link
Member

@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 reviewed 13 files and all commit messages, and resolved 1 discussion.
Reviewable status: :shipit: complete! all files reviewed, all discussions resolved (waiting on @gbrodman).

@weiminyu weiminyu enabled auto-merge February 11, 2026 20:58
@weiminyu weiminyu added this pull request to the merge queue Feb 11, 2026
Merged via the queue into google:master with commit a787660 Feb 11, 2026
10 checks passed
@weiminyu weiminyu deleted the epp-namespace-norm branch February 11, 2026 22:10
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.

2 participants