Skip to content

Commit 0789eec

Browse files
committed
Update the fee extension 1.0 and add some tests
Many of the actual fee extension changes are based off Weimin's PR google#2912, though this makes some additional changes based on the XML schema and description from RFC 8748. This adds tests for the DomainCheckFlow which is the most complex and thorough user of the fee extension, but we'll want to add further tests to the other domain flows to make sure they're handled correctly.
1 parent 4018468 commit 0789eec

36 files changed

Lines changed: 1422 additions & 223 deletions

File tree

core/src/main/java/google/registry/model/domain/feestdv1/FeeCheckCommandExtensionItemStdV1.java

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
import google.registry.model.domain.Period;
1919
import google.registry.model.domain.fee.FeeCheckCommandExtensionItem;
2020
import jakarta.xml.bind.annotation.XmlAttribute;
21-
import jakarta.xml.bind.annotation.XmlElement;
2221
import jakarta.xml.bind.annotation.XmlType;
2322
import java.util.Locale;
2423
import java.util.Optional;
@@ -32,12 +31,13 @@
3231
* <pre>{@code
3332
* <fee:command name="renew" phase="sunrise" subphase="hello">
3433
* <fee:period unit="y">1</fee:period>
35-
* <fee:class>premium</fee:class>
36-
* <fee:date>2017-05-17T13:22:21.0Z</fee:date>
3734
* </fee:command>
3835
* }</pre>
36+
*
37+
* <p>The `feeClass` and `feeDate` attributes that are present in version 0.12 are removed from this
38+
* version.
3939
*/
40-
@XmlType(propOrder = {"period", "feeClass", "feeDate"})
40+
@XmlType(propOrder = {"period"})
4141
public class FeeCheckCommandExtensionItemStdV1 extends FeeCheckCommandExtensionItem {
4242

4343
/** The default validity period (if not specified) is 1 year for all operations. */
@@ -50,12 +50,6 @@ public class FeeCheckCommandExtensionItemStdV1 extends FeeCheckCommandExtensionI
5050

5151
@XmlAttribute String subphase;
5252

53-
@XmlElement(name = "class")
54-
String feeClass;
55-
56-
@XmlElement(name = "date")
57-
DateTime feeDate;
58-
5953
/** Version 1.0 does not support domain name or currency in fee extension items. */
6054
@Override
6155
public boolean isDomainNameSupported() {
@@ -107,6 +101,6 @@ public FeeCheckResponseExtensionItemStdV1.Builder createResponseBuilder() {
107101

108102
@Override
109103
public Optional<DateTime> getEffectiveDate() {
110-
return Optional.ofNullable(feeDate);
104+
return Optional.empty();
111105
}
112106
}

core/src/main/java/google/registry/model/domain/feestdv1/FeeCheckCommandExtensionStdV1.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ public FeeCheckResponseExtensionStdV1 createResponse(
7676
}
7777

7878
/** Domains across multiple currencies cannot be checked simultaneously. */
79-
static class MultipleCurrenciesCannotBeCheckedException
79+
public static class MultipleCurrenciesCannotBeCheckedException
8080
extends ParameterValuePolicyErrorException {
8181
public MultipleCurrenciesCannotBeCheckedException() {
8282
// The fee extension 1.0 only supports one currency shared across all results

core/src/main/java/google/registry/model/domain/feestdv1/FeeCheckResponseExtensionItemCommandStdV1.java

Lines changed: 1 addition & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,11 @@
2424
import google.registry.model.domain.fee.Fee;
2525
import google.registry.model.domain.fee.FeeQueryCommandExtensionItem.CommandName;
2626
import jakarta.xml.bind.annotation.XmlAttribute;
27-
import jakarta.xml.bind.annotation.XmlElement;
2827
import jakarta.xml.bind.annotation.XmlType;
2928
import java.util.List;
30-
import org.joda.time.DateTime;
3129

3230
/** The version 1.0 response command entity for a domain check on a single resource. */
33-
@XmlType(propOrder = {"period", "fee", "effectiveDate", "notAfterDate"})
31+
@XmlType(propOrder = {"period", "fee"})
3432
public class FeeCheckResponseExtensionItemCommandStdV1 extends ImmutableObject {
3533

3634
/** The command that was checked. */
@@ -53,14 +51,6 @@ public class FeeCheckResponseExtensionItemCommandStdV1 extends ImmutableObject {
5351
*/
5452
List<Fee> fee;
5553

56-
/** The effective date that the check is to be performed on (if specified in the query). */
57-
@XmlElement(name = "date")
58-
DateTime effectiveDate;
59-
60-
/** The date after which the quoted fee is no longer valid (if applicable). */
61-
@XmlElement(name = "notAfter")
62-
DateTime notAfterDate;
63-
6454
/** Builder for {@link FeeCheckResponseExtensionItemCommandStdV1}. */
6555
public static class Builder extends Buildable.Builder<FeeCheckResponseExtensionItemCommandStdV1> {
6656

@@ -84,16 +74,6 @@ public Builder setPeriod(Period period) {
8474
return this;
8575
}
8676

87-
public Builder setEffectiveDate(DateTime effectiveDate) {
88-
getInstance().effectiveDate = effectiveDate;
89-
return this;
90-
}
91-
92-
public Builder setNotAfterDate(DateTime notAfterDate) {
93-
getInstance().notAfterDate = notAfterDate;
94-
return this;
95-
}
96-
9777
public Builder setFee(List<Fee> fees) {
9878
getInstance().fee = forceEmptyToNull(ImmutableList.copyOf(fees));
9979
return this;

core/src/main/java/google/registry/model/domain/feestdv1/FeeCheckResponseExtensionItemStdV1.java

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -17,20 +17,18 @@
1717
import static google.registry.util.CollectionUtils.forceEmptyToNull;
1818

1919
import com.google.common.collect.ImmutableList;
20-
import google.registry.model.domain.DomainObjectSpec;
2120
import google.registry.model.domain.Period;
2221
import google.registry.model.domain.fee.Fee;
2322
import google.registry.model.domain.fee.FeeCheckResponseExtensionItem;
2423
import google.registry.model.domain.fee.FeeQueryCommandExtensionItem.CommandName;
2524
import jakarta.xml.bind.annotation.XmlType;
26-
import org.joda.time.DateTime;
2725

2826
/** The version 1.0 response for a domain check on a single resource. */
29-
@XmlType(propOrder = {"object", "feeClass", "command"})
27+
@XmlType(propOrder = {"objID", "feeClass", "command"})
3028
public class FeeCheckResponseExtensionItemStdV1 extends FeeCheckResponseExtensionItem {
3129

3230
/** The domain that was checked. */
33-
DomainObjectSpec object;
31+
String objID;
3432

3533
/** The command that was checked. */
3634
FeeCheckResponseExtensionItemCommandStdV1 command;
@@ -88,7 +86,7 @@ public Builder setClass(String feeClass) {
8886

8987
@Override
9088
public Builder setDomainNameIfSupported(String name) {
91-
getInstance().object = new DomainObjectSpec(name);
89+
getInstance().objID = name;
9290
return this;
9391
}
9492

@@ -97,17 +95,5 @@ public FeeCheckResponseExtensionItemStdV1 build() {
9795
getInstance().command = commandBuilder.build();
9896
return super.build();
9997
}
100-
101-
@Override
102-
public Builder setEffectiveDateIfSupported(DateTime effectiveDate) {
103-
commandBuilder.setEffectiveDate(effectiveDate);
104-
return this;
105-
}
106-
107-
@Override
108-
public Builder setNotAfterDateIfSupported(DateTime notAfterDate) {
109-
commandBuilder.setNotAfterDate(notAfterDate);
110-
return this;
111-
}
11298
}
11399
}

core/src/main/java/google/registry/model/eppcommon/ProtocolDefinition.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ public enum ServiceExtension {
5656
FEE_0_6(FeeCheckCommandExtensionV06.class, FeeCheckResponseExtensionV06.class, true),
5757
FEE_0_11(FeeCheckCommandExtensionV11.class, FeeCheckResponseExtensionV11.class, true),
5858
FEE_0_12(FeeCheckCommandExtensionV12.class, FeeCheckResponseExtensionV12.class, true),
59-
FEE_1_00(FeeCheckCommandExtensionStdV1.class, FeeCheckResponseExtensionStdV1.class, false),
59+
FEE_1_00(FeeCheckCommandExtensionStdV1.class, FeeCheckResponseExtensionStdV1.class, true),
6060
METADATA_1_0(MetadataExtension.class, null, false);
6161

6262
private final Class<? extends CommandExtension> commandExtensionClass;

core/src/main/java/google/registry/xml/xsd/fee-std-v1.xsd

Lines changed: 63 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
<element name="renew" type="fee:transformCommandType" />
2424
<element name="renData" type="fee:transformResultType" />
2525
<element name="transfer" type="fee:transformCommandType" />
26-
<element name="trnData" type="fee:transferResultType" />
26+
<element name="trnData" type="fee:transformResultType" />
2727
<element name="update" type="fee:transformCommandType" />
2828
<element name="updData" type="fee:transformResultType" />
2929
<element name="delData" type="fee:transformResultType" />
@@ -33,78 +33,38 @@
3333
<sequence>
3434
<element name="currency" type="fee:currencyType"
3535
minOccurs="0" />
36-
<element name="command" type="fee:commandCheckType"
37-
maxOccurs="unbounded" />
36+
<element name="command" type="fee:commandType"
37+
minOccurs="1" maxOccurs="unbounded" />
3838
</sequence>
3939
</complexType>
4040

41-
<complexType name="commandCheckType">
42-
<sequence>
43-
<element name="period"
44-
type="domain:periodType"
45-
minOccurs="0" />
46-
<element name="class"
47-
type="token"
48-
minOccurs="0" />
49-
<element name="date"
50-
type="dateTime"
51-
minOccurs="0" />
52-
</sequence>
53-
<attribute name="name" type="fee:commandTypeValue" />
54-
<attribute name="phase" type="token" />
55-
<attribute name="subphase" type="token" />
41+
<complexType name="objectIdentifierType">
42+
<simpleContent>
43+
<extension base="eppcom:labelType">
44+
<attribute name="element"
45+
type="NMTOKEN" default="name" />
46+
</extension>
47+
</simpleContent>
5648
</complexType>
5749

5850
<!-- server <check> result -->
5951
<complexType name="chkDataType">
6052
<sequence>
61-
<element name="currency" type="fee:currencyType" minOccurs="0"/>
53+
<element name="currency" type="fee:currencyType" />
6254
<element name="cd" type="fee:objectCDType"
6355
maxOccurs="unbounded" />
6456
</sequence>
6557
</complexType>
6658

6759
<complexType name="objectCDType">
6860
<sequence>
69-
<element name="object">
70-
<complexType>
71-
<sequence>
72-
<any namespace="##other" processContents="lax"/>
73-
</sequence>
74-
</complexType>
75-
</element>
61+
<element name="objID" type="fee:objectIdentifierType" />
7662
<element name="class" type="token" minOccurs="0" />
77-
<element name="command"
78-
type="fee:commandCDType"
79-
maxOccurs="unbounded" />
80-
</sequence>
81-
</complexType>
82-
83-
<complexType name="commandCDType">
84-
<sequence>
85-
<element name="period"
86-
type="domain:periodType"
87-
minOccurs="0" maxOccurs="1" />
88-
<element name="fee"
89-
type="fee:feeType"
90-
minOccurs="0" maxOccurs="unbounded" />
91-
<element name="credit"
92-
type="fee:creditType"
63+
<element name="command" type="fee:commandDataType"
9364
minOccurs="0" maxOccurs="unbounded" />
94-
<element name="reason"
95-
type="token"
96-
minOccurs="0" />
97-
<element name="date"
98-
type="dateTime"
99-
minOccurs="0" />
100-
<element name="notAfter"
101-
type="dateTime"
102-
minOccurs="0" />
65+
<element name="reason" type="fee:reasonType" minOccurs="0" />
10366
</sequence>
10467
<attribute name="avail" type="boolean" default="1" />
105-
<attribute name="name" type="fee:commandTypeValue" />
106-
<attribute name="phase" type="token" />
107-
<attribute name="subphase" type="token" />
10868
</complexType>
10969

11070
<!-- general transform (create, renew, update, transfer) command-->
@@ -119,32 +79,15 @@
11979
</sequence>
12080
</complexType>
12181

122-
<!-- general transform (create, renew, update, delete) result -->
82+
<!-- general transform (create, renew, update) result -->
12383
<complexType name="transformResultType">
12484
<sequence>
125-
<element name="currency" type="fee:currencyType" />
126-
<element name="fee" type="fee:feeType"
127-
minOccurs="0" maxOccurs="unbounded" />
128-
<element name="credit" type="fee:creditType"
129-
minOccurs="0" maxOccurs="unbounded" />
130-
<element name="balance" type="fee:balanceType"
131-
minOccurs="0" />
132-
<element name="creditLimit" type="fee:creditLimitType"
85+
<element name="currency" type="fee:currencyType"
13386
minOccurs="0" />
134-
</sequence>
135-
</complexType>
136-
137-
<!-- transfer result -->
138-
<complexType name="transferResultType">
139-
<sequence>
140-
<element name="currency" type="fee:currencyType" />
141-
142-
<!-- only used op="query" responses -->
14387
<element name="period" type="domain:periodType"
14488
minOccurs="0" />
145-
14689
<element name="fee" type="fee:feeType"
147-
maxOccurs="unbounded" />
90+
minOccurs="0" maxOccurs="unbounded" />
14891
<element name="credit" type="fee:creditType"
14992
minOccurs="0" maxOccurs="unbounded" />
15093
<element name="balance" type="fee:balanceType"
@@ -161,10 +104,50 @@
161104
</restriction>
162105
</simpleType>
163106

164-
<simpleType name="commandTypeValue">
107+
<complexType name="commandType">
108+
<sequence>
109+
<element name="period" type="domain:periodType"
110+
minOccurs="0" maxOccurs="1" />
111+
</sequence>
112+
<attribute name="name" type="fee:commandEnum" use="required"/>
113+
<attribute name="customName" type="token"/>
114+
<attribute name="phase" type="token" />
115+
<attribute name="subphase" type="token" />
116+
</complexType>
117+
118+
<complexType name="commandDataType">
119+
<complexContent>
120+
<extension base="fee:commandType">
121+
<sequence>
122+
<element name="fee" type="fee:feeType"
123+
minOccurs="0" maxOccurs="unbounded" />
124+
<element name="credit" type="fee:creditType"
125+
minOccurs="0" maxOccurs="unbounded" />
126+
<element name="reason" type="fee:reasonType"
127+
minOccurs="0" />
128+
</sequence>
129+
<attribute name="standard" type="boolean" default="0" />
130+
</extension>
131+
</complexContent>
132+
</complexType>
133+
134+
<complexType name="reasonType">
135+
<simpleContent>
136+
<extension base="token">
137+
<attribute name="lang" type="language" default="en"/>
138+
</extension>
139+
</simpleContent>
140+
</complexType>
141+
142+
<simpleType name="commandEnum">
165143
<restriction base="token">
166-
<minLength value="3"/>
167-
<maxLength value="16"/>
144+
<enumeration value="create"/>
145+
<enumeration value="delete"/>
146+
<enumeration value="renew"/>
147+
<enumeration value="update"/>
148+
<enumeration value="transfer"/>
149+
<enumeration value="restore"/>
150+
<enumeration value="custom"/>
168151
</restriction>
169152
</simpleType>
170153

@@ -184,9 +167,10 @@
184167
<simpleContent>
185168
<extension base="fee:nonNegativeDecimal">
186169
<attribute name="description"/>
170+
<attribute name="lang" type="language" default="en"/>
187171
<attribute name="refundable" type="boolean" />
188172
<attribute name="grace-period" type="duration" />
189-
<attribute name="applied" default="immediate">
173+
<attribute name="applied">
190174
<simpleType>
191175
<restriction base="token">
192176
<enumeration value="immediate" />
@@ -202,6 +186,7 @@
202186
<simpleContent>
203187
<extension base="fee:negativeDecimal">
204188
<attribute name="description"/>
189+
<attribute name="lang" type="language" default="en"/>
205190
</extension>
206191
</simpleContent>
207192
</complexType>

core/src/test/java/google/registry/flows/FlowTestCase.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
import google.registry.flows.picker.FlowPicker;
3737
import google.registry.model.billing.BillingBase;
3838
import google.registry.model.domain.GracePeriod;
39+
import google.registry.model.eppcommon.EppXmlTransformer;
3940
import google.registry.model.eppcommon.ProtocolDefinition;
4041
import google.registry.model.eppinput.EppInput;
4142
import google.registry.model.eppoutput.EppOutput;
@@ -289,6 +290,8 @@ public EppOutput runFlowAssertResponse(
289290
if (output.isResponse()) {
290291
assertThat(output.isSuccess()).isTrue();
291292
}
293+
// Verify that expected xml is syntatically correct.
294+
EppXmlTransformer.validateOutput(xml);
292295
try {
293296
assertXmlEquals(
294297
xml, new String(marshal(output, ValidationMode.STRICT), UTF_8), ignoredPathsPlusTrid);

0 commit comments

Comments
 (0)