diff --git a/java/google/registry/model/registry/Registry.java b/java/google/registry/model/registry/Registry.java index 3d1889585..6644a852a 100644 --- a/java/google/registry/model/registry/Registry.java +++ b/java/google/registry/model/registry/Registry.java @@ -111,6 +111,7 @@ public class Registry extends ImmutableObject implements Buildable { public static final Duration DEFAULT_ANCHOR_TENANT_ADD_GRACE_PERIOD = Duration.standardDays(30); public static final CurrencyUnit DEFAULT_CURRENCY = USD; public static final Money DEFAULT_CREATE_BILLING_COST = Money.of(USD, 8); + public static final Money DEFAULT_EAP_BILLING_COST = Money.of(USD, 0); public static final Money DEFAULT_RENEW_BILLING_COST = Money.of(USD, 8); public static final Money DEFAULT_RESTORE_BILLING_COST = Money.of(USD, 100); public static final Money DEFAULT_SERVER_STATUS_CHANGE_BILLING_COST = Money.of(USD, 20); @@ -360,6 +361,13 @@ public class Registry extends ImmutableObject implements Buildable { TimedTransitionProperty renewBillingCostTransitions = TimedTransitionProperty.forMapify(DEFAULT_RENEW_BILLING_COST, BillingCostTransition.class); + /** + * A property that tracks the EAP fee schedule (if any) for the TLD. + */ + @Mapify(TimedTransitionProperty.TimeMapper.class) + TimedTransitionProperty eapFeeSchedule = + TimedTransitionProperty.forMapify(DEFAULT_EAP_BILLING_COST, BillingCostTransition.class); + String lordnUsername; /** The end of the claims period (at or after this time, claims no longer applies). */ @@ -510,6 +518,13 @@ public class Registry extends ImmutableObject implements Buildable { return renewBillingCostTransitions.toValueMap(); } + /** + * Returns the EAP fee for the registry at the given time. + */ + public Money getEapFeeFor(DateTime now) { + return eapFeeSchedule.getValueAtTime(now); + } + public String getLordnUsername() { return lordnUsername; } @@ -714,7 +729,7 @@ public class Registry extends ImmutableObject implements Buildable { */ public Builder setRenewBillingCostTransitions( ImmutableSortedMap renewCostsMap) { - checkNotNull(renewCostsMap, "renew billing costs map cannot be null"); + checkArgumentNotNull(renewCostsMap, "renew billing costs map cannot be null"); checkArgument(Iterables.all( renewCostsMap.values(), new Predicate() { @@ -728,6 +743,25 @@ public class Registry extends ImmutableObject implements Buildable { return this; } + /** + * Sets the EAP fee schedule for the TLD. + */ + public Builder setEapFeeSchedule( + ImmutableSortedMap eapFeeSchedule) { + checkArgumentNotNull(eapFeeSchedule, "EAP schedule map cannot be null"); + checkArgument(Iterables.all( + eapFeeSchedule.values(), + new Predicate() { + @Override + public boolean apply(Money amount) { + return amount.isPositiveOrZero(); + }}), + "EAP fee cannot be negative"); + getInstance().eapFeeSchedule = + TimedTransitionProperty.fromValueMap(eapFeeSchedule, BillingCostTransition.class); + return this; + } + public Builder setRoidSuffix(String roidSuffix) { getInstance().roidSuffix = roidSuffix; return this; @@ -779,6 +813,7 @@ public class Registry extends ImmutableObject implements Buildable { // cloned it into a new builder, to block re-building a Registry in an invalid state. instance.tldStateTransitions.checkValidity(); instance.renewBillingCostTransitions.checkValidity(); + instance.eapFeeSchedule.checkValidity(); // All costs must be in the expected currency. // TODO(b/21854155): When we move PremiumList into datastore, verify its currency too. checkArgument( diff --git a/javatests/google/registry/model/registry/RegistryTest.java b/javatests/google/registry/model/registry/RegistryTest.java index 396068be3..61bf1c5f5 100644 --- a/javatests/google/registry/model/registry/RegistryTest.java +++ b/javatests/google/registry/model/registry/RegistryTest.java @@ -413,4 +413,25 @@ public class RegistryTest extends EntityTestCase { thrown.expect(IllegalArgumentException.class, "cost must be in the registry's currency"); Registry.get("tld").asBuilder().setServerStatusChangeBillingCost(Money.of(EUR, 42)).build(); } + + @Test + public void testEapFee_undefined() { + assertThat(Registry.get("tld").getEapFeeFor(clock.nowUtc())).isEqualTo(Money.of(USD, 0)); + } + + @Test + public void testEapFee_specified() { + DateTime a = clock.nowUtc().minusDays(1); + DateTime b = clock.nowUtc().plusDays(1); + Registry registry = + Registry.get("tld").asBuilder().setEapFeeSchedule( + ImmutableSortedMap.of( + START_OF_TIME, Money.of(USD, 0), + a, Money.of(USD, 100), + b, Money.of(USD, 50))).build(); + + assertThat(registry.getEapFeeFor(clock.nowUtc())).isEqualTo(Money.of(USD, 100)); + assertThat(registry.getEapFeeFor(clock.nowUtc().minusDays(2))).isEqualTo(Money.of(USD, 0)); + assertThat(registry.getEapFeeFor(clock.nowUtc().plusDays(2))).isEqualTo(Money.of(USD, 50)); + } }