diff --git a/core/src/main/java/google/registry/model/tld/Tld.java b/core/src/main/java/google/registry/model/tld/Tld.java index e4e1514e7..c18a28755 100644 --- a/core/src/main/java/google/registry/model/tld/Tld.java +++ b/core/src/main/java/google/registry/model/tld/Tld.java @@ -74,6 +74,7 @@ import google.registry.tldconfig.idn.IdnTableEnum; import google.registry.util.Idn; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Optional; import java.util.Set; import java.util.function.Predicate; @@ -458,6 +459,8 @@ public class Tld extends ImmutableObject implements Buildable, UnsafeSerializabl @JsonDeserialize(using = CurrencyDeserializer.class) CurrencyUnit currency = DEFAULT_CURRENCY; + // TODO(sarahbot@): Remove this field and make createBillingCostTransitions not-null once all TLDs + // are populated with a create cost transition map /** The per-year billing cost for registering a new domain name. */ @Type(type = JodaMoneyType.TYPE_NAME) @Columns( @@ -467,6 +470,12 @@ public class Tld extends ImmutableObject implements Buildable, UnsafeSerializabl }) Money createBillingCost = DEFAULT_CREATE_BILLING_COST; + // TODO(sarahbot@): Make this field not null and add a default value once field is populated on + // all existing TLDs + /** A property that transitions to different create billing costs at different times. */ + @JsonDeserialize(using = TimedTransitionPropertyMoneyDeserializer.class) + TimedTransitionProperty createBillingCostTransitions; + /** The one-time billing cost for restoring a domain name from the redemption grace period. */ @Type(type = JodaMoneyType.TYPE_NAME) @Columns( @@ -676,6 +685,13 @@ public class Tld extends ImmutableObject implements Buildable, UnsafeSerializabl return createBillingCost; } + public ImmutableSortedMap getCreateBillingCostTransitions() { + return Objects.requireNonNullElseGet( + createBillingCostTransitions, + () -> TimedTransitionProperty.withInitialValue(getCreateBillingCost())) + .toValueMap(); + } + /** * Returns the add-on cost of a domain restore (the flat tld-wide fee charged in addition to one * year of renewal for that name). @@ -959,6 +975,17 @@ public class Tld extends ImmutableObject implements Buildable, UnsafeSerializabl return this; } + public Builder setCreateBillingCostTransitions( + ImmutableSortedMap createCostsMap) { + checkArgumentNotNull(createCostsMap, "Create billing costs map cannot be null"); + checkArgument( + createCostsMap.values().stream().allMatch(Money::isPositiveOrZero), + "Create billing cost cannot be negative"); + getInstance().createBillingCostTransitions = + TimedTransitionProperty.fromValueMap(createCostsMap); + return this; + } + public Builder setReservedListsByName(Set reservedListNames) { // TODO(b/309175133): forbid if enrolled with BSA checkArgument(reservedListNames != null, "reservedListNames must not be null"); @@ -1131,6 +1158,10 @@ public class Tld extends ImmutableObject implements Buildable, UnsafeSerializabl // here to catch cases where we loaded an invalid TimedTransitionProperty from the database // and cloned it into a new builder, to block re-building a Tld in an invalid state. instance.tldStateTransitions.checkValidity(); + // TODO(sarahbot@): Remove null check when createBillingCostTransitions field is made not-null + if (instance.createBillingCostTransitions != null) { + instance.createBillingCostTransitions.checkValidity(); + } instance.renewBillingCostTransitions.checkValidity(); instance.eapFeeSchedule.checkValidity(); // All costs must be in the expected currency. diff --git a/core/src/main/java/google/registry/tools/ConfigureTldCommand.java b/core/src/main/java/google/registry/tools/ConfigureTldCommand.java index db5c9310a..408b7423a 100644 --- a/core/src/main/java/google/registry/tools/ConfigureTldCommand.java +++ b/core/src/main/java/google/registry/tools/ConfigureTldCommand.java @@ -14,6 +14,7 @@ package google.registry.tools; import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.collect.ImmutableSet.toImmutableSet; import static google.registry.model.tld.Tld.Builder.ROID_SUFFIX_PATTERN; import static google.registry.model.tld.Tlds.getTlds; import static google.registry.util.ListNamingUtils.convertFilePathToName; @@ -28,10 +29,12 @@ import com.google.common.collect.ImmutableSortedMap; import com.google.common.collect.Sets; import com.google.common.collect.Sets.SetView; import com.google.common.flogger.FluentLogger; +import google.registry.model.common.TimedTransitionProperty; import google.registry.model.tld.Tld; import google.registry.model.tld.label.PremiumList; import google.registry.model.tld.label.PremiumListDao; import google.registry.tools.params.PathParameter; +import google.registry.util.Clock; import google.registry.util.Idn; import java.lang.reflect.Field; import java.lang.reflect.Modifier; @@ -40,9 +43,11 @@ import java.nio.file.Path; import java.util.Arrays; import java.util.HashSet; import java.util.Map; +import java.util.Objects; import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; +import java.util.stream.Stream; import javax.inject.Inject; import javax.inject.Named; import org.joda.money.CurrencyUnit; @@ -90,6 +95,8 @@ public class ConfigureTldCommand extends MutatingCommand { @Inject ObjectMapper mapper; + @Inject Clock clock; + @Inject @Named("dnsWriterNames") Set validDnsWriterNames; @@ -114,8 +121,11 @@ public class ConfigureTldCommand extends MutatingCommand { String name = convertFilePathToName(inputFile); Map tldData = new Yaml().load(Files.newBufferedReader(inputFile)); checkName(name, tldData); - checkForMissingFields(tldData); Tld oldTld = getTlds().contains(name) ? Tld.get(name) : null; + + checkForMissingFields( + Stream.concat(tldData.keySet().stream(), Stream.of("createBillingCostTransitions")) + .collect(toImmutableSet())); Tld newTld = mapper.readValue(inputFile.toFile(), Tld.class); if (oldTld != null) { oldTldInBreakGlass = oldTld.getBreakglassMode(); @@ -146,6 +156,14 @@ public class ConfigureTldCommand extends MutatingCommand { checkPremiumList(newTld); checkDnsWriters(newTld); checkCurrency(newTld); + // TODO(sarahbot@): Remove this once the createBillingCost field is removed + checkArgument( + Objects.equals( + TimedTransitionProperty.fromValueMap(newTld.getCreateBillingCostTransitions()) + .getValueAtTime(clock.nowUtc()), + newTld.getCreateBillingCost()), + "The createBillingCostTransitions map must have the same current cost as the" + + " createBillingCost field"); // bsaEnrollStartTime only exists in DB. Need to carry it over to the updated copy. See Tld.java // for more information. Optional bsaEnrollTime = @@ -198,7 +216,7 @@ public class ConfigureTldCommand extends MutatingCommand { ROID_SUFFIX_PATTERN.pattern()); } - private void checkForMissingFields(Map tldData) { + private void checkForMissingFields(ImmutableSet keySet) { Set tldFields = Arrays.stream(Tld.class.getDeclaredFields()) .filter(field -> !Modifier.isStatic(field.getModifiers())) @@ -207,7 +225,7 @@ public class ConfigureTldCommand extends MutatingCommand { .collect(Collectors.toSet()); Set missingFields = new HashSet<>(); for (String field : tldFields) { - if (!tldData.containsKey(field)) { + if (!keySet.contains(field)) { missingFields.add(field); } } diff --git a/core/src/test/java/google/registry/model/tld/TldTest.java b/core/src/test/java/google/registry/model/tld/TldTest.java index 54b9b0307..2eb983e78 100644 --- a/core/src/test/java/google/registry/model/tld/TldTest.java +++ b/core/src/test/java/google/registry/model/tld/TldTest.java @@ -46,6 +46,7 @@ import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSortedMap; import google.registry.dns.writer.VoidDnsWriter; import google.registry.model.EntityTestCase; +import google.registry.model.common.TimedTransitionProperty; import google.registry.model.domain.token.AllocationToken; import google.registry.model.tld.Tld.TldNotFoundException; import google.registry.model.tld.Tld.TldState; @@ -149,6 +150,8 @@ public final class TldTest extends EntityTestCase { .asBuilder() .setDnsAPlusAaaaTtl(Duration.standardHours(1)) .setDnsWriters(ImmutableSet.of("baz", "bang")) + .setCreateBillingCostTransitions( + TimedTransitionProperty.withInitialValue(Money.of(USD, 13)).toValueMap()) .setEapFeeSchedule( ImmutableSortedMap.of( START_OF_TIME, @@ -170,7 +173,12 @@ public final class TldTest extends EntityTestCase { @Test void testSuccess_tldYamlRoundtrip() throws Exception { - Tld testTld = createTld("test"); + Tld testTld = + createTld("test") + .asBuilder() + .setCreateBillingCostTransitions( + TimedTransitionProperty.withInitialValue(Money.of(USD, 8)).toValueMap()) + .build(); ObjectMapper mapper = createObjectMapper(); String yaml = mapper.writeValueAsString(testTld); Tld constructedTld = mapper.readValue(yaml, Tld.class); @@ -224,6 +232,46 @@ public final class TldTest extends EntityTestCase { assertThat(registry.getRestoreBillingCost()).isEqualTo(Money.of(USD, 17)); } + @Test + void testSetCreateBillingCostTransitions() { + ImmutableSortedMap createCostTransitions = + ImmutableSortedMap.of( + START_OF_TIME, + Money.of(USD, 8), + fakeClock.nowUtc(), + Money.of(USD, 1), + fakeClock.nowUtc().plusMonths(1), + Money.of(USD, 2), + fakeClock.nowUtc().plusMonths(2), + Money.of(USD, 3)); + Tld registry = + Tld.get("tld").asBuilder().setCreateBillingCostTransitions(createCostTransitions).build(); + assertThat(registry.getCreateBillingCostTransitions()).isEqualTo(createCostTransitions); + } + + @Test + void testSetCreateBillingCostTransitionsNegativeCost() throws Exception { + ImmutableSortedMap createCostTransitions = + ImmutableSortedMap.of( + START_OF_TIME, + Money.of(USD, 8), + fakeClock.nowUtc(), + Money.of(USD, 1), + fakeClock.nowUtc().plusMonths(1), + Money.of(USD, -2), + fakeClock.nowUtc().plusMonths(2), + Money.of(USD, 3)); + IllegalArgumentException thrown = + assertThrows( + IllegalArgumentException.class, + () -> + Tld.get("tld") + .asBuilder() + .setCreateBillingCostTransitions(createCostTransitions) + .build()); + assertThat(thrown.getMessage()).isEqualTo("Create billing cost cannot be negative"); + } + @Test void testSettingRestoreBillingCost() { Tld registry = Tld.get("tld").asBuilder().setRestoreBillingCost(Money.of(USD, 42)).build(); diff --git a/core/src/test/java/google/registry/tools/ConfigureTldCommandTest.java b/core/src/test/java/google/registry/tools/ConfigureTldCommandTest.java index 3e3fafdc9..ab5a2644e 100644 --- a/core/src/test/java/google/registry/tools/ConfigureTldCommandTest.java +++ b/core/src/test/java/google/registry/tools/ConfigureTldCommandTest.java @@ -25,6 +25,7 @@ import static google.registry.testing.TestDataHelper.loadFile; import static google.registry.tldconfig.idn.IdnTableEnum.EXTENDED_LATIN; import static google.registry.tldconfig.idn.IdnTableEnum.JA; import static google.registry.tldconfig.idn.IdnTableEnum.UNCONFUSABLE_LATIN; +import static google.registry.util.DateTimeUtils.START_OF_TIME; import static java.nio.charset.StandardCharsets.UTF_8; import static java.util.logging.Level.INFO; import static org.joda.money.CurrencyUnit.JPY; @@ -39,6 +40,7 @@ import com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException; import com.google.common.base.Ascii; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; +import com.google.common.collect.ImmutableSortedMap; import com.google.common.io.Files; import com.google.common.testing.TestLogHandler; import google.registry.model.domain.token.AllocationToken; @@ -70,6 +72,7 @@ public class ConfigureTldCommandTest extends CommandTestCase createCostTransitions = + ImmutableSortedMap.of( + START_OF_TIME, + Money.of(USD, 8), + fakeClock.nowUtc(), + Money.of(USD, 1), + fakeClock.nowUtc().plusMonths(1), + Money.of(USD, 2), + fakeClock.nowUtc().plusMonths(2), + Money.of(USD, 3)); + Tld tld = + createTld("nocreatecostmap") + .asBuilder() + .setCreateBillingCostTransitions(createCostTransitions) + .build(); + assertThat(tld.getCreateBillingCostTransitions().size()).isEqualTo(4); + File tldFile = tmpDir.resolve("nocreatecostmap.yaml").toFile(); + Files.asCharSink(tldFile, UTF_8).write(loadFile(getClass(), "nocreatecostmap.yaml")); + runCommandForced("--input=" + tldFile); + Tld updatedTld = Tld.get("nocreatecostmap"); + assertThat(updatedTld.getCreateBillingCostTransitions()) + .isEqualTo(ImmutableSortedMap.of(START_OF_TIME, Money.of(USD, 25))); + } + + @Test + void testFailure_billingCostTransitionsDoesNotMatchCreateCost() throws Exception { + createTld("diffcostmap"); + File tldFile = tmpDir.resolve("diffcostmap.yaml").toFile(); + Files.asCharSink(tldFile, UTF_8).write(loadFile(getClass(), "diffcostmap.yaml")); + IllegalArgumentException thrown = + assertThrows(IllegalArgumentException.class, () -> runCommandForced("--input=" + tldFile)); + assertThat(thrown.getMessage()) + .isEqualTo( + "The createBillingCostTransitions map must have the same current cost as the" + + " createBillingCost field"); + } + @Test void testFailure_fileMissingNullableFieldsOnCreate() throws Exception { File tldFile = tmpDir.resolve("missingnullablefields.yaml").toFile(); @@ -185,6 +239,20 @@ public class ConfigureTldCommandTest extends CommandTestCase costTransitions = + updatedTld.getCreateBillingCostTransitions(); + assertThat(costTransitions.size()).isEqualTo(3); + assertThat(costTransitions.get(START_OF_TIME)).isEqualTo(Money.of(USD, 13)); + assertThat(costTransitions.get(START_OF_TIME.plusYears(26))).isEqualTo(Money.of(USD, 14)); + } + @Test void testFailure_fileMissingNullableFieldOnUpdate() throws Exception { Tld tld = createTld("missingnullablefields"); diff --git a/core/src/test/java/google/registry/tools/GetTldCommandTest.java b/core/src/test/java/google/registry/tools/GetTldCommandTest.java index e9873fcd4..595c55a2d 100644 --- a/core/src/test/java/google/registry/tools/GetTldCommandTest.java +++ b/core/src/test/java/google/registry/tools/GetTldCommandTest.java @@ -19,14 +19,17 @@ import static google.registry.testing.DatabaseHelper.createTlds; import static google.registry.testing.DatabaseHelper.persistPremiumList; import static google.registry.testing.DatabaseHelper.persistResource; import static google.registry.testing.TestDataHelper.loadFile; +import static google.registry.util.DateTimeUtils.START_OF_TIME; import static org.joda.money.CurrencyUnit.USD; import static org.junit.jupiter.api.Assertions.assertThrows; import com.beust.jcommander.ParameterException; +import com.google.common.collect.ImmutableSortedMap; import google.registry.model.EntityYamlUtils; import google.registry.model.tld.Tld; import google.registry.model.tld.label.PremiumList; import org.joda.money.Money; +import org.joda.time.DateTime; import org.joda.time.Duration; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -48,6 +51,12 @@ class GetTldCommandTest extends CommandTestCase { .setDnsAPlusAaaaTtl(Duration.standardMinutes(15)) .setDriveFolderId("driveFolder") .setCreateBillingCost(Money.of(USD, 25)) + .setCreateBillingCostTransitions( + ImmutableSortedMap.of( + START_OF_TIME, + Money.of(USD, 8), + DateTime.parse("2020-01-01T00:00:00Z"), + Money.of(USD, 25))) .setPremiumList(premiumList) .build()); runCommand("tld"); diff --git a/core/src/test/resources/google/registry/model/tld/tld.yaml b/core/src/test/resources/google/registry/model/tld/tld.yaml index 6d8b2d824..59bcfdf9f 100644 --- a/core/src/test/resources/google/registry/model/tld/tld.yaml +++ b/core/src/test/resources/google/registry/model/tld/tld.yaml @@ -9,6 +9,10 @@ claimsPeriodEnd: "294247-01-10T04:00:54.775Z" createBillingCost: currency: "USD" amount: 13.00 +createBillingCostTransitions: + "1970-01-01T00:00:00.000Z": + currency: "USD" + amount: 13.00 creationTime: "1970-01-01T00:00:00.000Z" currency: "USD" defaultPromoTokens: diff --git a/core/src/test/resources/google/registry/tools/costmap.yaml b/core/src/test/resources/google/registry/tools/costmap.yaml new file mode 100644 index 000000000..f6b37e7c1 --- /dev/null +++ b/core/src/test/resources/google/registry/tools/costmap.yaml @@ -0,0 +1,75 @@ +addGracePeriodLength: "PT432000S" +allowedFullyQualifiedHostNames: +- "foo" +allowedRegistrantContactIds: [] +anchorTenantAddGracePeriodLength: "PT2592000S" +autoRenewGracePeriodLength: "PT3888000S" +automaticTransferLength: "PT432000S" +claimsPeriodEnd: "294247-01-10T04:00:54.775Z" +createBillingCost: + currency: "USD" + amount: 14.00 +createBillingCostTransitions: + "1970-01-01T00:00:00.000Z": + currency: "USD" + amount: 13.00 + "1996-01-01T00:00:00.000Z": + currency: "USD" + amount: 14.00 + "2050-01-01T00:00:00.000Z": + currency: "USD" + amount: 15.00 +creationTime: "1970-01-01T00:00:00.000Z" +currency: "USD" +defaultPromoTokens: +- "bbbbb" +dnsAPlusAaaaTtl: "PT3600S" +dnsDsTtl: null +dnsNsTtl: null +dnsPaused: false +dnsWriters: +- "VoidDnsWriter" +driveFolderId: null +eapFeeSchedule: + "1970-01-01T00:00:00.000Z": + currency: "USD" + amount: 0.00 + "2000-06-01T00:00:00.000Z": + currency: "USD" + amount: 100.00 + "2000-06-02T00:00:00.000Z": + currency: "USD" + amount: 0.00 +escrowEnabled: false +idnTables: +- "EXTENDED_LATIN" +- "JA" +invoicingEnabled: false +lordnUsername: null +numDnsPublishLocks: 1 +pendingDeleteLength: "PT432000S" +premiumListName: "test" +pricingEngineClassName: "google.registry.model.pricing.StaticPremiumListPricingEngine" +redemptionGracePeriodLength: "PT2592000S" +registryLockOrUnlockBillingCost: + currency: "USD" + amount: 0.00 +renewBillingCostTransitions: + "1970-01-01T00:00:00.000Z": + currency: "USD" + amount: 11.00 +renewGracePeriodLength: "PT432000S" +reservedListNames: [] +restoreBillingCost: + currency: "USD" + amount: 17.00 +roidSuffix: "COSTMAP" +serverStatusChangeBillingCost: + currency: "USD" + amount: 19.00 +tldStateTransitions: + "1970-01-01T00:00:00.000Z": "GENERAL_AVAILABILITY" +tldStr: "costmap" +tldType: "REAL" +tldUnicode: "costmap" +transferGracePeriodLength: "PT432000S" diff --git a/core/src/test/resources/google/registry/tools/diffcostmap.yaml b/core/src/test/resources/google/registry/tools/diffcostmap.yaml new file mode 100644 index 000000000..c2b39c443 --- /dev/null +++ b/core/src/test/resources/google/registry/tools/diffcostmap.yaml @@ -0,0 +1,59 @@ +addGracePeriodLength: "PT432000S" +allowedFullyQualifiedHostNames: [] +allowedRegistrantContactIds: [] +anchorTenantAddGracePeriodLength: "PT2592000S" +autoRenewGracePeriodLength: "PT3888000S" +automaticTransferLength: "PT432000S" +claimsPeriodEnd: "294247-01-10T04:00:54.775Z" +createBillingCost: + currency: "USD" + amount: 25.00 +createBillingCostTransitions: + "1970-01-01T00:00:00.000Z": + currency: "USD" + amount: 12.00 +creationTime: "2022-09-01T00:00:00.000Z" +currency: "USD" +defaultPromoTokens: [] +dnsAPlusAaaaTtl: "PT900S" +dnsDsTtl: null +dnsNsTtl: null +dnsPaused: false +dnsWriters: +- "VoidDnsWriter" +driveFolderId: "driveFolder" +eapFeeSchedule: + "1970-01-01T00:00:00.000Z": + currency: "USD" + amount: 0.00 +escrowEnabled: false +idnTables: [] +invoicingEnabled: false +lordnUsername: null +numDnsPublishLocks: 1 +pendingDeleteLength: "PT432000S" +premiumListName: "test" +pricingEngineClassName: "google.registry.model.pricing.StaticPremiumListPricingEngine" +redemptionGracePeriodLength: "PT2592000S" +registryLockOrUnlockBillingCost: + currency: "USD" + amount: 0.00 +renewBillingCostTransitions: + "1970-01-01T00:00:00.000Z": + currency: "USD" + amount: 11.00 +renewGracePeriodLength: "PT432000S" +reservedListNames: [] +restoreBillingCost: + currency: "USD" + amount: 17.00 +roidSuffix: "DIFFMAP" +serverStatusChangeBillingCost: + currency: "USD" + amount: 19.00 +tldStateTransitions: + "1970-01-01T00:00:00.000Z": "GENERAL_AVAILABILITY" +tldStr: "diffcostmap" +tldType: "REAL" +tldUnicode: "diffcostmap" +transferGracePeriodLength: "PT432000S" diff --git a/core/src/test/resources/google/registry/tools/idns.yaml b/core/src/test/resources/google/registry/tools/idns.yaml index 277117413..010c162d2 100644 --- a/core/src/test/resources/google/registry/tools/idns.yaml +++ b/core/src/test/resources/google/registry/tools/idns.yaml @@ -12,6 +12,10 @@ claimsPeriodEnd: "294247-01-10T04:00:54.775Z" createBillingCost: currency: "USD" amount: 13.00 +createBillingCostTransitions: + "1970-01-01T00:00:00.000Z": + currency: "USD" + amount: 13.00 creationTime: "2022-09-01T00:00:00.000Z" currency: "USD" defaultPromoTokens: [] diff --git a/core/src/test/resources/google/registry/tools/jpy.yaml b/core/src/test/resources/google/registry/tools/jpy.yaml index bcb516f69..9984e88c1 100644 --- a/core/src/test/resources/google/registry/tools/jpy.yaml +++ b/core/src/test/resources/google/registry/tools/jpy.yaml @@ -8,6 +8,10 @@ claimsPeriodEnd: "294247-01-10T04:00:54.775Z" createBillingCost: currency: "JPY" amount: 250 +createBillingCostTransitions: + "1970-01-01T00:00:00.000Z": + currency: "JPY" + amount: 250 creationTime: "2022-09-01T00:00:00.000Z" currency: "JPY" defaultPromoTokens: [] diff --git a/core/src/test/resources/google/registry/tools/nocreatecostmap.yaml b/core/src/test/resources/google/registry/tools/nocreatecostmap.yaml new file mode 100644 index 000000000..bede718d8 --- /dev/null +++ b/core/src/test/resources/google/registry/tools/nocreatecostmap.yaml @@ -0,0 +1,55 @@ +addGracePeriodLength: "PT432000S" +allowedFullyQualifiedHostNames: [] +allowedRegistrantContactIds: [] +anchorTenantAddGracePeriodLength: "PT2592000S" +autoRenewGracePeriodLength: "PT3888000S" +automaticTransferLength: "PT432000S" +claimsPeriodEnd: "294247-01-10T04:00:54.775Z" +createBillingCost: + currency: "USD" + amount: 25.00 +creationTime: "2022-09-01T00:00:00.000Z" +currency: "USD" +defaultPromoTokens: [] +dnsAPlusAaaaTtl: "PT900S" +dnsDsTtl: null +dnsNsTtl: null +dnsPaused: false +dnsWriters: +- "VoidDnsWriter" +driveFolderId: "driveFolder" +eapFeeSchedule: + "1970-01-01T00:00:00.000Z": + currency: "USD" + amount: 0.00 +escrowEnabled: false +idnTables: [] +invoicingEnabled: false +lordnUsername: null +numDnsPublishLocks: 1 +pendingDeleteLength: "PT432000S" +premiumListName: "test" +pricingEngineClassName: "google.registry.model.pricing.StaticPremiumListPricingEngine" +redemptionGracePeriodLength: "PT2592000S" +registryLockOrUnlockBillingCost: + currency: "USD" + amount: 0.00 +renewBillingCostTransitions: + "1970-01-01T00:00:00.000Z": + currency: "USD" + amount: 11.00 +renewGracePeriodLength: "PT432000S" +reservedListNames: [] +restoreBillingCost: + currency: "USD" + amount: 17.00 +roidSuffix: "NOCREATE" +serverStatusChangeBillingCost: + currency: "USD" + amount: 19.00 +tldStateTransitions: + "1970-01-01T00:00:00.000Z": "GENERAL_AVAILABILITY" +tldStr: "nocreatecostmap" +tldType: "REAL" +tldUnicode: "nocreatecostmap" +transferGracePeriodLength: "PT432000S" diff --git a/core/src/test/resources/google/registry/tools/tld.yaml b/core/src/test/resources/google/registry/tools/tld.yaml index 71934a723..8b61326e1 100644 --- a/core/src/test/resources/google/registry/tools/tld.yaml +++ b/core/src/test/resources/google/registry/tools/tld.yaml @@ -8,6 +8,13 @@ claimsPeriodEnd: "294247-01-10T04:00:54.775Z" createBillingCost: currency: "USD" amount: 25.00 +createBillingCostTransitions: + "1970-01-01T00:00:00.000Z": + currency: "USD" + amount: 8.00 + "2020-01-01T00:00:00.000Z": + currency: "USD" + amount: 25.00 creationTime: "2022-09-01T00:00:00.000Z" currency: "USD" defaultPromoTokens: [] diff --git a/core/src/test/resources/google/registry/tools/wildcard.yaml b/core/src/test/resources/google/registry/tools/wildcard.yaml index a9900e165..a8f45a551 100644 --- a/core/src/test/resources/google/registry/tools/wildcard.yaml +++ b/core/src/test/resources/google/registry/tools/wildcard.yaml @@ -8,6 +8,10 @@ claimsPeriodEnd: "294247-01-10T04:00:54.775Z" createBillingCost: currency: "USD" amount: 25.00 +createBillingCostTransitions: + "1970-01-01T00:00:00.000Z": + currency: "USD" + amount: 25.00 creationTime: "2022-09-01T00:00:00.000Z" currency: "USD" defaultPromoTokens: [] diff --git a/db/src/main/resources/sql/schema/db-schema.sql.generated b/db/src/main/resources/sql/schema/db-schema.sql.generated index 994980ab8..d61ce3053 100644 --- a/db/src/main/resources/sql/schema/db-schema.sql.generated +++ b/db/src/main/resources/sql/schema/db-schema.sql.generated @@ -740,6 +740,7 @@ claims_period_end timestamptz not null, create_billing_cost_amount numeric(19, 2), create_billing_cost_currency text, + create_billing_cost_transitions hstore, creation_time timestamptz not null, currency text not null, default_promo_tokens text[],