diff --git a/core/src/main/java/google/registry/tools/CreateDomainCommand.java b/core/src/main/java/google/registry/tools/CreateDomainCommand.java index 2c896c38b3a..dc408f0cf34 100644 --- a/core/src/main/java/google/registry/tools/CreateDomainCommand.java +++ b/core/src/main/java/google/registry/tools/CreateDomainCommand.java @@ -16,6 +16,7 @@ import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Strings.isNullOrEmpty; +import static google.registry.persistence.transaction.TransactionManagerFactory.tm; import static google.registry.pricing.PricingEngineProxy.getPricesForDomainName; import static google.registry.util.PreconditionsUtils.checkArgumentNotNull; import static org.joda.time.DateTimeZone.UTC; @@ -23,6 +24,7 @@ import com.beust.jcommander.Parameter; import com.beust.jcommander.Parameters; import com.google.template.soy.data.SoyMapData; +import google.registry.model.common.FeatureFlag; import google.registry.model.pricing.PremiumPricingEngine.DomainPrices; import google.registry.tools.soy.DomainCreateSoyInfo; import google.registry.util.StringGenerator; @@ -58,9 +60,15 @@ final class CreateDomainCommand extends CreateOrUpdateDomainCommand { @Override protected void initMutatingEppToolCommand() { - checkArgumentNotNull(registrant, "Registrant must be specified"); - checkArgument(!admins.isEmpty(), "At least one admin must be specified"); - checkArgument(!techs.isEmpty(), "At least one tech must be specified"); + tm().transact( + () -> { + if (!FeatureFlag.isActiveNowOrElse( + FeatureFlag.FeatureName.MINIMUM_DATASET_CONTACTS_OPTIONAL, false)) { + checkArgumentNotNull(registrant, "Registrant must be specified"); + checkArgument(!admins.isEmpty(), "At least one admin must be specified"); + checkArgument(!techs.isEmpty(), "At least one tech must be specified"); + } + }); if (isNullOrEmpty(password)) { password = passwordGenerator.createString(PASSWORD_LENGTH); } diff --git a/core/src/main/resources/google/registry/tools/soy/DomainCreate.soy b/core/src/main/resources/google/registry/tools/soy/DomainCreate.soy index b7eeb825891..9b20b85d61e 100644 --- a/core/src/main/resources/google/registry/tools/soy/DomainCreate.soy +++ b/core/src/main/resources/google/registry/tools/soy/DomainCreate.soy @@ -20,9 +20,9 @@ {@param domain: string} {@param period: int} {@param nameservers: list} - {@param registrant: string} - {@param admins: list} - {@param techs: list} + {@param? registrant: string|null} + {@param? admins: list|null} + {@param? techs: list|null} {@param password: string} {@param? currency: string|null} {@param? price: string|null} @@ -45,13 +45,19 @@ {/for} {/if} - {$registrant} - {for $admin in $admins} - {$admin} - {/for} - {for $tech in $techs} - {$tech} - {/for} + {if $registrant != null} + {$registrant} + {/if} + {if $admins != null} + {for $admin in $admins} + {$admin} + {/for} + {/if} + {if $techs != null} + {for $tech in $techs} + {$tech} + {/for} + {/if} {$password} diff --git a/core/src/test/java/google/registry/tools/CreateDomainCommandTest.java b/core/src/test/java/google/registry/tools/CreateDomainCommandTest.java index a05c557e71d..000486cae6a 100644 --- a/core/src/test/java/google/registry/tools/CreateDomainCommandTest.java +++ b/core/src/test/java/google/registry/tools/CreateDomainCommandTest.java @@ -15,16 +15,21 @@ package google.registry.tools; import static com.google.common.truth.Truth.assertThat; +import static google.registry.model.common.FeatureFlag.FeatureName.MINIMUM_DATASET_CONTACTS_OPTIONAL; +import static google.registry.model.common.FeatureFlag.FeatureStatus.ACTIVE; import static google.registry.persistence.transaction.TransactionManagerFactory.tm; import static google.registry.testing.DatabaseHelper.createTld; import static google.registry.testing.DatabaseHelper.persistPremiumList; import static google.registry.testing.DatabaseHelper.persistResource; +import static google.registry.util.DateTimeUtils.START_OF_TIME; import static org.joda.money.CurrencyUnit.JPY; import static org.junit.jupiter.api.Assertions.assertThrows; import com.beust.jcommander.ParameterException; import com.google.common.collect.ImmutableSet; +import com.google.common.collect.ImmutableSortedMap; import google.registry.dns.writer.VoidDnsWriter; +import google.registry.model.common.FeatureFlag; import google.registry.model.pricing.StaticPremiumListPricingEngine; import google.registry.model.tld.Tld; import google.registry.model.tld.label.PremiumListDao; @@ -111,12 +116,15 @@ void testSuccess_completeWithSquareBracketsAndCanonicalization() throws Exceptio @Test void testSuccess_minimal() throws Exception { + persistResource( + new FeatureFlag() + .asBuilder() + .setFeatureName(MINIMUM_DATASET_CONTACTS_OPTIONAL) + .setStatusMap(ImmutableSortedMap.of(START_OF_TIME, ACTIVE)) + .build()); // Test that each optional field can be omitted. Also tests the auto-gen password. runCommandForced( "--client=NewRegistrar", - "--registrant=crr-admin", - "--admins=crr-admin", - "--techs=crr-tech", "example.tld"); eppVerifier.verifySent("domain_create_minimal.xml"); } @@ -131,7 +139,9 @@ void testSuccess_multipleDomains() throws Exception { "--techs=crr-tech", "example.tld", "example.abc"); - eppVerifier.verifySent("domain_create_minimal.xml").verifySent("domain_create_minimal_abc.xml"); + eppVerifier + .verifySent("domain_create_contacts.xml") + .verifySent("domain_create_contacts_abc.xml"); } @Test @@ -152,8 +162,8 @@ void testSuccess_premiumListNull() throws Exception { "example.tld", "example.abc"); eppVerifier - .verifySent("domain_create_minimal.xml") - .verifySent("domain_create_minimal_abc.xml"); + .verifySent("domain_create_contacts.xml") + .verifySent("domain_create_contacts_abc.xml"); } @Test @@ -192,9 +202,9 @@ void testSuccess_multipleDomainsWithPremium() throws Exception { "palladium.tld", "example.abc"); eppVerifier - .verifySent("domain_create_minimal.xml") + .verifySent("domain_create_contacts.xml") .verifySent("domain_create_palladium.xml") - .verifySent("domain_create_minimal_abc.xml"); + .verifySent("domain_create_contacts_abc.xml"); assertInStdout( "palladium.tld is premium at USD 877.00 per year; " + "sending total cost for 1 year(s) of USD 877.00."); @@ -227,6 +237,19 @@ void testSuccess_allocationToken() throws Exception { eppVerifier.verifySent("domain_create_token.xml"); } + @Test + void testSuccess_contactsStillRequired() throws Exception { + // Verify that if contacts are still required, the minimum+contacts request is sent + createTld("tld"); + runCommandForced( + "--client=NewRegistrar", + "--registrant=crr-admin", + "--admins=crr-admin", + "--techs=crr-tech", + "example.tld"); + eppVerifier.verifySent("domain_create_contacts.xml"); + } + @Test void testFailure_duplicateDomains() { IllegalArgumentException thrown = diff --git a/core/src/test/resources/google/registry/tools/server/domain_create_contacts.xml b/core/src/test/resources/google/registry/tools/server/domain_create_contacts.xml new file mode 100644 index 00000000000..c04c1e1a83a --- /dev/null +++ b/core/src/test/resources/google/registry/tools/server/domain_create_contacts.xml @@ -0,0 +1,19 @@ + + + + + + example.tld + 1 + crr-admin + crr-admin + crr-tech + + abcdefghijklmnop + + + + RegistryTool + + diff --git a/core/src/test/resources/google/registry/tools/server/domain_create_minimal_abc.xml b/core/src/test/resources/google/registry/tools/server/domain_create_contacts_abc.xml similarity index 100% rename from core/src/test/resources/google/registry/tools/server/domain_create_minimal_abc.xml rename to core/src/test/resources/google/registry/tools/server/domain_create_contacts_abc.xml diff --git a/core/src/test/resources/google/registry/tools/server/domain_create_minimal.xml b/core/src/test/resources/google/registry/tools/server/domain_create_minimal.xml index c04c1e1a83a..8f6bedcfb30 100644 --- a/core/src/test/resources/google/registry/tools/server/domain_create_minimal.xml +++ b/core/src/test/resources/google/registry/tools/server/domain_create_minimal.xml @@ -6,9 +6,6 @@ xmlns:domain="urn:ietf:params:xml:ns:domain-1.0"> example.tld 1 - crr-admin - crr-admin - crr-tech abcdefghijklmnop