Update WHOIS output format to reflect CL&D and PDT requirements

PDT testing revealed a couple ways in which our WHOIS output was non-compliant. First, the Consistent Labeling & Display policy dictates that the contact IDs must be ROIDs. See rule 11 in https://www.icann.org/resources/pages/rdds-labeling-policy-2017-02-01-en. Second, PDT tests expect that a WHOIS response will treat missing values either by omitting the line entirely, or by including the line with a blank value, but not both. So this is legal:

Phone Number: 123-4567
Phone Number Ext:
Fax Number: 123-4568
Fax Number Ext:

and this is legal:

Phone Number: 123-4567
Fax Number: 123-4568

but this is not:

Phone Number: 123-4567
Phone Number Ext:
Fax Number: 123-4568

In the last example, one extension line is present with a blank value, while the other extension line is omitted. We cannot do both. Therefore, we should update our code to omit lines with no value. Since we can't guarantee that we will always emit all lines that the parse might expect to see, it is safe to use the policy of omitting lines with no value.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=158184150
This commit is contained in:
mountford 2017-06-06 13:48:43 -07:00 committed by Ben McIlwain
parent ae039aa0d8
commit e8eabe01cf
6 changed files with 47 additions and 48 deletions

View file

@ -23,6 +23,7 @@ import static google.registry.xml.UtcDateTimeAdapter.getFormattedString;
import com.google.common.base.Function; import com.google.common.base.Function;
import com.google.common.base.Optional; import com.google.common.base.Optional;
import com.google.common.base.Predicate; import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables; import com.google.common.collect.Iterables;
import com.googlecode.objectify.Key; import com.googlecode.objectify.Key;
@ -88,7 +89,7 @@ final class DomainWhoisResponse extends WhoisResponseImpl {
.emitField("Registry Domain ID", domain.getRepoId()) .emitField("Registry Domain ID", domain.getRepoId())
.emitField("Registrar WHOIS Server", registrar.getWhoisServer()) .emitField("Registrar WHOIS Server", registrar.getWhoisServer())
.emitField("Registrar URL", registrar.getReferralUrl()) .emitField("Registrar URL", registrar.getReferralUrl())
.emitField("Updated Date", getFormattedString(domain.getLastEppUpdateTime())) .emitFieldIfDefined("Updated Date", getFormattedString(domain.getLastEppUpdateTime()))
.emitField("Creation Date", getFormattedString(domain.getCreationTime())) .emitField("Creation Date", getFormattedString(domain.getCreationTime()))
.emitField( .emitField(
"Registry Expiry Date", getFormattedString(domain.getRegistrationExpirationTime())) "Registry Expiry Date", getFormattedString(domain.getRegistrationExpirationTime()))
@ -98,10 +99,10 @@ final class DomainWhoisResponse extends WhoisResponseImpl {
Objects.toString(registrar.getIanaIdentifier(), "")) Objects.toString(registrar.getIanaIdentifier(), ""))
// Email address is a required field for registrar contacts. Therefore as long as there // Email address is a required field for registrar contacts. Therefore as long as there
// is an abuse contact, we can get an email address from it. // is an abuse contact, we can get an email address from it.
.emitField( .emitFieldIfDefined(
"Registrar Abuse Contact Email", "Registrar Abuse Contact Email",
abuseContact.isPresent() ? abuseContact.get().getEmailAddress() : null) abuseContact.isPresent() ? abuseContact.get().getEmailAddress() : null)
.emitField( .emitFieldIfDefined(
"Registrar Abuse Contact Phone", "Registrar Abuse Contact Phone",
abuseContact.isPresent() ? abuseContact.get().getPhoneNumber() : null) abuseContact.isPresent() ? abuseContact.get().getPhoneNumber() : null)
.emitStatusValues(domain.getStatusValues(), domain.getGracePeriods()) .emitStatusValues(domain.getStatusValues(), domain.getGracePeriods())
@ -144,10 +145,12 @@ final class DomainWhoisResponse extends WhoisResponseImpl {
class DomainEmitter extends Emitter<DomainEmitter> { class DomainEmitter extends Emitter<DomainEmitter> {
DomainEmitter emitPhone( DomainEmitter emitPhone(
String contactType, String title, @Nullable ContactPhoneNumber phoneNumber) { String contactType, String title, @Nullable ContactPhoneNumber phoneNumber) {
return emitField( if (phoneNumber == null) {
contactType, title, phoneNumber != null ? phoneNumber.getPhoneNumber() : null) return this;
.emitField( }
contactType, title, "Ext", phoneNumber != null ? phoneNumber.getExtension() : null); return emitFieldIfDefined(ImmutableList.of(contactType, title), phoneNumber.getPhoneNumber())
.emitFieldIfDefined(
ImmutableList.of(contactType, title, "Ext"), phoneNumber.getExtension());
} }
/** Emit the contact entry of the given type. */ /** Emit the contact entry of the given type. */
@ -167,19 +170,20 @@ final class DomainWhoisResponse extends WhoisResponseImpl {
domain.getFullyQualifiedDomainName(), contact); domain.getFullyQualifiedDomainName(), contact);
return this; return this;
} }
emitField("Registry", contactType, "ID", contactResource.getContactId()); // ICANN Consistent Labeling & Display policy requires that this be the ROID.
emitField(ImmutableList.of("Registry", contactType, "ID"), contactResource.getRepoId());
PostalInfo postalInfo = chooseByUnicodePreference( PostalInfo postalInfo = chooseByUnicodePreference(
preferUnicode, preferUnicode,
contactResource.getLocalizedPostalInfo(), contactResource.getLocalizedPostalInfo(),
contactResource.getInternationalizedPostalInfo()); contactResource.getInternationalizedPostalInfo());
if (postalInfo != null) { if (postalInfo != null) {
emitField(contactType, "Name", postalInfo.getName()); emitFieldIfDefined(ImmutableList.of(contactType, "Name"), postalInfo.getName());
emitField(contactType, "Organization", postalInfo.getOrg()); emitFieldIfDefined(ImmutableList.of(contactType, "Organization"), postalInfo.getOrg());
emitAddress(contactType, postalInfo.getAddress()); emitAddress(contactType, postalInfo.getAddress());
} }
return emitPhone(contactType, "Phone", contactResource.getVoiceNumber()) return emitPhone(contactType, "Phone", contactResource.getVoiceNumber())
.emitPhone(contactType, "Fax", contactResource.getFaxNumber()) .emitPhone(contactType, "Fax", contactResource.getFaxNumber())
.emitField(contactType, "Email", contactResource.getEmailAddress()); .emitField(ImmutableList.of(contactType, "Email"), contactResource.getEmailAddress());
} }
/** Emits status values and grace periods as a set, in the AWIP format. */ /** Emits status values and grace periods as a set, in the AWIP format. */

View file

@ -22,12 +22,10 @@ import com.google.common.base.Function;
import com.google.common.base.Joiner; import com.google.common.base.Joiner;
import com.google.common.base.Optional; import com.google.common.base.Optional;
import com.google.common.collect.FluentIterable; import com.google.common.collect.FluentIterable;
import com.google.common.collect.Iterables;
import com.google.common.collect.Ordering; import com.google.common.collect.Ordering;
import google.registry.model.eppcommon.Address; import google.registry.model.eppcommon.Address;
import google.registry.util.Idn; import google.registry.util.Idn;
import google.registry.xml.UtcDateTimeAdapter; import google.registry.xml.UtcDateTimeAdapter;
import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@ -109,6 +107,16 @@ abstract class WhoisResponseImpl implements WhoisResponse {
return thisCastToDerived(); return thisCastToDerived();
} }
/** Emit the field name and value followed by a newline, but only if a value exists. */
E emitFieldIfDefined(String name, @Nullable String value) {
if (isNullOrEmpty(value)) {
return thisCastToDerived();
}
stringBuilder.append(cleanse(name)).append(':');
stringBuilder.append(' ').append(cleanse(value));
return emitNewline();
}
/** Emit the field name and value followed by a newline. */ /** Emit the field name and value followed by a newline. */
E emitField(String name, @Nullable String value) { E emitField(String name, @Nullable String value) {
stringBuilder.append(cleanse(name)).append(':'); stringBuilder.append(cleanse(name)).append(':');
@ -118,11 +126,17 @@ abstract class WhoisResponseImpl implements WhoisResponse {
return emitNewline(); return emitNewline();
} }
/** Emit a multi-part field name and value followed by a newline, but only if a value exists. */
E emitFieldIfDefined(List<String> nameParts, String value) {
if (isNullOrEmpty(value)) {
return thisCastToDerived();
}
return emitField(nameParts, value);
}
/** Emit a multi-part field name and value followed by a newline. */ /** Emit a multi-part field name and value followed by a newline. */
E emitField(String... namePartsAndValue) { E emitField(List<String> nameParts, String value) {
List<String> parts = Arrays.asList(namePartsAndValue); return emitField(Joiner.on(' ').join(nameParts), value);
return emitField(
Joiner.on(' ').join(parts.subList(0, parts.size() - 1)), Iterables.getLast(parts));
} }
/** Emit a contact address. */ /** Emit a contact address. */

View file

@ -15,7 +15,7 @@ Domain Status: clientRenewProhibited https://icann.org/epp#clientRenewProhibited
Domain Status: clientTransferProhibited https://icann.org/epp#clientTransferProhibited Domain Status: clientTransferProhibited https://icann.org/epp#clientTransferProhibited
Domain Status: serverUpdateProhibited https://icann.org/epp#serverUpdateProhibited Domain Status: serverUpdateProhibited https://icann.org/epp#serverUpdateProhibited
Domain Status: transferPeriod https://icann.org/epp#transferPeriod Domain Status: transferPeriod https://icann.org/epp#transferPeriod
Registry Registrant ID: 5372808-ERL Registry Registrant ID: 4-TLD
Registrant Name: EXAMPLE REGISTRANT Registrant Name: EXAMPLE REGISTRANT
Registrant Organization: EXAMPLE ORGANIZATION Registrant Organization: EXAMPLE ORGANIZATION
Registrant Street: 123 EXAMPLE STREET Registrant Street: 123 EXAMPLE STREET
@ -28,7 +28,7 @@ Registrant Phone Ext: 1234
Registrant Fax: +1.5555551213 Registrant Fax: +1.5555551213
Registrant Fax Ext: 4321 Registrant Fax Ext: 4321
Registrant Email: EMAIL@EXAMPLE.tld Registrant Email: EMAIL@EXAMPLE.tld
Registry Admin ID: 5372809-ERL Registry Admin ID: 5-TLD
Admin Name: EXAMPLE REGISTRANT ADMINISTRATIVE Admin Name: EXAMPLE REGISTRANT ADMINISTRATIVE
Admin Organization: EXAMPLE REGISTRANT ORGANIZATION Admin Organization: EXAMPLE REGISTRANT ORGANIZATION
Admin Street: 123 EXAMPLE STREET Admin Street: 123 EXAMPLE STREET
@ -39,9 +39,8 @@ Admin Country: EX
Admin Phone: +1.5555551212 Admin Phone: +1.5555551212
Admin Phone Ext: 1234 Admin Phone Ext: 1234
Admin Fax: +1.5555551213 Admin Fax: +1.5555551213
Admin Fax Ext:
Admin Email: EMAIL@EXAMPLE.tld Admin Email: EMAIL@EXAMPLE.tld
Registry Tech ID: 5372811-ERL Registry Tech ID: 6-TLD
Tech Name: EXAMPLE REGISTRAR TECHNICAL Tech Name: EXAMPLE REGISTRAR TECHNICAL
Tech Organization: EXAMPLE REGISTRAR LLC Tech Organization: EXAMPLE REGISTRAR LLC
Tech Street: 123 EXAMPLE STREET Tech Street: 123 EXAMPLE STREET

View file

@ -13,7 +13,7 @@ Domain Status: clientDeleteProhibited https://icann.org/epp#clientDeleteProhibit
Domain Status: clientRenewProhibited https://icann.org/epp#clientRenewProhibited Domain Status: clientRenewProhibited https://icann.org/epp#clientRenewProhibited
Domain Status: clientTransferProhibited https://icann.org/epp#clientTransferProhibited Domain Status: clientTransferProhibited https://icann.org/epp#clientTransferProhibited
Domain Status: serverUpdateProhibited https://icann.org/epp#serverUpdateProhibited Domain Status: serverUpdateProhibited https://icann.org/epp#serverUpdateProhibited
Registry Registrant ID: 5372808-ERL Registry Registrant ID: 4-ROID
Registrant Name: Goblin Market Registrant Name: Goblin Market
Registrant Organization: GOOGLE INCORPORATED &lt;script&gt; Registrant Organization: GOOGLE INCORPORATED &lt;script&gt;
Registrant Street: 123 Example Boulevard &lt;script&gt; Registrant Street: 123 Example Boulevard &lt;script&gt;
@ -22,11 +22,9 @@ Registrant State/Province: BM
Registrant Postal Code: 31337 Registrant Postal Code: 31337
Registrant Country: US Registrant Country: US
Registrant Phone: +1.2126660420 Registrant Phone: +1.2126660420
Registrant Phone Ext:
Registrant Fax: +1.2126660420 Registrant Fax: +1.2126660420
Registrant Fax Ext:
Registrant Email: lol@cat.lol Registrant Email: lol@cat.lol
Registry Admin ID: 5372808-IRL Registry Admin ID: 5-ROID
Admin Name: Santa Claus Admin Name: Santa Claus
Admin Organization: GOOGLE INCORPORATED &lt;script&gt; Admin Organization: GOOGLE INCORPORATED &lt;script&gt;
Admin Street: 123 Example Boulevard &lt;script&gt; Admin Street: 123 Example Boulevard &lt;script&gt;
@ -35,11 +33,9 @@ Admin State/Province: BM
Admin Postal Code: 31337 Admin Postal Code: 31337
Admin Country: US Admin Country: US
Admin Phone: +1.2126660420 Admin Phone: +1.2126660420
Admin Phone Ext:
Admin Fax: +1.2126660420 Admin Fax: +1.2126660420
Admin Fax Ext:
Admin Email: BOFH@cat.lol Admin Email: BOFH@cat.lol
Registry Tech ID: 5372808-TRL Registry Tech ID: 6-ROID
Tech Name: The Raven Tech Name: The Raven
Tech Organization: GOOGLE INCORPORATED &lt;script&gt; Tech Organization: GOOGLE INCORPORATED &lt;script&gt;
Tech Street: 123 Example Boulevard &lt;script&gt; Tech Street: 123 Example Boulevard &lt;script&gt;
@ -48,9 +44,7 @@ Tech State/Province: BM
Tech Postal Code: 31337 Tech Postal Code: 31337
Tech Country: US Tech Country: US
Tech Phone: +1.2126660420 Tech Phone: +1.2126660420
Tech Phone Ext:
Tech Fax: +1.2126660420 Tech Fax: +1.2126660420
Tech Fax Ext:
Tech Email: bog@cat.lol Tech Email: bog@cat.lol
Name Server: ns1.cat.lol Name Server: ns1.cat.lol
Name Server: ns2.cat.lol Name Server: ns2.cat.lol

View file

@ -13,7 +13,7 @@ Domain Status: clientDeleteProhibited https://icann.org/epp#clientDeleteProhibit
Domain Status: clientRenewProhibited https://icann.org/epp#clientRenewProhibited Domain Status: clientRenewProhibited https://icann.org/epp#clientRenewProhibited
Domain Status: clientTransferProhibited https://icann.org/epp#clientTransferProhibited Domain Status: clientTransferProhibited https://icann.org/epp#clientTransferProhibited
Domain Status: serverUpdateProhibited https://icann.org/epp#serverUpdateProhibited Domain Status: serverUpdateProhibited https://icann.org/epp#serverUpdateProhibited
Registry Registrant ID: 5372808-ERL Registry Registrant ID: 4-ROID
Registrant Name: (◕‿◕) Registrant Name: (◕‿◕)
Registrant Organization: GOOGLE INCORPORATED &lt;script&gt; Registrant Organization: GOOGLE INCORPORATED &lt;script&gt;
Registrant Street: 123 Example Boulevard &lt;script&gt; Registrant Street: 123 Example Boulevard &lt;script&gt;
@ -22,11 +22,9 @@ Registrant State/Province: BM
Registrant Postal Code: 31337 Registrant Postal Code: 31337
Registrant Country: US Registrant Country: US
Registrant Phone: +1.2126660420 Registrant Phone: +1.2126660420
Registrant Phone Ext:
Registrant Fax: +1.2126660420 Registrant Fax: +1.2126660420
Registrant Fax Ext:
Registrant Email: lol@cat.みんな Registrant Email: lol@cat.みんな
Registry Admin ID: 5372808-IRL Registry Admin ID: 5-ROID
Admin Name: Santa Claus Admin Name: Santa Claus
Admin Organization: GOOGLE INCORPORATED &lt;script&gt; Admin Organization: GOOGLE INCORPORATED &lt;script&gt;
Admin Street: 123 Example Boulevard &lt;script&gt; Admin Street: 123 Example Boulevard &lt;script&gt;
@ -35,11 +33,9 @@ Admin State/Province: BM
Admin Postal Code: 31337 Admin Postal Code: 31337
Admin Country: US Admin Country: US
Admin Phone: +1.2126660420 Admin Phone: +1.2126660420
Admin Phone Ext:
Admin Fax: +1.2126660420 Admin Fax: +1.2126660420
Admin Fax Ext:
Admin Email: BOFH@cat.みんな Admin Email: BOFH@cat.みんな
Registry Tech ID: 5372808-TRL Registry Tech ID: 6-ROID
Tech Name: The Raven Tech Name: The Raven
Tech Organization: GOOGLE INCORPORATED &lt;script&gt; Tech Organization: GOOGLE INCORPORATED &lt;script&gt;
Tech Street: 123 Example Boulevard &lt;script&gt; Tech Street: 123 Example Boulevard &lt;script&gt;
@ -48,9 +44,7 @@ Tech State/Province: BM
Tech Postal Code: 31337 Tech Postal Code: 31337
Tech Country: US Tech Country: US
Tech Phone: +1.2126660420 Tech Phone: +1.2126660420
Tech Phone Ext:
Tech Fax: +1.2126660420 Tech Fax: +1.2126660420
Tech Fax Ext:
Tech Email: bog@cat.みんな Tech Email: bog@cat.みんな
Name Server: ns1.cat.xn--q9jyb4c Name Server: ns1.cat.xn--q9jyb4c
Name Server: ns2.cat.xn--q9jyb4c Name Server: ns2.cat.xn--q9jyb4c

View file

@ -13,7 +13,7 @@ Domain Status: clientDeleteProhibited https://icann.org/epp#clientDeleteProhibit
Domain Status: clientRenewProhibited https://icann.org/epp#clientRenewProhibited Domain Status: clientRenewProhibited https://icann.org/epp#clientRenewProhibited
Domain Status: clientTransferProhibited https://icann.org/epp#clientTransferProhibited Domain Status: clientTransferProhibited https://icann.org/epp#clientTransferProhibited
Domain Status: serverUpdateProhibited https://icann.org/epp#serverUpdateProhibited Domain Status: serverUpdateProhibited https://icann.org/epp#serverUpdateProhibited
Registry Registrant ID: 5372808-ERL Registry Registrant ID: 4-ROID
Registrant Name: (◕‿◕) Registrant Name: (◕‿◕)
Registrant Organization: GOOGLE INCORPORATED &lt;script&gt; Registrant Organization: GOOGLE INCORPORATED &lt;script&gt;
Registrant Street: 123 Example Boulevard &lt;script&gt; Registrant Street: 123 Example Boulevard &lt;script&gt;
@ -22,11 +22,9 @@ Registrant State/Province: BM
Registrant Postal Code: 31337 Registrant Postal Code: 31337
Registrant Country: US Registrant Country: US
Registrant Phone: +1.2126660420 Registrant Phone: +1.2126660420
Registrant Phone Ext:
Registrant Fax: +1.2126660420 Registrant Fax: +1.2126660420
Registrant Fax Ext:
Registrant Email: lol@cat.みんな Registrant Email: lol@cat.みんな
Registry Admin ID: 5372808-IRL Registry Admin ID: 5-ROID
Admin Name: Santa Claus Admin Name: Santa Claus
Admin Organization: GOOGLE INCORPORATED &lt;script&gt; Admin Organization: GOOGLE INCORPORATED &lt;script&gt;
Admin Street: 123 Example Boulevard &lt;script&gt; Admin Street: 123 Example Boulevard &lt;script&gt;
@ -35,11 +33,9 @@ Admin State/Province: BM
Admin Postal Code: 31337 Admin Postal Code: 31337
Admin Country: US Admin Country: US
Admin Phone: +1.2126660420 Admin Phone: +1.2126660420
Admin Phone Ext:
Admin Fax: +1.2126660420 Admin Fax: +1.2126660420
Admin Fax Ext:
Admin Email: BOFH@cat.みんな Admin Email: BOFH@cat.みんな
Registry Tech ID: 5372808-TRL Registry Tech ID: 6-ROID
Tech Name: The Raven Tech Name: The Raven
Tech Organization: GOOGLE INCORPORATED &lt;script&gt; Tech Organization: GOOGLE INCORPORATED &lt;script&gt;
Tech Street: 123 Example Boulevard &lt;script&gt; Tech Street: 123 Example Boulevard &lt;script&gt;
@ -48,9 +44,7 @@ Tech State/Province: BM
Tech Postal Code: 31337 Tech Postal Code: 31337
Tech Country: US Tech Country: US
Tech Phone: +1.2126660420 Tech Phone: +1.2126660420
Tech Phone Ext:
Tech Fax: +1.2126660420 Tech Fax: +1.2126660420
Tech Fax Ext:
Tech Email: bog@cat.みんな Tech Email: bog@cat.みんな
Name Server: ns1.cat.みんな Name Server: ns1.cat.みんな
Name Server: ns2.cat.みんな Name Server: ns2.cat.みんな