mirror of
https://github.com/google/nomulus.git
synced 2025-05-17 17:59:41 +02:00
Add additional return values to PricingEngine interface
------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=123658519
This commit is contained in:
parent
ca585dd0b5
commit
91f6c7006e
21 changed files with 191 additions and 191 deletions
|
@ -181,7 +181,7 @@ public abstract class BaseDomainCreateFlow<R extends DomainBase, B extends Build
|
||||||
tldState = registry.getTldState(now);
|
tldState = registry.getTldState(now);
|
||||||
checkRegistryStateForTld(tld);
|
checkRegistryStateForTld(tld);
|
||||||
domainLabel = domainName.parts().get(0);
|
domainLabel = domainName.parts().get(0);
|
||||||
createCost = getDomainCreateCost(targetId, now, getClientId(), command.getPeriod().getValue());
|
createCost = getDomainCreateCost(targetId, now, command.getPeriod().getValue());
|
||||||
// The TLD should always be the parent of the requested domain name.
|
// The TLD should always be the parent of the requested domain name.
|
||||||
isAnchorTenantViaReservation = matchesAnchorTenantReservation(
|
isAnchorTenantViaReservation = matchesAnchorTenantReservation(
|
||||||
domainLabel, tld, command.getAuthInfo().getPw().getValue());
|
domainLabel, tld, command.getAuthInfo().getPw().getValue());
|
||||||
|
|
|
@ -106,8 +106,7 @@ public class DomainAllocateFlow extends DomainCreateOrAllocateFlow {
|
||||||
.setClientId(getClientId())
|
.setClientId(getClientId())
|
||||||
// Note that the cost is calculated as of now, i.e. the event time, not the billing time,
|
// Note that the cost is calculated as of now, i.e. the event time, not the billing time,
|
||||||
// which may be some additional days into the future.
|
// which may be some additional days into the future.
|
||||||
.setCost(
|
.setCost(getDomainCreateCost(targetId, now, command.getPeriod().getValue()))
|
||||||
getDomainCreateCost(targetId, now, getClientId(), command.getPeriod().getValue()))
|
|
||||||
.setPeriodYears(command.getPeriod().getValue())
|
.setPeriodYears(command.getPeriod().getValue())
|
||||||
.setEventTime(now)
|
.setEventTime(now)
|
||||||
// If there are no nameservers on the domain, then they get the benefit of the sunrush
|
// If there are no nameservers on the domain, then they get the benefit of the sunrush
|
||||||
|
|
|
@ -139,7 +139,7 @@ public class DomainApplicationCreateFlow extends BaseDomainCreateFlow<DomainAppl
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void verifyDomainCreateIsAllowed() throws EppException {
|
protected void verifyDomainCreateIsAllowed() throws EppException {
|
||||||
validateFeeChallenge(targetId, getTld(), now, getClientId(), feeCreate, createCost);
|
validateFeeChallenge(targetId, getTld(), now, feeCreate, createCost);
|
||||||
if (tldState == TldState.LANDRUSH && !superuser) {
|
if (tldState == TldState.LANDRUSH && !superuser) {
|
||||||
// Prohibit creating a landrush application in LANDRUSH (but not in SUNRUSH) if there is
|
// Prohibit creating a landrush application in LANDRUSH (but not in SUNRUSH) if there is
|
||||||
// exactly one sunrise application for the same name.
|
// exactly one sunrise application for the same name.
|
||||||
|
|
|
@ -18,7 +18,7 @@ import static google.registry.flows.domain.DomainFlowUtils.getReservationType;
|
||||||
import static google.registry.flows.domain.DomainFlowUtils.handleFeeRequest;
|
import static google.registry.flows.domain.DomainFlowUtils.handleFeeRequest;
|
||||||
import static google.registry.model.EppResourceUtils.checkResourcesExist;
|
import static google.registry.model.EppResourceUtils.checkResourcesExist;
|
||||||
import static google.registry.model.registry.label.ReservationType.UNRESERVED;
|
import static google.registry.model.registry.label.ReservationType.UNRESERVED;
|
||||||
import static google.registry.pricing.PricingEngineProxy.isPremiumName;
|
import static google.registry.pricing.PricingEngineProxy.getPricesForDomainName;
|
||||||
import static google.registry.util.CollectionUtils.nullToEmpty;
|
import static google.registry.util.CollectionUtils.nullToEmpty;
|
||||||
import static google.registry.util.DomainNameUtils.getTldFromDomainName;
|
import static google.registry.util.DomainNameUtils.getTldFromDomainName;
|
||||||
|
|
||||||
|
@ -83,7 +83,7 @@ public class DomainCheckFlow extends BaseDomainCheckFlow {
|
||||||
ReservationType reservationType = getReservationType(domainName);
|
ReservationType reservationType = getReservationType(domainName);
|
||||||
Registry registry = Registry.get(domainName.parent().toString());
|
Registry registry = Registry.get(domainName.parent().toString());
|
||||||
if (reservationType == UNRESERVED
|
if (reservationType == UNRESERVED
|
||||||
&& isPremiumName(domainName, now, getClientId())
|
&& getPricesForDomainName(domainName.toString(), now).isPremium()
|
||||||
&& registry.getPremiumPriceAckRequired()
|
&& registry.getPremiumPriceAckRequired()
|
||||||
&& !nullToEmpty(sessionMetadata.getServiceExtensionUris()).contains(
|
&& !nullToEmpty(sessionMetadata.getServiceExtensionUris()).contains(
|
||||||
ServiceExtension.FEE_0_6.getUri())) {
|
ServiceExtension.FEE_0_6.getUri())) {
|
||||||
|
@ -121,7 +121,7 @@ public class DomainCheckFlow extends BaseDomainCheckFlow {
|
||||||
}
|
}
|
||||||
FeeCheck.Builder builder = new FeeCheck.Builder();
|
FeeCheck.Builder builder = new FeeCheck.Builder();
|
||||||
handleFeeRequest(
|
handleFeeRequest(
|
||||||
domainCheck, builder, domainName, getTldFromDomainName(domainName), getClientId(), now);
|
domainCheck, builder, domainName, getTldFromDomainName(domainName), now);
|
||||||
feeChecksBuilder.add(builder.setName(domainName).build());
|
feeChecksBuilder.add(builder.setName(domainName).build());
|
||||||
}
|
}
|
||||||
return ImmutableList.of(FeeCheckResponseExtension.create(feeChecksBuilder.build()));
|
return ImmutableList.of(FeeCheckResponseExtension.create(feeChecksBuilder.build()));
|
||||||
|
|
|
@ -108,7 +108,7 @@ public class DomainCreateFlow extends DomainCreateOrAllocateFlow {
|
||||||
@Override
|
@Override
|
||||||
protected final void verifyDomainCreateIsAllowed() throws EppException {
|
protected final void verifyDomainCreateIsAllowed() throws EppException {
|
||||||
String tld = getTld();
|
String tld = getTld();
|
||||||
validateFeeChallenge(targetId, tld, now, getClientId(), feeCreate, createCost);
|
validateFeeChallenge(targetId, tld, now, feeCreate, createCost);
|
||||||
if (!superuser) {
|
if (!superuser) {
|
||||||
// Prohibit creating a domain if there is an open application for the same name.
|
// Prohibit creating a domain if there is an open application for the same name.
|
||||||
for (DomainApplication application : loadActiveApplicationsByDomainName(targetId, now)) {
|
for (DomainApplication application : loadActiveApplicationsByDomainName(targetId, now)) {
|
||||||
|
|
|
@ -139,7 +139,7 @@ public class DomainDeleteFlow extends ResourceSyncDeleteFlow<DomainResource, Bui
|
||||||
TimeOfYear recurrenceTimeOfYear =
|
TimeOfYear recurrenceTimeOfYear =
|
||||||
checkNotNull(gracePeriod.getRecurringBillingEvent()).get().getRecurrenceTimeOfYear();
|
checkNotNull(gracePeriod.getRecurringBillingEvent()).get().getRecurrenceTimeOfYear();
|
||||||
DateTime autoRenewTime = recurrenceTimeOfYear.getLastInstanceBeforeOrAt(now);
|
DateTime autoRenewTime = recurrenceTimeOfYear.getLastInstanceBeforeOrAt(now);
|
||||||
cost = getDomainRenewCost(targetId, autoRenewTime, getClientId(), 1);
|
cost = getDomainRenewCost(targetId, autoRenewTime, 1);
|
||||||
} else {
|
} else {
|
||||||
cost = checkNotNull(gracePeriod.getOneTimeBillingEvent()).get().getCost();
|
cost = checkNotNull(gracePeriod.getOneTimeBillingEvent()).get().getCost();
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,6 @@ package google.registry.flows.domain;
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
import static com.google.common.base.Preconditions.checkState;
|
import static com.google.common.base.Preconditions.checkState;
|
||||||
import static com.google.common.base.Predicates.equalTo;
|
import static com.google.common.base.Predicates.equalTo;
|
||||||
import static com.google.common.base.Strings.emptyToNull;
|
|
||||||
import static com.google.common.collect.Iterables.any;
|
import static com.google.common.collect.Iterables.any;
|
||||||
import static com.google.common.collect.Iterables.concat;
|
import static com.google.common.collect.Iterables.concat;
|
||||||
import static com.google.common.collect.Sets.difference;
|
import static com.google.common.collect.Sets.difference;
|
||||||
|
@ -25,9 +24,7 @@ import static google.registry.flows.EppXmlTransformer.unmarshal;
|
||||||
import static google.registry.model.ofy.ObjectifyService.ofy;
|
import static google.registry.model.ofy.ObjectifyService.ofy;
|
||||||
import static google.registry.model.registry.Registries.findTldForName;
|
import static google.registry.model.registry.Registries.findTldForName;
|
||||||
import static google.registry.model.registry.label.ReservedList.getReservation;
|
import static google.registry.model.registry.label.ReservedList.getReservation;
|
||||||
import static google.registry.pricing.PricingEngineProxy.getDomainCreateCost;
|
import static google.registry.pricing.PricingEngineProxy.getPricesForDomainName;
|
||||||
import static google.registry.pricing.PricingEngineProxy.getDomainRenewCost;
|
|
||||||
import static google.registry.pricing.PricingEngineProxy.isPremiumName;
|
|
||||||
import static google.registry.tldconfig.idn.IdnLabelValidator.findValidIdnTableForTld;
|
import static google.registry.tldconfig.idn.IdnLabelValidator.findValidIdnTableForTld;
|
||||||
import static google.registry.util.CollectionUtils.nullToEmpty;
|
import static google.registry.util.CollectionUtils.nullToEmpty;
|
||||||
import static google.registry.util.DateTimeUtils.isAtOrAfter;
|
import static google.registry.util.DateTimeUtils.isAtOrAfter;
|
||||||
|
@ -82,6 +79,7 @@ import google.registry.model.mark.Mark;
|
||||||
import google.registry.model.mark.ProtectedMark;
|
import google.registry.model.mark.ProtectedMark;
|
||||||
import google.registry.model.mark.Trademark;
|
import google.registry.model.mark.Trademark;
|
||||||
import google.registry.model.poll.PollMessage;
|
import google.registry.model.poll.PollMessage;
|
||||||
|
import google.registry.model.pricing.PricingEngine.DomainPrices;
|
||||||
import google.registry.model.registrar.Registrar;
|
import google.registry.model.registrar.Registrar;
|
||||||
import google.registry.model.registry.Registry;
|
import google.registry.model.registry.Registry;
|
||||||
import google.registry.model.registry.Registry.TldState;
|
import google.registry.model.registry.Registry.TldState;
|
||||||
|
@ -286,7 +284,6 @@ public class DomainFlowUtils {
|
||||||
throw new TooManyNameserversException(String.format(
|
throw new TooManyNameserversException(String.format(
|
||||||
"Only %d nameservers are allowed per domain", MAX_NAMESERVERS_PER_DOMAIN));
|
"Only %d nameservers are allowed per domain", MAX_NAMESERVERS_PER_DOMAIN));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void validateNoDuplicateContacts(Set<DesignatedContact> contacts)
|
static void validateNoDuplicateContacts(Set<DesignatedContact> contacts)
|
||||||
|
@ -388,7 +385,7 @@ public class DomainFlowUtils {
|
||||||
*/
|
*/
|
||||||
static void verifyPremiumNameIsNotBlocked(
|
static void verifyPremiumNameIsNotBlocked(
|
||||||
String domainName, DateTime priceTime, String clientIdentifier) throws EppException {
|
String domainName, DateTime priceTime, String clientIdentifier) throws EppException {
|
||||||
if (isPremiumName(domainName, priceTime, clientIdentifier)) {
|
if (getPricesForDomainName(domainName, priceTime).isPremium()) {
|
||||||
// NB: The load of the Registar object is transactionless, which means that it should hit
|
// NB: The load of the Registar object is transactionless, which means that it should hit
|
||||||
// memcache most of the time.
|
// memcache most of the time.
|
||||||
if (Registrar.loadByClientId(clientIdentifier).getBlockPremiumNames()) {
|
if (Registrar.loadByClientId(clientIdentifier).getBlockPremiumNames()) {
|
||||||
|
@ -563,15 +560,12 @@ public class DomainFlowUtils {
|
||||||
BaseFeeResponse.Builder<?, ?> builder,
|
BaseFeeResponse.Builder<?, ?> builder,
|
||||||
String domainName,
|
String domainName,
|
||||||
String tld,
|
String tld,
|
||||||
String clientIdentifier,
|
|
||||||
DateTime now) throws EppException {
|
DateTime now) throws EppException {
|
||||||
InternetDomainName domain = InternetDomainName.from(domainName);
|
InternetDomainName domain = InternetDomainName.from(domainName);
|
||||||
FeeCommandDescriptor feeCommand = feeRequest.getCommand();
|
FeeCommandDescriptor feeCommand = feeRequest.getCommand();
|
||||||
Registry registry = Registry.get(tld);
|
Registry registry = Registry.get(tld);
|
||||||
int years = verifyUnitIsYears(feeRequest.getPeriod()).getValue();
|
int years = verifyUnitIsYears(feeRequest.getPeriod()).getValue();
|
||||||
boolean isSunrise = registry.getTldState(now).equals(TldState.SUNRISE);
|
boolean isSunrise = registry.getTldState(now).equals(TldState.SUNRISE);
|
||||||
boolean isNameCollisionInSunrise =
|
|
||||||
isSunrise && getReservationType(domain) == ReservationType.NAME_COLLISION;
|
|
||||||
|
|
||||||
if (feeCommand.getPhase() != null || feeCommand.getSubphase() != null) {
|
if (feeCommand.getPhase() != null || feeCommand.getSubphase() != null) {
|
||||||
throw new FeeChecksDontSupportPhasesException();
|
throw new FeeChecksDontSupportPhasesException();
|
||||||
|
@ -581,14 +575,13 @@ public class DomainFlowUtils {
|
||||||
throw new CurrencyUnitMismatchException();
|
throw new CurrencyUnitMismatchException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DomainPrices prices = getPricesForDomainName(domainName, now);
|
||||||
builder
|
builder
|
||||||
.setCommand(feeCommand)
|
.setCommand(feeCommand)
|
||||||
.setCurrency(registry.getCurrency())
|
.setCurrency(registry.getCurrency())
|
||||||
.setPeriod(feeRequest.getPeriod())
|
.setPeriod(feeRequest.getPeriod())
|
||||||
// Choose from four classes: premium, premium-collision, collision, or null (standard case).
|
// Choose from four classes: premium, premium-collision, collision, or null (standard case).
|
||||||
.setClass(emptyToNull(Joiner.on('-').skipNulls().join(
|
.setClass(prices.getFeeClass().orNull());
|
||||||
isPremiumName(domainName, now, clientIdentifier) ? "premium" : null,
|
|
||||||
isNameCollisionInSunrise ? "collision" : null)));
|
|
||||||
|
|
||||||
switch (feeCommand.getCommand()) {
|
switch (feeCommand.getCommand()) {
|
||||||
case UNKNOWN:
|
case UNKNOWN:
|
||||||
|
@ -598,9 +591,7 @@ public class DomainFlowUtils {
|
||||||
builder.setClass("reserved"); // Override whatever class we've set above.
|
builder.setClass("reserved"); // Override whatever class we've set above.
|
||||||
} else {
|
} else {
|
||||||
builder.setFee(
|
builder.setFee(
|
||||||
Fee.create(
|
Fee.create(prices.getCreateCost().multipliedBy(years).getAmount(), "create"));
|
||||||
getDomainCreateCost(domainName, now, clientIdentifier, years).getAmount(),
|
|
||||||
"create"));
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case RESTORE:
|
case RESTORE:
|
||||||
|
@ -609,17 +600,12 @@ public class DomainFlowUtils {
|
||||||
}
|
}
|
||||||
// Restores have a "renew" and a "restore" fee.
|
// Restores have a "renew" and a "restore" fee.
|
||||||
builder.setFee(
|
builder.setFee(
|
||||||
Fee.create(
|
Fee.create(prices.getRenewCost().multipliedBy(years).getAmount(), "renew"),
|
||||||
getDomainRenewCost(domainName, now, clientIdentifier, years).getAmount(),
|
|
||||||
"renew"),
|
|
||||||
Fee.create(registry.getStandardRestoreCost().getAmount(), "restore"));
|
Fee.create(registry.getStandardRestoreCost().getAmount(), "restore"));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// Anything else (transfer|renew) will have a "renew" fee.
|
// Anything else (transfer|renew) will have a "renew" fee.
|
||||||
builder.setFee(
|
builder.setFee(Fee.create(prices.getRenewCost().multipliedBy(years).getAmount(), "renew"));
|
||||||
Fee.create(
|
|
||||||
getDomainRenewCost(domainName, now, clientIdentifier, years).getAmount(),
|
|
||||||
"renew"));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -627,14 +613,13 @@ public class DomainFlowUtils {
|
||||||
String domainName,
|
String domainName,
|
||||||
String tld,
|
String tld,
|
||||||
DateTime priceTime,
|
DateTime priceTime,
|
||||||
String clientIdentifier,
|
|
||||||
final BaseFeeCommand feeCommand,
|
final BaseFeeCommand feeCommand,
|
||||||
Money cost,
|
Money cost,
|
||||||
Money... otherCosts)
|
Money... otherCosts)
|
||||||
throws EppException {
|
throws EppException {
|
||||||
Registry registry = Registry.get(tld);
|
Registry registry = Registry.get(tld);
|
||||||
if (registry.getPremiumPriceAckRequired()
|
if (registry.getPremiumPriceAckRequired()
|
||||||
&& isPremiumName(domainName, priceTime, clientIdentifier)
|
&& getPricesForDomainName(domainName, priceTime).isPremium()
|
||||||
&& feeCommand == null) {
|
&& feeCommand == null) {
|
||||||
throw new FeesRequiredForPremiumNameException();
|
throw new FeesRequiredForPremiumNameException();
|
||||||
}
|
}
|
||||||
|
@ -1021,4 +1006,3 @@ public class DomainFlowUtils {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -95,7 +95,7 @@ public class DomainInfoFlow extends BaseDomainInfoFlow<DomainResource, Builder>
|
||||||
if (feeInfo != null) { // Fee check was requested.
|
if (feeInfo != null) { // Fee check was requested.
|
||||||
FeeInfoResponseExtension.Builder builder = new FeeInfoResponseExtension.Builder();
|
FeeInfoResponseExtension.Builder builder = new FeeInfoResponseExtension.Builder();
|
||||||
handleFeeRequest(
|
handleFeeRequest(
|
||||||
feeInfo, builder, getTargetId(), existingResource.getTld(), getClientId(), now);
|
feeInfo, builder, getTargetId(), existingResource.getTld(), now);
|
||||||
extensions.add(builder.build());
|
extensions.add(builder.build());
|
||||||
}
|
}
|
||||||
if (!registrationTypes.isEmpty()) {
|
if (!registrationTypes.isEmpty()) {
|
||||||
|
|
|
@ -110,9 +110,9 @@ public class DomainRenewFlow extends OwnedResourceMutateFlow<DomainResource, Ren
|
||||||
existingResource.getRegistrationExpirationTime().toLocalDate())) {
|
existingResource.getRegistrationExpirationTime().toLocalDate())) {
|
||||||
throw new IncorrectCurrentExpirationDateException();
|
throw new IncorrectCurrentExpirationDateException();
|
||||||
}
|
}
|
||||||
renewCost = getDomainRenewCost(targetId, now, getClientId(), command.getPeriod().getValue());
|
renewCost = getDomainRenewCost(targetId, now, command.getPeriod().getValue());
|
||||||
validateFeeChallenge(
|
validateFeeChallenge(
|
||||||
targetId, existingResource.getTld(), now, getClientId(), feeRenew, renewCost);
|
targetId, existingResource.getTld(), now, feeRenew, renewCost);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -103,8 +103,8 @@ public class DomainRestoreRequestFlow extends OwnedResourceMutateFlow<DomainReso
|
||||||
}
|
}
|
||||||
feeUpdate = eppInput.getSingleExtension(FeeUpdateExtension.class);
|
feeUpdate = eppInput.getSingleExtension(FeeUpdateExtension.class);
|
||||||
restoreCost = Registry.get(tld).getStandardRestoreCost();
|
restoreCost = Registry.get(tld).getStandardRestoreCost();
|
||||||
renewCost = getDomainRenewCost(targetId, now, getClientId(), 1);
|
renewCost = getDomainRenewCost(targetId, now, 1);
|
||||||
validateFeeChallenge(targetId, tld, now, getClientId(), feeUpdate, restoreCost, renewCost);
|
validateFeeChallenge(targetId, tld, now, feeUpdate, restoreCost, renewCost);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -72,16 +72,14 @@ public class DomainTransferApproveFlow extends
|
||||||
String tld = existingResource.getTld();
|
String tld = existingResource.getTld();
|
||||||
int extraYears = transferData.getExtendedRegistrationYears();
|
int extraYears = transferData.getExtendedRegistrationYears();
|
||||||
// Bill for the transfer.
|
// Bill for the transfer.
|
||||||
BillingEvent.OneTime billingEvent = new BillingEvent.OneTime.Builder()
|
BillingEvent.OneTime billingEvent =
|
||||||
|
new BillingEvent.OneTime.Builder()
|
||||||
.setReason(Reason.TRANSFER)
|
.setReason(Reason.TRANSFER)
|
||||||
.setTargetId(targetId)
|
.setTargetId(targetId)
|
||||||
.setClientId(gainingClientId)
|
.setClientId(gainingClientId)
|
||||||
.setPeriodYears(extraYears)
|
.setPeriodYears(extraYears)
|
||||||
.setCost(getDomainRenewCost(
|
.setCost(
|
||||||
targetId,
|
getDomainRenewCost(targetId, transferData.getTransferRequestTime(), extraYears))
|
||||||
transferData.getTransferRequestTime(),
|
|
||||||
transferData.getGainingClientId(),
|
|
||||||
extraYears))
|
|
||||||
.setEventTime(now)
|
.setEventTime(now)
|
||||||
.setBillingTime(now.plus(Registry.get(tld).getTransferGracePeriodLength()))
|
.setBillingTime(now.plus(Registry.get(tld).getTransferGracePeriodLength()))
|
||||||
.setParent(historyEntry)
|
.setParent(historyEntry)
|
||||||
|
|
|
@ -115,7 +115,7 @@ public class DomainTransferRequestFlow
|
||||||
Registry registry = Registry.get(existingResource.getTld());
|
Registry registry = Registry.get(existingResource.getTld());
|
||||||
automaticTransferTime = now.plus(registry.getAutomaticTransferLength());
|
automaticTransferTime = now.plus(registry.getAutomaticTransferLength());
|
||||||
// Note that the gaining registrar is used to calculate the cost of the renewal.
|
// Note that the gaining registrar is used to calculate the cost of the renewal.
|
||||||
renewCost = getDomainRenewCost(targetId, now, getClientId(), command.getPeriod().getValue());
|
renewCost = getDomainRenewCost(targetId, now, command.getPeriod().getValue());
|
||||||
transferBillingEvent = new BillingEvent.OneTime.Builder()
|
transferBillingEvent = new BillingEvent.OneTime.Builder()
|
||||||
.setReason(Reason.TRANSFER)
|
.setReason(Reason.TRANSFER)
|
||||||
.setTargetId(targetId)
|
.setTargetId(targetId)
|
||||||
|
@ -156,7 +156,7 @@ public class DomainTransferRequestFlow
|
||||||
verifyPremiumNameIsNotBlocked(targetId, now, getClientId());
|
verifyPremiumNameIsNotBlocked(targetId, now, getClientId());
|
||||||
}
|
}
|
||||||
validateFeeChallenge(
|
validateFeeChallenge(
|
||||||
targetId, existingResource.getTld(), now, getClientId(), feeTransfer, renewCost);
|
targetId, existingResource.getTld(), now, feeTransfer, renewCost);
|
||||||
checkAllowedAccessToTld(getAllowedTlds(), existingResource.getTld());
|
checkAllowedAccessToTld(getAllowedTlds(), existingResource.getTld());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,12 +23,70 @@ import org.joda.time.DateTime;
|
||||||
public interface PricingEngine {
|
public interface PricingEngine {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the premium price for the given domain name at the given time for the given registrar,
|
* Returns the prices for the given fully qualified domain name at the given time.
|
||||||
* or absent if the domain name isn't premium.
|
|
||||||
*
|
*
|
||||||
* <p>Note that fullyQualifiedDomainName must not include any subdomains. It should be a single
|
* <p>Note that the fullyQualifiedDomainName must only contain a single part left of the TLD, i.e.
|
||||||
* level above the TLD (which may be multi-part).
|
* subdomains are not allowed, but multi-part TLDs are.
|
||||||
*/
|
*/
|
||||||
public Optional<Money> getPremiumPrice(
|
public DomainPrices getDomainPrices(String fullyQualifiedDomainName, DateTime priceTime);
|
||||||
String fullyQualifiedDomainName, DateTime priceTime, String clientIdentifier);
|
|
||||||
|
/**
|
||||||
|
* A class containing information on prices for a specific domain name.
|
||||||
|
*
|
||||||
|
* <p>Any implementation of PricingEngine is responsible for determining all of these.
|
||||||
|
*/
|
||||||
|
public static class DomainPrices {
|
||||||
|
|
||||||
|
private boolean isPremium;
|
||||||
|
// TODO(b/26901539): Refactor return values to support an arbitrary list of costs for each of
|
||||||
|
// create, renew, restore, and transfer.
|
||||||
|
private Money createCost;
|
||||||
|
private Money renewCost;
|
||||||
|
private Optional<Money> oneTimeFee;
|
||||||
|
private Optional<String> feeClass;
|
||||||
|
|
||||||
|
static DomainPrices create(
|
||||||
|
boolean isPremium,
|
||||||
|
Money createCost,
|
||||||
|
Money renewCost,
|
||||||
|
Optional<Money> oneTimeFee,
|
||||||
|
Optional<String> feeClass) {
|
||||||
|
DomainPrices instance = new DomainPrices();
|
||||||
|
instance.isPremium = isPremium;
|
||||||
|
instance.createCost = createCost;
|
||||||
|
instance.renewCost = renewCost;
|
||||||
|
instance.oneTimeFee = oneTimeFee;
|
||||||
|
instance.feeClass = feeClass;
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns whether the domain is premium. */
|
||||||
|
public boolean isPremium() {
|
||||||
|
return isPremium;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns the cost to create the domain. */
|
||||||
|
public Money getCreateCost() {
|
||||||
|
return createCost;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns the cost to renew the domain. */
|
||||||
|
public Money getRenewCost() {
|
||||||
|
return renewCost;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the one time fee to register a domain if there is one.
|
||||||
|
*
|
||||||
|
* <p>This is primarily used for EAP registration fees.
|
||||||
|
*/
|
||||||
|
public Optional<Money> getOneTimeFee() {
|
||||||
|
return oneTimeFee;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns the fee class of the cost (used for the Fee extension). */
|
||||||
|
public Optional<String> getFeeClass() {
|
||||||
|
return feeClass;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,8 +16,13 @@ package google.registry.model.pricing;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
import static com.google.common.base.Preconditions.checkState;
|
import static com.google.common.base.Preconditions.checkState;
|
||||||
|
import static com.google.common.base.Strings.emptyToNull;
|
||||||
|
import static google.registry.model.registry.Registry.TldState.SUNRISE;
|
||||||
|
import static google.registry.model.registry.label.ReservationType.NAME_COLLISION;
|
||||||
|
import static google.registry.model.registry.label.ReservedList.getReservation;
|
||||||
import static google.registry.util.DomainNameUtils.getTldFromDomainName;
|
import static google.registry.util.DomainNameUtils.getTldFromDomainName;
|
||||||
|
|
||||||
|
import com.google.common.base.Joiner;
|
||||||
import com.google.common.base.Optional;
|
import com.google.common.base.Optional;
|
||||||
import com.google.common.net.InternetDomainName;
|
import com.google.common.net.InternetDomainName;
|
||||||
|
|
||||||
|
@ -35,19 +40,28 @@ public final class StaticPremiumListPricingEngine implements PricingEngine {
|
||||||
@Inject StaticPremiumListPricingEngine() {}
|
@Inject StaticPremiumListPricingEngine() {}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Optional<Money> getPremiumPrice(
|
public DomainPrices getDomainPrices(String fullyQualifiedDomainName, DateTime priceTime) {
|
||||||
String fullyQualifiedDomainName, DateTime priceTime, String clientIdentifier) {
|
|
||||||
// Note that clientIdentifier and priceTime are not used for determining premium pricing for
|
|
||||||
// static premium lists.
|
|
||||||
String tld = getTldFromDomainName(fullyQualifiedDomainName);
|
String tld = getTldFromDomainName(fullyQualifiedDomainName);
|
||||||
|
String label = InternetDomainName.from(fullyQualifiedDomainName).parts().get(0);
|
||||||
Registry registry = Registry.get(checkNotNull(tld, "tld"));
|
Registry registry = Registry.get(checkNotNull(tld, "tld"));
|
||||||
if (registry.getPremiumList() == null) {
|
Optional<Money> premiumPrice = Optional.<Money>absent();
|
||||||
return Optional.<Money>absent();
|
if (registry.getPremiumList() != null) {
|
||||||
}
|
|
||||||
String listName = registry.getPremiumList().getName();
|
String listName = registry.getPremiumList().getName();
|
||||||
Optional<PremiumList> premiumList = PremiumList.get(listName);
|
Optional<PremiumList> premiumList = PremiumList.get(listName);
|
||||||
checkState(premiumList.isPresent(), "Could not load premium list: %s", listName);
|
checkState(premiumList.isPresent(), "Could not load premium list: %s", listName);
|
||||||
String label = InternetDomainName.from(fullyQualifiedDomainName).parts().get(0);
|
premiumPrice = premiumList.get().getPremiumPrice(label);
|
||||||
return premiumList.get().getPremiumPrice(label);
|
}
|
||||||
|
boolean isNameCollisionInSunrise =
|
||||||
|
registry.getTldState(priceTime).equals(SUNRISE)
|
||||||
|
&& getReservation(label, tld) == NAME_COLLISION;
|
||||||
|
String feeClass = emptyToNull(Joiner.on('-').skipNulls().join(
|
||||||
|
premiumPrice.isPresent() ? "premium" : null,
|
||||||
|
isNameCollisionInSunrise ? "collision" : null));
|
||||||
|
return DomainPrices.create(
|
||||||
|
premiumPrice.isPresent(),
|
||||||
|
premiumPrice.or(registry.getStandardCreateCost()),
|
||||||
|
premiumPrice.or(registry.getStandardRenewCost(priceTime)),
|
||||||
|
Optional.<Money>absent(),
|
||||||
|
Optional.<String>fromNullable(feeClass));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,16 +16,14 @@ package google.registry.pricing;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkArgument;
|
import static com.google.common.base.Preconditions.checkArgument;
|
||||||
import static com.google.common.base.Preconditions.checkState;
|
import static com.google.common.base.Preconditions.checkState;
|
||||||
import static google.registry.model.registry.Registries.assertTldExists;
|
|
||||||
import static google.registry.util.DomainNameUtils.getTldFromDomainName;
|
import static google.registry.util.DomainNameUtils.getTldFromDomainName;
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
import com.google.common.base.Optional;
|
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
import com.google.common.net.InternetDomainName;
|
|
||||||
|
|
||||||
import google.registry.model.pricing.PricingEngine;
|
import google.registry.model.pricing.PricingEngine;
|
||||||
|
import google.registry.model.pricing.PricingEngine.DomainPrices;
|
||||||
import google.registry.model.registry.Registry;
|
import google.registry.model.registry.Registry;
|
||||||
|
|
||||||
import org.joda.money.Money;
|
import org.joda.money.Money;
|
||||||
|
@ -54,53 +52,29 @@ public final class PricingEngineProxy {
|
||||||
return pricingEngine.getClass().getCanonicalName();
|
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. */
|
/** Returns the billing cost for registering the specified domain name for this many years. */
|
||||||
public static Money getDomainCreateCost(
|
public static Money getDomainCreateCost(String domainName, DateTime priceTime, int years) {
|
||||||
String domainName, DateTime priceTime, String clientIdentifier, int years) {
|
|
||||||
checkArgument(years > 0, "Number of years must be positive");
|
checkArgument(years > 0, "Number of years must be positive");
|
||||||
Optional<Money> annualCost =
|
return getPricesForDomainName(domainName, priceTime).getCreateCost().multipliedBy(years);
|
||||||
getPremiumPriceForDomainName(
|
|
||||||
InternetDomainName.from(domainName), priceTime, clientIdentifier);
|
|
||||||
return annualCost
|
|
||||||
.or(Registry.get(getTldFromDomainName(domainName)).getStandardCreateCost())
|
|
||||||
.multipliedBy(years);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns the billing cost for renewing the specified domain name for this many years. */
|
/** Returns the billing cost for renewing the specified domain name for this many years. */
|
||||||
public static Money getDomainRenewCost(
|
public static Money getDomainRenewCost(String domainName, DateTime priceTime, int years) {
|
||||||
String domainName, DateTime priceTime, String clientIdentifier, int years) {
|
|
||||||
checkArgument(years > 0, "Number of years must be positive");
|
checkArgument(years > 0, "Number of years must be positive");
|
||||||
Optional<Money> annualCost =
|
return getPricesForDomainName(domainName, priceTime).getRenewCost().multipliedBy(years);
|
||||||
getPremiumPriceForDomainName(
|
|
||||||
InternetDomainName.from(domainName), priceTime, clientIdentifier);
|
|
||||||
return annualCost
|
|
||||||
.or(Registry.get(getTldFromDomainName(domainName)).getStandardRenewCost(priceTime))
|
|
||||||
.multipliedBy(years);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns whether the given domain name is premium by dispatching to the appropriate
|
* Returns the full {@link DomainPrices} details for the given domain name by dispatching to the
|
||||||
* {@link PricingEngine} based on what is configured for the TLD that the domain is under.
|
* appropriate {@link PricingEngine} based on what is configured for the TLD that the domain is
|
||||||
|
* under.
|
||||||
*/
|
*/
|
||||||
private static Optional<Money> getPremiumPriceForDomainName(
|
public static DomainPrices getPricesForDomainName(String domainName, DateTime priceTime) {
|
||||||
InternetDomainName domainName, DateTime priceTime, String clientIdentifier) {
|
String tld = getTldFromDomainName(domainName);
|
||||||
String tld = assertTldExists(getTldFromDomainName(domainName));
|
|
||||||
String clazz = Registry.get(tld).getPricingEngineClassName();
|
String clazz = Registry.get(tld).getPricingEngineClassName();
|
||||||
PricingEngine engine = pricingEngines.get(clazz);
|
PricingEngine engine = pricingEngines.get(clazz);
|
||||||
checkState(engine != null, "Could not load pricing engine %s for TLD %s", clazz, tld);
|
checkState(engine != null, "Could not load pricing engine %s for TLD %s", clazz, tld);
|
||||||
return engine.getPremiumPrice(domainName.toString(), priceTime, clientIdentifier);
|
return engine.getDomainPrices(domainName, priceTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
private PricingEngineProxy() {}
|
private PricingEngineProxy() {}
|
||||||
|
|
|
@ -88,9 +88,7 @@ final class CreateAnchorTenantCommand extends MutatingEppToolCommand implements
|
||||||
|
|
||||||
Money cost = null;
|
Money cost = null;
|
||||||
if (fee) {
|
if (fee) {
|
||||||
cost =
|
cost = getDomainCreateCost(domainName, DateTime.now(UTC), DEFAULT_ANCHOR_TENANT_PERIOD_YEARS);
|
||||||
getDomainCreateCost(
|
|
||||||
domainName, DateTime.now(UTC), clientIdentifier, DEFAULT_ANCHOR_TENANT_PERIOD_YEARS);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
setSoyTemplate(CreateAnchorTenantSoyInfo.getInstance(),
|
setSoyTemplate(CreateAnchorTenantSoyInfo.getInstance(),
|
||||||
|
|
|
@ -43,7 +43,10 @@ public final class DomainNameUtils {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the canonicalized TLD part of a valid domain name by stripping off the leftmost part.
|
* Returns the canonicalized TLD part of a valid fully-qualified domain name by stripping off the
|
||||||
|
* leftmost part.
|
||||||
|
*
|
||||||
|
* <p>This method should not be called for subdomains.
|
||||||
*
|
*
|
||||||
* <p>This function is compatible with multi-part tlds, e.g. {@code co.uk}. This function will
|
* <p>This function is compatible with multi-part tlds, e.g. {@code co.uk}. This function will
|
||||||
* also work on domains for which the registry is not authoritative. If you are certain that the
|
* also work on domains for which the registry is not authoritative. If you are certain that the
|
||||||
|
@ -51,28 +54,28 @@ public final class DomainNameUtils {
|
||||||
* {@link google.registry.model.registry.Registries#findTldForName(InternetDomainName)
|
* {@link google.registry.model.registry.Registries#findTldForName(InternetDomainName)
|
||||||
* Registries#findTldForName}, which will work on hostnames in addition to domains.
|
* Registries#findTldForName}, which will work on hostnames in addition to domains.
|
||||||
*
|
*
|
||||||
* @param fullyQualifiedDomainName must be a puny-coded domain name (not a subdomain or Unicode)
|
* @param fullyQualifiedDomainName must be a punycode SLD (not a host or unicode)
|
||||||
* @throws IllegalArgumentException if there is no TLD
|
* @throws IllegalArgumentException if there is no TLD
|
||||||
*/
|
*/
|
||||||
public static String getTldFromDomainName(String fullyQualifiedDomainName) {
|
public static String getTldFromDomainName(String fullyQualifiedDomainName) {
|
||||||
checkArgument(
|
checkArgument(
|
||||||
!Strings.isNullOrEmpty(fullyQualifiedDomainName),
|
!Strings.isNullOrEmpty(fullyQualifiedDomainName),
|
||||||
"fullyQualifiedDomainName cannot be null or empty");
|
"secondLevelDomainName cannot be null or empty");
|
||||||
return getTldFromDomainName(InternetDomainName.from(fullyQualifiedDomainName));
|
return getTldFromDomainName(InternetDomainName.from(fullyQualifiedDomainName));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the canonicalized TLD part of a valid domain name by stripping off the leftmost part.
|
* Returns the canonicalized TLD part of a valid fully-qualified domain name by stripping off the
|
||||||
|
* leftmost part.
|
||||||
*
|
*
|
||||||
* <p>This function is compatible with multi-part TLDs and must not be called with subdomains.
|
* <p>This function is compatible with multi-part TLDs and should not be called with subdomains.
|
||||||
*
|
*
|
||||||
* @throws IllegalArgumentException if there is no TLD
|
* @throws IllegalArgumentException if there is no TLD
|
||||||
*/
|
*/
|
||||||
public static String getTldFromDomainName(InternetDomainName fullyQualifiedDomainName) {
|
public static String getTldFromDomainName(InternetDomainName domainName) {
|
||||||
checkArgumentNotNull(fullyQualifiedDomainName);
|
checkArgumentNotNull(domainName);
|
||||||
checkArgument(
|
checkArgument(domainName.hasParent(), "secondLevelDomainName does not have a TLD");
|
||||||
fullyQualifiedDomainName.hasParent(), "fullyQualifiedDomainName does not have a TLD");
|
return domainName.parent().toString();
|
||||||
return fullyQualifiedDomainName.parent().toString();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private DomainNameUtils() {}
|
private DomainNameUtils() {}
|
||||||
|
|
|
@ -16,7 +16,7 @@ package google.registry.flows.domain;
|
||||||
|
|
||||||
import static com.google.common.io.BaseEncoding.base16;
|
import static com.google.common.io.BaseEncoding.base16;
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
import static google.registry.pricing.PricingEngineProxy.isPremiumName;
|
import static google.registry.pricing.PricingEngineProxy.getPricesForDomainName;
|
||||||
import static google.registry.testing.DatastoreHelper.assertBillingEvents;
|
import static google.registry.testing.DatastoreHelper.assertBillingEvents;
|
||||||
import static google.registry.testing.DatastoreHelper.createTld;
|
import static google.registry.testing.DatastoreHelper.createTld;
|
||||||
import static google.registry.testing.DatastoreHelper.deleteTld;
|
import static google.registry.testing.DatastoreHelper.deleteTld;
|
||||||
|
@ -180,7 +180,7 @@ public class DomainCreateFlowTest extends ResourceFlowTestCase<DomainCreateFlow,
|
||||||
.setReason(Reason.CREATE)
|
.setReason(Reason.CREATE)
|
||||||
.setTargetId(getUniqueIdFromCommand())
|
.setTargetId(getUniqueIdFromCommand())
|
||||||
.setClientId("TheRegistrar")
|
.setClientId("TheRegistrar")
|
||||||
.setCost(isPremiumName(getUniqueIdFromCommand(), clock.nowUtc(), "TheRegistrar")
|
.setCost(getPricesForDomainName(getUniqueIdFromCommand(), clock.nowUtc()).isPremium()
|
||||||
? Money.of(USD, 200)
|
? Money.of(USD, 200)
|
||||||
: Money.of(USD, 26))
|
: Money.of(USD, 26))
|
||||||
.setPeriodYears(2)
|
.setPeriodYears(2)
|
||||||
|
|
|
@ -180,7 +180,6 @@ public class DomainTransferFlowTestCase<F extends Flow, R extends EppResource>
|
||||||
return createBillingEventForTransfer(
|
return createBillingEventForTransfer(
|
||||||
domain,
|
domain,
|
||||||
historyEntry,
|
historyEntry,
|
||||||
"NewRegistrar",
|
|
||||||
TRANSFER_REQUEST_TIME,
|
TRANSFER_REQUEST_TIME,
|
||||||
TRANSFER_EXPIRATION_TIME,
|
TRANSFER_EXPIRATION_TIME,
|
||||||
EXTENDED_REGISTRATION_YEARS);
|
EXTENDED_REGISTRATION_YEARS);
|
||||||
|
|
|
@ -17,7 +17,7 @@ package google.registry.pricing;
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
import static google.registry.pricing.PricingEngineProxy.getDomainCreateCost;
|
import static google.registry.pricing.PricingEngineProxy.getDomainCreateCost;
|
||||||
import static google.registry.pricing.PricingEngineProxy.getDomainRenewCost;
|
import static google.registry.pricing.PricingEngineProxy.getDomainRenewCost;
|
||||||
import static google.registry.pricing.PricingEngineProxy.isPremiumName;
|
import static google.registry.pricing.PricingEngineProxy.getPricesForDomainName;
|
||||||
import static google.registry.testing.DatastoreHelper.createTld;
|
import static google.registry.testing.DatastoreHelper.createTld;
|
||||||
import static google.registry.testing.DatastoreHelper.persistPremiumList;
|
import static google.registry.testing.DatastoreHelper.persistPremiumList;
|
||||||
import static google.registry.testing.DatastoreHelper.persistResource;
|
import static google.registry.testing.DatastoreHelper.persistResource;
|
||||||
|
@ -26,6 +26,7 @@ import static org.joda.money.CurrencyUnit.USD;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableSortedMap;
|
import com.google.common.collect.ImmutableSortedMap;
|
||||||
|
|
||||||
|
import google.registry.model.pricing.PricingEngine;
|
||||||
import google.registry.model.registry.Registry;
|
import google.registry.model.registry.Registry;
|
||||||
import google.registry.model.registry.label.PremiumList;
|
import google.registry.model.registry.label.PremiumList;
|
||||||
import google.registry.testing.AppEngineRule;
|
import google.registry.testing.AppEngineRule;
|
||||||
|
@ -68,34 +69,34 @@ public class PricingEngineProxyTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void test_getDomainCreateCost_multipleYears() {
|
public void test_getDomainCreateCost_multipleYears() {
|
||||||
assertThat(getDomainCreateCost("espresso.moka", clock.nowUtc(), "TheRegistrar", 1))
|
assertThat(getDomainCreateCost("espresso.moka", clock.nowUtc(), 1))
|
||||||
.isEqualTo(Money.parse("USD 13"));
|
.isEqualTo(Money.parse("USD 13"));
|
||||||
assertThat(getDomainCreateCost("espresso.moka", clock.nowUtc(), "TheRegistrar", 5))
|
assertThat(getDomainCreateCost("espresso.moka", clock.nowUtc(), 5))
|
||||||
.isEqualTo(Money.parse("USD 65"));
|
.isEqualTo(Money.parse("USD 65"));
|
||||||
assertThat(getDomainCreateCost("fraction.moka", clock.nowUtc(), "TheRegistrar", 1))
|
assertThat(getDomainCreateCost("fraction.moka", clock.nowUtc(), 1))
|
||||||
.isEqualTo(Money.parse("USD 20.50"));
|
.isEqualTo(Money.parse("USD 20.50"));
|
||||||
assertThat(getDomainCreateCost("fraction.moka", clock.nowUtc(), "TheRegistrar", 3))
|
assertThat(getDomainCreateCost("fraction.moka", clock.nowUtc(), 3))
|
||||||
.isEqualTo(Money.parse("USD 61.50"));
|
.isEqualTo(Money.parse("USD 61.50"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void test_getDomainRenewCost_multipleYears() {
|
public void test_getDomainRenewCost_multipleYears() {
|
||||||
assertThat(getDomainRenewCost("espresso.moka", clock.nowUtc(), "TheRegistrar", 1))
|
assertThat(getDomainRenewCost("espresso.moka", clock.nowUtc(), 1))
|
||||||
.isEqualTo(Money.parse("USD 11"));
|
.isEqualTo(Money.parse("USD 11"));
|
||||||
assertThat(getDomainRenewCost("espresso.moka", clock.nowUtc(), "TheRegistrar", 5))
|
assertThat(getDomainRenewCost("espresso.moka", clock.nowUtc(), 5))
|
||||||
.isEqualTo(Money.parse("USD 55"));
|
.isEqualTo(Money.parse("USD 55"));
|
||||||
assertThat(getDomainRenewCost("fraction.moka", clock.nowUtc(), "TheRegistrar", 1))
|
assertThat(getDomainRenewCost("fraction.moka", clock.nowUtc(), 1))
|
||||||
.isEqualTo(Money.parse("USD 20.50"));
|
.isEqualTo(Money.parse("USD 20.50"));
|
||||||
assertThat(getDomainRenewCost("fraction.moka", clock.nowUtc(), "TheRegistrar", 3))
|
assertThat(getDomainRenewCost("fraction.moka", clock.nowUtc(), 3))
|
||||||
.isEqualTo(Money.parse("USD 61.50"));
|
.isEqualTo(Money.parse("USD 61.50"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testIsPremiumDomain() throws Exception {
|
public void testIsPremiumDomain() throws Exception {
|
||||||
createTld("example");
|
createTld("example");
|
||||||
assertThat(isPremiumName("poor.example", clock.nowUtc(), "TheRegistrar")).isFalse();
|
assertThat(getPricesForDomainName("poor.example", clock.nowUtc()).isPremium()).isFalse();
|
||||||
assertThat(isPremiumName("rich.example", clock.nowUtc(), "TheRegistrar")).isTrue();
|
assertThat(getPricesForDomainName("rich.example", clock.nowUtc()).isPremium()).isTrue();
|
||||||
assertThat(isPremiumName("richer.example", clock.nowUtc(), "TheRegistrar")).isTrue();
|
assertThat(getPricesForDomainName("richer.example", clock.nowUtc()).isPremium()).isTrue();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -103,13 +104,13 @@ public class PricingEngineProxyTest {
|
||||||
// The example tld has a premium price for "rich".
|
// The example tld has a premium price for "rich".
|
||||||
createTld("example");
|
createTld("example");
|
||||||
// The default value of 17 is set in createTld().
|
// The default value of 17 is set in createTld().
|
||||||
assertThat(getDomainCreateCost("poor.example", clock.nowUtc(), "TheRegistrar", 1))
|
assertThat(getDomainCreateCost("poor.example", clock.nowUtc(), 1))
|
||||||
.isEqualTo(Money.of(USD, 13));
|
.isEqualTo(Money.of(USD, 13));
|
||||||
assertThat(getDomainCreateCost("poor.example", clock.nowUtc(), "TheRegistrar", 2))
|
assertThat(getDomainCreateCost("poor.example", clock.nowUtc(), 2))
|
||||||
.isEqualTo(Money.of(USD, 26));
|
.isEqualTo(Money.of(USD, 26));
|
||||||
assertThat(getDomainCreateCost("rich.example", clock.nowUtc(), "TheRegistrar", 1))
|
assertThat(getDomainCreateCost("rich.example", clock.nowUtc(), 1))
|
||||||
.isEqualTo(Money.of(USD, 100));
|
.isEqualTo(Money.of(USD, 100));
|
||||||
assertThat(getDomainCreateCost("rich.example", clock.nowUtc(), "TheRegistrar", 2))
|
assertThat(getDomainCreateCost("rich.example", clock.nowUtc(), 2))
|
||||||
.isEqualTo(Money.of(USD, 200));
|
.isEqualTo(Money.of(USD, 200));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,60 +125,36 @@ public class PricingEngineProxyTest {
|
||||||
ImmutableSortedMap.of(
|
ImmutableSortedMap.of(
|
||||||
START_OF_TIME, Money.of(USD, 8), clock.nowUtc(), Money.of(USD, 10)))
|
START_OF_TIME, Money.of(USD, 8), clock.nowUtc(), Money.of(USD, 10)))
|
||||||
.build());
|
.build());
|
||||||
assertThat(getDomainRenewCost("poor.example", START_OF_TIME, "TheRegistrar", 1))
|
assertThat(getDomainRenewCost("poor.example", START_OF_TIME, 1))
|
||||||
.isEqualTo(Money.of(USD, 8));
|
.isEqualTo(Money.of(USD, 8));
|
||||||
assertThat(getDomainRenewCost("poor.example", START_OF_TIME, "TheRegistrar", 2))
|
assertThat(getDomainRenewCost("poor.example", START_OF_TIME, 2))
|
||||||
.isEqualTo(Money.of(USD, 16));
|
.isEqualTo(Money.of(USD, 16));
|
||||||
assertThat(getDomainRenewCost("poor.example", clock.nowUtc(), "TheRegistrar", 1))
|
assertThat(getDomainRenewCost("poor.example", clock.nowUtc(), 1))
|
||||||
.isEqualTo(Money.of(USD, 10));
|
.isEqualTo(Money.of(USD, 10));
|
||||||
assertThat(getDomainRenewCost("poor.example", clock.nowUtc(), "TheRegistrar", 2))
|
assertThat(getDomainRenewCost("poor.example", clock.nowUtc(), 2))
|
||||||
.isEqualTo(Money.of(USD, 20));
|
.isEqualTo(Money.of(USD, 20));
|
||||||
assertThat(getDomainRenewCost("rich.example", START_OF_TIME, "TheRegistrar", 1))
|
assertThat(getDomainRenewCost("rich.example", START_OF_TIME, 1))
|
||||||
.isEqualTo(Money.of(USD, 100));
|
.isEqualTo(Money.of(USD, 100));
|
||||||
assertThat(getDomainRenewCost("rich.example", START_OF_TIME, "TheRegistrar", 2))
|
assertThat(getDomainRenewCost("rich.example", START_OF_TIME, 2))
|
||||||
.isEqualTo(Money.of(USD, 200));
|
.isEqualTo(Money.of(USD, 200));
|
||||||
assertThat(getDomainRenewCost("rich.example", clock.nowUtc(), "TheRegistrar", 1))
|
assertThat(getDomainRenewCost("rich.example", clock.nowUtc(), 1))
|
||||||
.isEqualTo(Money.of(USD, 100));
|
.isEqualTo(Money.of(USD, 100));
|
||||||
assertThat(getDomainRenewCost("rich.example", clock.nowUtc(), "TheRegistrar", 2))
|
assertThat(getDomainRenewCost("rich.example", clock.nowUtc(), 2))
|
||||||
.isEqualTo(Money.of(USD, 200));
|
.isEqualTo(Money.of(USD, 200));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testFailure_isPremiumNameForSldNotUnderTld() {
|
public void testFailure_cantLoadPricingEngine() throws Exception {
|
||||||
thrown.expect(IllegalArgumentException.class);
|
|
||||||
isPremiumName("test.example", clock.nowUtc(), "TheRegistrar");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testFailure_isPremiumNameForSldSubdomain() throws Exception {
|
|
||||||
createTld("example");
|
createTld("example");
|
||||||
thrown.expect(IllegalArgumentException.class);
|
persistResource(
|
||||||
isPremiumName("rich.sld.example", clock.nowUtc(), "TheRegistrar");
|
Registry.get("example").asBuilder().setPricingEngineClass(FakePricingEngine.class).build());
|
||||||
|
thrown.expect(
|
||||||
|
IllegalStateException.class,
|
||||||
|
String.format(
|
||||||
|
"Could not load pricing engine %s for TLD example",
|
||||||
|
FakePricingEngine.class.getCanonicalName()));
|
||||||
|
getDomainCreateCost("bad.example", clock.nowUtc(), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
private abstract static class FakePricingEngine implements PricingEngine {}
|
||||||
public void testFailure_getCreateCostForSldNotUnderTld() {
|
|
||||||
thrown.expect(IllegalArgumentException.class);
|
|
||||||
getDomainCreateCost("test.example", clock.nowUtc(), "TheRegistrar", 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testFailure_getCreateCostForSldSubdomain() throws Exception {
|
|
||||||
createTld("example");
|
|
||||||
thrown.expect(IllegalArgumentException.class);
|
|
||||||
getDomainCreateCost("rich.sld.example", clock.nowUtc(), "TheRegistrar", 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testFailure_getRenewCostForSldNotUnderTld() {
|
|
||||||
thrown.expect(IllegalArgumentException.class);
|
|
||||||
getDomainRenewCost("test.example", clock.nowUtc(), "TheRegistrar", 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testFailure_getRenewCostForSldSubdomain() throws Exception {
|
|
||||||
createTld("example");
|
|
||||||
thrown.expect(IllegalArgumentException.class);
|
|
||||||
getDomainRenewCost("rich.sld.example", clock.nowUtc(), "TheRegistrar", 1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -428,7 +428,6 @@ public class DatastoreHelper {
|
||||||
public static BillingEvent.OneTime createBillingEventForTransfer(
|
public static BillingEvent.OneTime createBillingEventForTransfer(
|
||||||
DomainResource domain,
|
DomainResource domain,
|
||||||
HistoryEntry historyEntry,
|
HistoryEntry historyEntry,
|
||||||
String gainingClientId,
|
|
||||||
DateTime costLookupTime,
|
DateTime costLookupTime,
|
||||||
DateTime eventTime,
|
DateTime eventTime,
|
||||||
Integer extendedRegistrationYears) {
|
Integer extendedRegistrationYears) {
|
||||||
|
@ -440,11 +439,9 @@ public class DatastoreHelper {
|
||||||
eventTime.plus(Registry.get(domain.getTld()).getTransferGracePeriodLength()))
|
eventTime.plus(Registry.get(domain.getTld()).getTransferGracePeriodLength()))
|
||||||
.setClientId("NewRegistrar")
|
.setClientId("NewRegistrar")
|
||||||
.setPeriodYears(extendedRegistrationYears)
|
.setPeriodYears(extendedRegistrationYears)
|
||||||
.setCost(getDomainRenewCost(
|
.setCost(
|
||||||
domain.getFullyQualifiedDomainName(),
|
getDomainRenewCost(
|
||||||
costLookupTime,
|
domain.getFullyQualifiedDomainName(), costLookupTime, extendedRegistrationYears))
|
||||||
gainingClientId,
|
|
||||||
extendedRegistrationYears))
|
|
||||||
.setParent(historyEntry)
|
.setParent(historyEntry)
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
@ -505,7 +502,6 @@ public class DatastoreHelper {
|
||||||
BillingEvent.OneTime transferBillingEvent = persistResource(createBillingEventForTransfer(
|
BillingEvent.OneTime transferBillingEvent = persistResource(createBillingEventForTransfer(
|
||||||
domain,
|
domain,
|
||||||
historyEntryDomainTransfer,
|
historyEntryDomainTransfer,
|
||||||
"NewRegistrar",
|
|
||||||
requestTime,
|
requestTime,
|
||||||
expirationTime,
|
expirationTime,
|
||||||
extendedRegistrationYears));
|
extendedRegistrationYears));
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue