diff --git a/java/google/registry/flows/BUILD b/java/google/registry/flows/BUILD index 2ded8635f..8eaa33348 100644 --- a/java/google/registry/flows/BUILD +++ b/java/google/registry/flows/BUILD @@ -40,6 +40,7 @@ java_library( "//java/google/registry/mapreduce/inputs", "//java/google/registry/model", "//java/google/registry/monitoring/whitebox", + "//java/google/registry/pricing", "//java/google/registry/request", "//java/google/registry/security:servlets", "//java/google/registry/tldconfig/idn", diff --git a/java/google/registry/flows/domain/BaseDomainCreateFlow.java b/java/google/registry/flows/domain/BaseDomainCreateFlow.java index 57a87f2d4..dc5535cb8 100644 --- a/java/google/registry/flows/domain/BaseDomainCreateFlow.java +++ b/java/google/registry/flows/domain/BaseDomainCreateFlow.java @@ -35,6 +35,7 @@ import static google.registry.model.EppResourceUtils.loadByUniqueId; import static google.registry.model.ofy.ObjectifyService.ofy; import static google.registry.model.registry.Registries.findTldForName; import static google.registry.model.registry.label.ReservedList.matchesAnchorTenantReservation; +import static google.registry.pricing.PricingEngineProxy.getDomainCreateCost; import com.google.common.base.Optional; import com.google.common.net.InternetDomainName; @@ -176,8 +177,7 @@ public abstract class BaseDomainCreateFlow getPremiumPrice( + String secondLevelDomainName, DateTime priceTime, String clientIdentifier); +} diff --git a/java/google/registry/model/pricing/StaticPremiumListPricingEngine.java b/java/google/registry/model/pricing/StaticPremiumListPricingEngine.java new file mode 100644 index 000000000..8a114594e --- /dev/null +++ b/java/google/registry/model/pricing/StaticPremiumListPricingEngine.java @@ -0,0 +1,53 @@ +// Copyright 2016 The Domain Registry Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package google.registry.model.pricing; + +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.base.Preconditions.checkState; +import static google.registry.util.DomainNameUtils.getTldFromSld; + +import com.google.common.base.Optional; +import com.google.common.net.InternetDomainName; + +import google.registry.model.registry.Registry; +import google.registry.model.registry.label.PremiumList; + +import org.joda.money.Money; +import org.joda.time.DateTime; + +import javax.inject.Inject; + +/** A premium list pricing engine that stores static pricing information in Datastore entities. */ +public final class StaticPremiumListPricingEngine implements PricingEngine { + + @Inject StaticPremiumListPricingEngine() {} + + @Override + public Optional getPremiumPrice( + String secondLevelDomainName, DateTime priceTime, String clientIdentifier) { + // Note that clientIdentifier and priceTime are not used for determining premium pricing for + // static premium lists. + String tld = getTldFromSld(secondLevelDomainName); + Registry registry = Registry.get(checkNotNull(tld, "tld")); + if (registry.getPremiumList() == null) { + return Optional.absent(); + } + String listName = registry.getPremiumList().getName(); + Optional premiumList = PremiumList.get(listName); + checkState(premiumList.isPresent(), "Could not load premium list: %s", listName); + String label = InternetDomainName.from(secondLevelDomainName).parts().get(0); + return premiumList.get().getPremiumPrice(label); + } +} diff --git a/java/google/registry/model/registry/Registry.java b/java/google/registry/model/registry/Registry.java index acc662235..fb836a7d0 100644 --- a/java/google/registry/model/registry/Registry.java +++ b/java/google/registry/model/registry/Registry.java @@ -21,7 +21,6 @@ import static com.google.common.base.Predicates.not; import static google.registry.model.common.EntityGroupRoot.getCrossTldKey; import static google.registry.model.ofy.ObjectifyService.ofy; import static google.registry.model.ofy.Ofy.RECOMMENDED_MEMCACHE_EXPIRATION; -import static google.registry.model.registry.label.PremiumList.getPremiumPrice; import static google.registry.util.CollectionUtils.nullToEmptyImmutableCopy; import static google.registry.util.DateTimeUtils.END_OF_TIME; import static google.registry.util.PreconditionsUtils.checkArgumentNotNull; @@ -47,6 +46,7 @@ import com.googlecode.objectify.annotation.Embed; import com.googlecode.objectify.annotation.Entity; import com.googlecode.objectify.annotation.Id; import com.googlecode.objectify.annotation.Mapify; +import com.googlecode.objectify.annotation.OnLoad; import com.googlecode.objectify.annotation.OnSave; import com.googlecode.objectify.annotation.Parent; @@ -57,6 +57,8 @@ import google.registry.model.ImmutableObject; import google.registry.model.common.EntityGroupRoot; import google.registry.model.common.TimedTransitionProperty; import google.registry.model.common.TimedTransitionProperty.TimedTransition; +import google.registry.model.pricing.PricingEngine; +import google.registry.model.pricing.StaticPremiumListPricingEngine; import google.registry.model.registry.label.PremiumList; import google.registry.model.registry.label.ReservedList; import google.registry.util.Idn; @@ -238,6 +240,27 @@ public class Registry extends ImmutableObject implements Buildable { CACHE.invalidate(tldStr); } + /** + * Backfill the Registry entities that were saved before this field was added. + * + *

Note that this defaults to the {@link StaticPremiumListPricingEngine}. + */ + // TODO(b/26901539): Remove this backfill once it is populated on all Registry entities. + @OnLoad + void backfillPricingEngine() { + if (pricingEngineClassName == null) { + pricingEngineClassName = StaticPremiumListPricingEngine.class.getCanonicalName(); + } + } + + /** + * The fully qualified canonical classname of the pricing engine that this TLD uses. + * + *

This must be a valid key for the map of pricing engines injected by + * @Inject Map + */ + String pricingEngineClassName; + /** * The unicode-aware representation of the TLD associated with this {@link Registry}. *

@@ -271,7 +294,7 @@ public class Registry extends ImmutableObject implements Buildable { return nullToEmptyImmutableCopy(reservedLists); } - /** The {@link PremiumList} for this TLD. */ + /** The static {@link PremiumList} for this TLD, if there is one. */ Key premiumList; /** Should RDE upload a nightly escrow deposit for this TLD? */ @@ -442,7 +465,10 @@ public class Registry extends ImmutableObject implements Buildable { return currency; } - /** Use {@link #getDomainCreateCost} instead of this to find the cost for a domain create. */ + /** + * Use PricingUtils.getDomainCreateCost instead of this to find the cost for a + * domain create. + */ @VisibleForTesting public Money getStandardCreateCost() { return createBillingCost; @@ -457,8 +483,9 @@ public class Registry extends ImmutableObject implements Buildable { } /** - * Use {@link #getDomainRenewCost} instead of this to find the cost for a domain renew, and all - * derived costs (i.e. autorenews, transfers, and the per-domain part of a restore cost). + * Use PricingUtils.getDomainRenewCost instead of this to find the cost for a domain + * renewal, and all derived costs (i.e. autorenews, transfers, and the per-domain part of a + * restore cost). */ @VisibleForTesting public Money getStandardRenewCost(DateTime now) { @@ -480,47 +507,6 @@ public class Registry extends ImmutableObject implements Buildable { return renewBillingCostTransitions.toValueMap(); } - private Optional getPremiumPriceForSld(String sldName) { - return getPremiumPriceForSld(InternetDomainName.from(sldName)); - } - - private Optional getPremiumPriceForSld(InternetDomainName domainName) { - checkArgument(getTld().equals(domainName.parent()), - "Domain name %s is not an SLD for TLD %s", domainName.toString(), tldStr); - String label = domainName.parts().get(0); - return getPremiumPrice(label, tldStr); - } - - /** Returns true if the given domain name is on the premium price list. */ - public boolean isPremiumName(String domainName, DateTime priceTime, String clientIdentifier) { - return isPremiumName(InternetDomainName.from(domainName), priceTime, clientIdentifier); - } - - /** Returns true if the given domain name is on the premium price list. */ - @SuppressWarnings("unused") - public boolean isPremiumName( - InternetDomainName domainName, DateTime priceTime, String clientIdentifier) { - return getPremiumPriceForSld(domainName).isPresent(); - } - - /** Returns the billing cost for registering the specified domain name for this many years. */ - @SuppressWarnings("unused") - public Money getDomainCreateCost( - String domainName, DateTime priceTime, String clientIdentifier, int years) { - checkArgument(years > 0, "Number of years must be positive"); - Money annualCost = getPremiumPriceForSld(domainName).or(getStandardCreateCost()); - return annualCost.multipliedBy(years); - } - - /** Returns the billing cost for renewing the specified domain name for this many years. */ - @SuppressWarnings("unused") - public Money getDomainRenewCost( - String domainName, DateTime priceTime, String clientIdentifier, int years) { - checkArgument(years > 0, "Number of years must be positive"); - Money annualCost = getPremiumPriceForSld(domainName).or(getStandardRenewCost(priceTime)); - return annualCost.multipliedBy(years); - } - public String getLordnUsername() { return lordnUsername; } @@ -529,6 +515,10 @@ public class Registry extends ImmutableObject implements Buildable { return claimsPeriodEnd; } + public String getPricingEngineClassName() { + return pricingEngineClassName; + } + public ImmutableSet getAllowedRegistrantContactIds() { return nullToEmptyImmutableCopy(allowedRegistrantContactIds); } @@ -595,6 +585,12 @@ public class Registry extends ImmutableObject implements Buildable { return this; } + public Builder setPricingEngineClass(Class pricingEngineClass) { + getInstance().pricingEngineClassName = + checkArgumentNotNull(pricingEngineClass).getCanonicalName(); + return this; + } + public Builder setAddGracePeriodLength(Duration addGracePeriodLength) { checkArgument(addGracePeriodLength.isLongerThan(Duration.ZERO), "addGracePeriodLength must be non-zero"); @@ -800,6 +796,8 @@ public class Registry extends ImmutableObject implements Buildable { return money.getCurrencyUnit().equals(instance.currency); }}), "Renew cost must be in the registry's currency"); + checkArgumentNotNull( + instance.pricingEngineClassName, "All registries must have a configured pricing engine"); instance.tldStrId = tldName; instance.tldUnicode = Idn.toUnicode(tldName); return super.build(); diff --git a/java/google/registry/monitoring/whitebox/WhiteboxModule.java b/java/google/registry/monitoring/whitebox/WhiteboxModule.java index c3596ca39..b98684c53 100644 --- a/java/google/registry/monitoring/whitebox/WhiteboxModule.java +++ b/java/google/registry/monitoring/whitebox/WhiteboxModule.java @@ -14,7 +14,6 @@ package google.registry.monitoring.whitebox; -import static dagger.Provides.Type.MAP; import static google.registry.monitoring.whitebox.EntityIntegrityAlertsSchema.ENTITY_INTEGRITY_ALERTS_SCHEMA_FIELDS; import static google.registry.monitoring.whitebox.EntityIntegrityAlertsSchema.TABLE_ID; import static google.registry.monitoring.whitebox.EppMetrics.EPPMETRICS_SCHEMA_FIELDS; @@ -27,6 +26,7 @@ import com.google.common.collect.ImmutableList; import dagger.Module; import dagger.Provides; +import dagger.multibindings.IntoMap; import dagger.multibindings.StringKey; import google.registry.request.Parameter; @@ -41,13 +41,13 @@ import javax.servlet.http.HttpServletRequest; @Module public class WhiteboxModule { - @Provides(type = MAP) + @Provides @IntoMap @StringKey(EPPMETRICS_TABLE_ID) static ImmutableList provideEppMetricsSchema() { return EPPMETRICS_SCHEMA_FIELDS; } - @Provides(type = MAP) + @Provides @IntoMap @StringKey(TABLE_ID) static ImmutableList provideEntityIntegrityAlertsSchema() { return ENTITY_INTEGRITY_ALERTS_SCHEMA_FIELDS; diff --git a/java/google/registry/pricing/BUILD b/java/google/registry/pricing/BUILD new file mode 100644 index 000000000..d11a79a06 --- /dev/null +++ b/java/google/registry/pricing/BUILD @@ -0,0 +1,28 @@ +package( + default_visibility = ["//java/google/registry:registry_project"], +) + +licenses(["notice"]) # Apache 2.0 + + +java_library( + name = "pricing", + srcs = glob(["*.java"]), + deps = [ + "//java/com/google/common/annotations", + "//java/com/google/common/base", + "//java/com/google/common/collect", + "//java/com/google/common/io", + "//java/com/google/common/net", + "//java/com/google/common/util/concurrent", + "//third_party/java/dagger", + "//third_party/java/joda_money", + "//third_party/java/joda_time", + "//third_party/java/jsr305_annotations", + "//third_party/java/jsr330_inject", + "//third_party/java/objectify:objectify-v4_1", + "//third_party/java/servlet/servlet_api", + "//java/google/registry/model", + "//java/google/registry/util", + ], +) diff --git a/java/google/registry/pricing/PricingComponent.java b/java/google/registry/pricing/PricingComponent.java new file mode 100644 index 000000000..c716d371d --- /dev/null +++ b/java/google/registry/pricing/PricingComponent.java @@ -0,0 +1,36 @@ +// Copyright 2016 The Domain Registry Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package google.registry.pricing; + +import dagger.Component; + +import google.registry.model.pricing.PricingEngine; + +import java.util.Map; + +import javax.inject.Singleton; + +/** + * Dagger component with instance lifetime for pricing engines. + * + *

This component only exists because the flows themselves are not yet injected. Once they are, + * this separate component can be removed, and the pricingEngines() map added to the relevant + * component used to construct the flows. + */ +@Singleton +@Component(modules = {PricingModule.class}) +interface PricingComponent { + Map, PricingEngine> pricingEngines(); +} diff --git a/java/google/registry/pricing/PricingEngineProxy.java b/java/google/registry/pricing/PricingEngineProxy.java new file mode 100644 index 000000000..772e54de8 --- /dev/null +++ b/java/google/registry/pricing/PricingEngineProxy.java @@ -0,0 +1,107 @@ +// Copyright 2016 The Domain Registry Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package google.registry.pricing; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkState; +import static google.registry.model.registry.Registries.assertTldExists; +import static google.registry.util.DomainNameUtils.getTldFromSld; + +import com.google.common.base.Function; +import com.google.common.base.Optional; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Maps; +import com.google.common.net.InternetDomainName; + +import google.registry.model.pricing.PricingEngine; +import google.registry.model.registry.Registry; + +import org.joda.money.Money; +import org.joda.time.DateTime; + +import java.util.Map; + +/** + * A global proxy providing static methods for getting premium prices that dispatches requests + * correctly to the relevant {@link PricingEngine} implementation per TLD. + */ +public final class PricingEngineProxy { + + private static final Map, PricingEngine> pricingEngineClasses = + DaggerPricingComponent.create().pricingEngines(); + + // Dagger map keys have to be provided with constant values that are known at compile time, so it + // can't be done using clazz.getCanonicalName(). So we construct the map by canonical name here, + // at runtime. + private static final ImmutableMap pricingEngines = + Maps.uniqueIndex( + pricingEngineClasses.values(), + new Function() { + @Override + public String apply(PricingEngine pricingEngine) { + return pricingEngine.getClass().getCanonicalName(); + }}); + + /** Returns true if the given domain name is on the premium price list. */ + public static boolean isPremiumName( + String domainName, DateTime priceTime, String clientIdentifier) { + return isPremiumName(InternetDomainName.from(domainName), priceTime, clientIdentifier); + } + + /** Returns true if the given domain name is on the premium price list. */ + public static boolean isPremiumName( + InternetDomainName domainName, DateTime priceTime, String clientIdentifier) { + return getPremiumPriceForDomainName(domainName, priceTime, clientIdentifier).isPresent(); + } + + /** Returns the billing cost for registering the specified domain name for this many years. */ + public static Money getDomainCreateCost( + String domainName, DateTime priceTime, String clientIdentifier, int years) { + checkArgument(years > 0, "Number of years must be positive"); + Optional annualCost = + getPremiumPriceForDomainName( + InternetDomainName.from(domainName), priceTime, clientIdentifier); + return annualCost + .or(Registry.get(getTldFromSld(domainName)).getStandardCreateCost()) + .multipliedBy(years); + } + + /** Returns the billing cost for renewing the specified domain name for this many years. */ + public static Money getDomainRenewCost( + String domainName, DateTime priceTime, String clientIdentifier, int years) { + checkArgument(years > 0, "Number of years must be positive"); + Optional annualCost = + getPremiumPriceForDomainName( + InternetDomainName.from(domainName), priceTime, clientIdentifier); + return annualCost + .or(Registry.get(getTldFromSld(domainName)).getStandardRenewCost(priceTime)) + .multipliedBy(years); + } + + /** + * Returns whether the given domain name is premium by dispatching to the appropriate + * {@link PricingEngine} based on what is configured for the TLD that the domain is under. + */ + private static Optional getPremiumPriceForDomainName( + InternetDomainName domainName, DateTime priceTime, String clientIdentifier) { + String tld = assertTldExists(getTldFromSld(domainName)); + String clazz = Registry.get(tld).getPricingEngineClassName(); + PricingEngine engine = pricingEngines.get(clazz); + checkState(engine != null, "Could not load pricing engine %s for TLD %s", clazz, tld); + return engine.getPremiumPrice(domainName.toString(), priceTime, clientIdentifier); + } + + private PricingEngineProxy() {} +} diff --git a/java/google/registry/pricing/PricingModule.java b/java/google/registry/pricing/PricingModule.java new file mode 100644 index 000000000..ed6e07fad --- /dev/null +++ b/java/google/registry/pricing/PricingModule.java @@ -0,0 +1,47 @@ +// Copyright 2016 The Domain Registry Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package google.registry.pricing; + +import dagger.MapKey; +import dagger.Module; +import dagger.Provides; +import dagger.multibindings.IntoMap; + +import google.registry.model.pricing.PricingEngine; +import google.registry.model.pricing.StaticPremiumListPricingEngine; + +/** + * Dagger module for injecting pricing engines. + * + *

To add a new pricing engine, create a new class that implements {@link PricingEngine}, and add + * a module that provides an instance of PricingEngine with a PricingEngineClassKey + * annotation with the class of the implementation and also @Provides @IntoMap + * annotations. + */ +@Module +public class PricingModule { + + /** The annotation used for PricingEngine implementation keys. */ + @MapKey + @interface PricingEngineClassKey { + Class value(); + } + + @Provides @IntoMap + @PricingEngineClassKey(StaticPremiumListPricingEngine.class) + static PricingEngine provideStaticPremiumList(StaticPremiumListPricingEngine engine) { + return engine; + } +} diff --git a/java/google/registry/repositories.bzl b/java/google/registry/repositories.bzl index 10430a78a..f456c61d6 100644 --- a/java/google/registry/repositories.bzl +++ b/java/google/registry/repositories.bzl @@ -190,20 +190,20 @@ def domain_registry_repositories(): native.maven_jar( name = "dagger", - artifact = "com.google.dagger:dagger:2.0.2", - sha1 = "de8416eda7b2fd7c25836b140c39e1cbf10542f6", + artifact = "com.google.dagger:dagger:2.4", + sha1 = "6b290a792253035c9fcc912d6a4d7efb3e850211", ) native.maven_jar( name = "dagger_compiler", - artifact = "com.google.dagger:dagger-compiler:2.0.2", - sha1 = "1170f75c1ce293f80755bbc9fcd60e0765022bd0", + artifact = "com.google.dagger:dagger-compiler:2.4", + sha1 = "01053c9ef441e93088c9261c33163f6af30766b7", ) native.maven_jar( name = "dagger_producers", - artifact = "com.google.dagger:dagger-producers:2.0-beta", - sha1 = "80276338d1c2542ebebac542b535d1ecd48a3fd7", + artifact = "com.google.dagger:dagger-producers:2.4", + sha1 = "f334a19afdc2ce2d8d5191f8a0fac2321bdd50fc", ) native.maven_jar( diff --git a/java/google/registry/tools/BUILD b/java/google/registry/tools/BUILD index e8a021582..fc874f97d 100644 --- a/java/google/registry/tools/BUILD +++ b/java/google/registry/tools/BUILD @@ -49,6 +49,7 @@ java_library( "//java/google/registry/flows", "//java/google/registry/keyring/api", "//java/google/registry/model", + "//java/google/registry/pricing", "//java/google/registry/rde", "//java/google/registry/security", "//java/google/registry/request:modules", diff --git a/java/google/registry/tools/CreateAnchorTenantCommand.java b/java/google/registry/tools/CreateAnchorTenantCommand.java index d4944e0b6..86a7271a8 100644 --- a/java/google/registry/tools/CreateAnchorTenantCommand.java +++ b/java/google/registry/tools/CreateAnchorTenantCommand.java @@ -17,6 +17,7 @@ package google.registry.tools; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Strings.isNullOrEmpty; import static google.registry.model.registry.Registries.findTldForNameOrThrow; +import static google.registry.pricing.PricingEngineProxy.getDomainCreateCost; import static org.joda.time.DateTimeZone.UTC; import com.google.common.net.InternetDomainName; @@ -25,7 +26,6 @@ import com.google.template.soy.data.SoyMapData; import com.beust.jcommander.Parameter; import com.beust.jcommander.Parameters; -import google.registry.model.registry.Registry; import google.registry.tools.Command.GtechCommand; import google.registry.tools.soy.CreateAnchorTenantSoyInfo; @@ -81,15 +81,15 @@ final class CreateAnchorTenantCommand extends MutatingEppToolCommand implements @Override protected void initMutatingEppToolCommand() { checkArgument(superuser, "This command must be run as a superuser."); - String tld = findTldForNameOrThrow(InternetDomainName.from(domainName)).toString(); + findTldForNameOrThrow(InternetDomainName.from(domainName)); // Check that the tld exists. if (isNullOrEmpty(password)) { password = passwordGenerator.createPassword(PASSWORD_LENGTH); } Money cost = null; if (fee) { - cost = Registry.get(tld) - .getDomainCreateCost( + cost = + getDomainCreateCost( domainName, DateTime.now(UTC), clientIdentifier, DEFAULT_ANCHOR_TENANT_PERIOD_YEARS); } diff --git a/java/google/registry/tools/CreateOrUpdateTldCommand.java b/java/google/registry/tools/CreateOrUpdateTldCommand.java index 8a48469bb..22a73d4ea 100644 --- a/java/google/registry/tools/CreateOrUpdateTldCommand.java +++ b/java/google/registry/tools/CreateOrUpdateTldCommand.java @@ -35,6 +35,7 @@ import com.google.common.collect.ImmutableSortedMap; import com.beust.jcommander.Parameter; import com.googlecode.objectify.Key; +import google.registry.model.pricing.StaticPremiumListPricingEngine; import google.registry.model.registry.Registries; import google.registry.model.registry.Registry; import google.registry.model.registry.Registry.TldState; @@ -259,8 +260,13 @@ abstract class CreateOrUpdateTldCommand extends MutatingCommand { "The roid suffix %s is already in use", roidSuffix); } - Registry.Builder builder = oldRegistry == null - ? new Registry.Builder().setTldStr(tld) : oldRegistry.asBuilder(); + // TODO(b/26901539): Add a flag to set the pricing engine once we have more than one option. + Registry.Builder builder = + oldRegistry == null + ? new Registry.Builder() + .setTldStr(tld) + .setPricingEngineClass(StaticPremiumListPricingEngine.class) + : oldRegistry.asBuilder(); if (escrow != null) { builder.setEscrowEnabled(escrow); diff --git a/java/google/registry/tools/CreatePremiumListCommand.java b/java/google/registry/tools/CreatePremiumListCommand.java index df3ee97f1..fbbdecd92 100644 --- a/java/google/registry/tools/CreatePremiumListCommand.java +++ b/java/google/registry/tools/CreatePremiumListCommand.java @@ -22,13 +22,10 @@ import com.beust.jcommander.Parameters; import google.registry.model.registry.label.PremiumList; import google.registry.tools.server.CreatePremiumListAction; -import javax.annotation.Nullable; - /** Command to create a {@link PremiumList} on Datastore. */ @Parameters(separators = " =", commandDescription = "Create a PremiumList in Datastore.") public class CreatePremiumListCommand extends CreateOrUpdatePremiumListCommand { - @Nullable @Parameter( names = {"-o", "--override"}, description = "Override restrictions on premium list naming") diff --git a/javatests/google/registry/flows/BUILD b/javatests/google/registry/flows/BUILD index ab253abe8..5040d2925 100644 --- a/javatests/google/registry/flows/BUILD +++ b/javatests/google/registry/flows/BUILD @@ -46,6 +46,7 @@ java_library( "//java/google/registry/mapreduce", "//java/google/registry/model", "//java/google/registry/monitoring/whitebox", + "//java/google/registry/pricing", "//java/google/registry/request", "//java/google/registry/security", "//java/google/registry/security:servlets", diff --git a/javatests/google/registry/flows/domain/DomainCreateFlowTest.java b/javatests/google/registry/flows/domain/DomainCreateFlowTest.java index 3abb55d67..3ecf36317 100644 --- a/javatests/google/registry/flows/domain/DomainCreateFlowTest.java +++ b/javatests/google/registry/flows/domain/DomainCreateFlowTest.java @@ -16,6 +16,7 @@ package google.registry.flows.domain; import static com.google.common.io.BaseEncoding.base16; import static com.google.common.truth.Truth.assertThat; +import static google.registry.pricing.PricingEngineProxy.isPremiumName; import static google.registry.testing.DatastoreHelper.assertBillingEvents; import static google.registry.testing.DatastoreHelper.createTld; import static google.registry.testing.DatastoreHelper.deleteTld; @@ -179,10 +180,9 @@ public class DomainCreateFlowTest extends ResourceFlowTestCase