Add java changes for createBillingCostTransitions (#2314)

* Add java changes for createBillingCostTransitions

* Add negative cost test

* Remove default value

* remove unused variable

* Add check that create cost and trnasitions map are the same

* inject clock, only use key set when checking for missing fields

* Add test for removing map
This commit is contained in:
sarahcaseybot 2024-02-09 12:08:51 -05:00 committed by GitHub
parent 7b47ecb1f1
commit abc1a0ef3d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
14 changed files with 391 additions and 4 deletions

View file

@ -74,6 +74,7 @@ import google.registry.tldconfig.idn.IdnTableEnum;
import google.registry.util.Idn; import google.registry.util.Idn;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects;
import java.util.Optional; import java.util.Optional;
import java.util.Set; import java.util.Set;
import java.util.function.Predicate; import java.util.function.Predicate;
@ -458,6 +459,8 @@ public class Tld extends ImmutableObject implements Buildable, UnsafeSerializabl
@JsonDeserialize(using = CurrencyDeserializer.class) @JsonDeserialize(using = CurrencyDeserializer.class)
CurrencyUnit currency = DEFAULT_CURRENCY; 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. */ /** The per-year billing cost for registering a new domain name. */
@Type(type = JodaMoneyType.TYPE_NAME) @Type(type = JodaMoneyType.TYPE_NAME)
@Columns( @Columns(
@ -467,6 +470,12 @@ public class Tld extends ImmutableObject implements Buildable, UnsafeSerializabl
}) })
Money createBillingCost = DEFAULT_CREATE_BILLING_COST; 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<Money> createBillingCostTransitions;
/** The one-time billing cost for restoring a domain name from the redemption grace period. */ /** The one-time billing cost for restoring a domain name from the redemption grace period. */
@Type(type = JodaMoneyType.TYPE_NAME) @Type(type = JodaMoneyType.TYPE_NAME)
@Columns( @Columns(
@ -676,6 +685,13 @@ public class Tld extends ImmutableObject implements Buildable, UnsafeSerializabl
return createBillingCost; return createBillingCost;
} }
public ImmutableSortedMap<DateTime, Money> 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 * 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). * year of renewal for that name).
@ -959,6 +975,17 @@ public class Tld extends ImmutableObject implements Buildable, UnsafeSerializabl
return this; return this;
} }
public Builder setCreateBillingCostTransitions(
ImmutableSortedMap<DateTime, Money> 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<String> reservedListNames) { public Builder setReservedListsByName(Set<String> reservedListNames) {
// TODO(b/309175133): forbid if enrolled with BSA // TODO(b/309175133): forbid if enrolled with BSA
checkArgument(reservedListNames != null, "reservedListNames must not be null"); 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 // 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. // and cloned it into a new builder, to block re-building a Tld in an invalid state.
instance.tldStateTransitions.checkValidity(); 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.renewBillingCostTransitions.checkValidity();
instance.eapFeeSchedule.checkValidity(); instance.eapFeeSchedule.checkValidity();
// All costs must be in the expected currency. // All costs must be in the expected currency.

View file

@ -14,6 +14,7 @@
package google.registry.tools; package google.registry.tools;
import static com.google.common.base.Preconditions.checkArgument; 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.Tld.Builder.ROID_SUFFIX_PATTERN;
import static google.registry.model.tld.Tlds.getTlds; import static google.registry.model.tld.Tlds.getTlds;
import static google.registry.util.ListNamingUtils.convertFilePathToName; 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;
import com.google.common.collect.Sets.SetView; import com.google.common.collect.Sets.SetView;
import com.google.common.flogger.FluentLogger; import com.google.common.flogger.FluentLogger;
import google.registry.model.common.TimedTransitionProperty;
import google.registry.model.tld.Tld; import google.registry.model.tld.Tld;
import google.registry.model.tld.label.PremiumList; import google.registry.model.tld.label.PremiumList;
import google.registry.model.tld.label.PremiumListDao; import google.registry.model.tld.label.PremiumListDao;
import google.registry.tools.params.PathParameter; import google.registry.tools.params.PathParameter;
import google.registry.util.Clock;
import google.registry.util.Idn; import google.registry.util.Idn;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
@ -40,9 +43,11 @@ import java.nio.file.Path;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashSet; import java.util.HashSet;
import java.util.Map; import java.util.Map;
import java.util.Objects;
import java.util.Optional; import java.util.Optional;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Named; import javax.inject.Named;
import org.joda.money.CurrencyUnit; import org.joda.money.CurrencyUnit;
@ -90,6 +95,8 @@ public class ConfigureTldCommand extends MutatingCommand {
@Inject ObjectMapper mapper; @Inject ObjectMapper mapper;
@Inject Clock clock;
@Inject @Inject
@Named("dnsWriterNames") @Named("dnsWriterNames")
Set<String> validDnsWriterNames; Set<String> validDnsWriterNames;
@ -114,8 +121,11 @@ public class ConfigureTldCommand extends MutatingCommand {
String name = convertFilePathToName(inputFile); String name = convertFilePathToName(inputFile);
Map<String, Object> tldData = new Yaml().load(Files.newBufferedReader(inputFile)); Map<String, Object> tldData = new Yaml().load(Files.newBufferedReader(inputFile));
checkName(name, tldData); checkName(name, tldData);
checkForMissingFields(tldData);
Tld oldTld = getTlds().contains(name) ? Tld.get(name) : null; 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); Tld newTld = mapper.readValue(inputFile.toFile(), Tld.class);
if (oldTld != null) { if (oldTld != null) {
oldTldInBreakGlass = oldTld.getBreakglassMode(); oldTldInBreakGlass = oldTld.getBreakglassMode();
@ -146,6 +156,14 @@ public class ConfigureTldCommand extends MutatingCommand {
checkPremiumList(newTld); checkPremiumList(newTld);
checkDnsWriters(newTld); checkDnsWriters(newTld);
checkCurrency(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 // bsaEnrollStartTime only exists in DB. Need to carry it over to the updated copy. See Tld.java
// for more information. // for more information.
Optional<DateTime> bsaEnrollTime = Optional<DateTime> bsaEnrollTime =
@ -198,7 +216,7 @@ public class ConfigureTldCommand extends MutatingCommand {
ROID_SUFFIX_PATTERN.pattern()); ROID_SUFFIX_PATTERN.pattern());
} }
private void checkForMissingFields(Map<String, Object> tldData) { private void checkForMissingFields(ImmutableSet<String> keySet) {
Set<String> tldFields = Set<String> tldFields =
Arrays.stream(Tld.class.getDeclaredFields()) Arrays.stream(Tld.class.getDeclaredFields())
.filter(field -> !Modifier.isStatic(field.getModifiers())) .filter(field -> !Modifier.isStatic(field.getModifiers()))
@ -207,7 +225,7 @@ public class ConfigureTldCommand extends MutatingCommand {
.collect(Collectors.toSet()); .collect(Collectors.toSet());
Set<String> missingFields = new HashSet<>(); Set<String> missingFields = new HashSet<>();
for (String field : tldFields) { for (String field : tldFields) {
if (!tldData.containsKey(field)) { if (!keySet.contains(field)) {
missingFields.add(field); missingFields.add(field);
} }
} }

View file

@ -46,6 +46,7 @@ import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSortedMap; import com.google.common.collect.ImmutableSortedMap;
import google.registry.dns.writer.VoidDnsWriter; import google.registry.dns.writer.VoidDnsWriter;
import google.registry.model.EntityTestCase; import google.registry.model.EntityTestCase;
import google.registry.model.common.TimedTransitionProperty;
import google.registry.model.domain.token.AllocationToken; import google.registry.model.domain.token.AllocationToken;
import google.registry.model.tld.Tld.TldNotFoundException; import google.registry.model.tld.Tld.TldNotFoundException;
import google.registry.model.tld.Tld.TldState; import google.registry.model.tld.Tld.TldState;
@ -149,6 +150,8 @@ public final class TldTest extends EntityTestCase {
.asBuilder() .asBuilder()
.setDnsAPlusAaaaTtl(Duration.standardHours(1)) .setDnsAPlusAaaaTtl(Duration.standardHours(1))
.setDnsWriters(ImmutableSet.of("baz", "bang")) .setDnsWriters(ImmutableSet.of("baz", "bang"))
.setCreateBillingCostTransitions(
TimedTransitionProperty.withInitialValue(Money.of(USD, 13)).toValueMap())
.setEapFeeSchedule( .setEapFeeSchedule(
ImmutableSortedMap.of( ImmutableSortedMap.of(
START_OF_TIME, START_OF_TIME,
@ -170,7 +173,12 @@ public final class TldTest extends EntityTestCase {
@Test @Test
void testSuccess_tldYamlRoundtrip() throws Exception { 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(); ObjectMapper mapper = createObjectMapper();
String yaml = mapper.writeValueAsString(testTld); String yaml = mapper.writeValueAsString(testTld);
Tld constructedTld = mapper.readValue(yaml, Tld.class); 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)); assertThat(registry.getRestoreBillingCost()).isEqualTo(Money.of(USD, 17));
} }
@Test
void testSetCreateBillingCostTransitions() {
ImmutableSortedMap<DateTime, Money> 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<DateTime, Money> 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 @Test
void testSettingRestoreBillingCost() { void testSettingRestoreBillingCost() {
Tld registry = Tld.get("tld").asBuilder().setRestoreBillingCost(Money.of(USD, 42)).build(); Tld registry = Tld.get("tld").asBuilder().setRestoreBillingCost(Money.of(USD, 42)).build();

View file

@ -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.EXTENDED_LATIN;
import static google.registry.tldconfig.idn.IdnTableEnum.JA; import static google.registry.tldconfig.idn.IdnTableEnum.JA;
import static google.registry.tldconfig.idn.IdnTableEnum.UNCONFUSABLE_LATIN; 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.nio.charset.StandardCharsets.UTF_8;
import static java.util.logging.Level.INFO; import static java.util.logging.Level.INFO;
import static org.joda.money.CurrencyUnit.JPY; 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.base.Ascii;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSortedMap;
import com.google.common.io.Files; import com.google.common.io.Files;
import com.google.common.testing.TestLogHandler; import com.google.common.testing.TestLogHandler;
import google.registry.model.domain.token.AllocationToken; import google.registry.model.domain.token.AllocationToken;
@ -70,6 +72,7 @@ public class ConfigureTldCommandTest extends CommandTestCase<ConfigureTldCommand
command.mapper = objectMapper; command.mapper = objectMapper;
premiumList = persistPremiumList("test", USD, "silver,USD 50", "gold,USD 80"); premiumList = persistPremiumList("test", USD, "silver,USD 50", "gold,USD 80");
command.validDnsWriterNames = ImmutableSet.of("VoidDnsWriter", "FooDnsWriter"); command.validDnsWriterNames = ImmutableSet.of("VoidDnsWriter", "FooDnsWriter");
command.clock = fakeClock;
logger.addHandler(logHandler); logger.addHandler(logHandler);
} }
@ -173,6 +176,57 @@ public class ConfigureTldCommandTest extends CommandTestCase<ConfigureTldCommand
assertThat(updatedTld.getCreateBillingCost()).isEqualTo(Money.of(USD, 25)); assertThat(updatedTld.getCreateBillingCost()).isEqualTo(Money.of(USD, 25));
} }
@Test
void testSuccess_fileMissingCreateBillingCostTransitions() throws Exception {
createTld("nocreatecostmap");
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 testSuccess_fileMissingCreateBillingCostTransitionsRevertsToBasicConstructedMap()
throws Exception {
ImmutableSortedMap<DateTime, Money> 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 @Test
void testFailure_fileMissingNullableFieldsOnCreate() throws Exception { void testFailure_fileMissingNullableFieldsOnCreate() throws Exception {
File tldFile = tmpDir.resolve("missingnullablefields.yaml").toFile(); File tldFile = tmpDir.resolve("missingnullablefields.yaml").toFile();
@ -185,6 +239,20 @@ public class ConfigureTldCommandTest extends CommandTestCase<ConfigureTldCommand
+ " premiumListName, currency, numDnsPublishLocks]"); + " premiumListName, currency, numDnsPublishLocks]");
} }
@Test
void testSuccess_addCreateBillingCostTransitions() throws Exception {
createTld("costmap");
File tldFile = tmpDir.resolve("costmap.yaml").toFile();
Files.asCharSink(tldFile, UTF_8).write(loadFile(getClass(), "costmap.yaml"));
runCommandForced("--input=" + tldFile);
Tld updatedTld = Tld.get("costmap");
ImmutableSortedMap<DateTime, Money> 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 @Test
void testFailure_fileMissingNullableFieldOnUpdate() throws Exception { void testFailure_fileMissingNullableFieldOnUpdate() throws Exception {
Tld tld = createTld("missingnullablefields"); Tld tld = createTld("missingnullablefields");

View file

@ -19,14 +19,17 @@ import static google.registry.testing.DatabaseHelper.createTlds;
import static google.registry.testing.DatabaseHelper.persistPremiumList; import static google.registry.testing.DatabaseHelper.persistPremiumList;
import static google.registry.testing.DatabaseHelper.persistResource; import static google.registry.testing.DatabaseHelper.persistResource;
import static google.registry.testing.TestDataHelper.loadFile; 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.joda.money.CurrencyUnit.USD;
import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertThrows;
import com.beust.jcommander.ParameterException; import com.beust.jcommander.ParameterException;
import com.google.common.collect.ImmutableSortedMap;
import google.registry.model.EntityYamlUtils; import google.registry.model.EntityYamlUtils;
import google.registry.model.tld.Tld; import google.registry.model.tld.Tld;
import google.registry.model.tld.label.PremiumList; import google.registry.model.tld.label.PremiumList;
import org.joda.money.Money; import org.joda.money.Money;
import org.joda.time.DateTime;
import org.joda.time.Duration; import org.joda.time.Duration;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
@ -48,6 +51,12 @@ class GetTldCommandTest extends CommandTestCase<GetTldCommand> {
.setDnsAPlusAaaaTtl(Duration.standardMinutes(15)) .setDnsAPlusAaaaTtl(Duration.standardMinutes(15))
.setDriveFolderId("driveFolder") .setDriveFolderId("driveFolder")
.setCreateBillingCost(Money.of(USD, 25)) .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) .setPremiumList(premiumList)
.build()); .build());
runCommand("tld"); runCommand("tld");

View file

@ -9,6 +9,10 @@ claimsPeriodEnd: "294247-01-10T04:00:54.775Z"
createBillingCost: createBillingCost:
currency: "USD" currency: "USD"
amount: 13.00 amount: 13.00
createBillingCostTransitions:
"1970-01-01T00:00:00.000Z":
currency: "USD"
amount: 13.00
creationTime: "1970-01-01T00:00:00.000Z" creationTime: "1970-01-01T00:00:00.000Z"
currency: "USD" currency: "USD"
defaultPromoTokens: defaultPromoTokens:

View file

@ -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"

View file

@ -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"

View file

@ -12,6 +12,10 @@ claimsPeriodEnd: "294247-01-10T04:00:54.775Z"
createBillingCost: createBillingCost:
currency: "USD" currency: "USD"
amount: 13.00 amount: 13.00
createBillingCostTransitions:
"1970-01-01T00:00:00.000Z":
currency: "USD"
amount: 13.00
creationTime: "2022-09-01T00:00:00.000Z" creationTime: "2022-09-01T00:00:00.000Z"
currency: "USD" currency: "USD"
defaultPromoTokens: [] defaultPromoTokens: []

View file

@ -8,6 +8,10 @@ claimsPeriodEnd: "294247-01-10T04:00:54.775Z"
createBillingCost: createBillingCost:
currency: "JPY" currency: "JPY"
amount: 250 amount: 250
createBillingCostTransitions:
"1970-01-01T00:00:00.000Z":
currency: "JPY"
amount: 250
creationTime: "2022-09-01T00:00:00.000Z" creationTime: "2022-09-01T00:00:00.000Z"
currency: "JPY" currency: "JPY"
defaultPromoTokens: [] defaultPromoTokens: []

View file

@ -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"

View file

@ -8,6 +8,13 @@ claimsPeriodEnd: "294247-01-10T04:00:54.775Z"
createBillingCost: createBillingCost:
currency: "USD" currency: "USD"
amount: 25.00 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" creationTime: "2022-09-01T00:00:00.000Z"
currency: "USD" currency: "USD"
defaultPromoTokens: [] defaultPromoTokens: []

View file

@ -8,6 +8,10 @@ claimsPeriodEnd: "294247-01-10T04:00:54.775Z"
createBillingCost: createBillingCost:
currency: "USD" currency: "USD"
amount: 25.00 amount: 25.00
createBillingCostTransitions:
"1970-01-01T00:00:00.000Z":
currency: "USD"
amount: 25.00
creationTime: "2022-09-01T00:00:00.000Z" creationTime: "2022-09-01T00:00:00.000Z"
currency: "USD" currency: "USD"
defaultPromoTokens: [] defaultPromoTokens: []

View file

@ -740,6 +740,7 @@
claims_period_end timestamptz not null, claims_period_end timestamptz not null,
create_billing_cost_amount numeric(19, 2), create_billing_cost_amount numeric(19, 2),
create_billing_cost_currency text, create_billing_cost_currency text,
create_billing_cost_transitions hstore,
creation_time timestamptz not null, creation_time timestamptz not null,
currency text not null, currency text not null,
default_promo_tokens text[], default_promo_tokens text[],