Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,7 @@ public static ImmutableSet<String> getBlockedLabels(ImmutableCollection<String>
ImmutableList<VKey<BsaLabel>> queriedLabels =
domainLabels.stream().map(BsaLabel::vKey).collect(toImmutableList());
return cacheBsaLabels.getAll(queriedLabels).values().stream()
.filter(Optional::isPresent)
.map(Optional::get)
.flatMap(Optional::stream)
.map(BsaLabel::getLabel)
.collect(toImmutableSet());
}
Expand Down
3 changes: 1 addition & 2 deletions core/src/main/java/google/registry/flows/FlowReporter.java
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,7 @@ private static Optional<String> extractTld(String domainName) {
public static ImmutableSet<String> extractTlds(Iterable<String> domainNames) {
return Streams.stream(domainNames)
.map(FlowReporter::extractTld)
.filter(Optional::isPresent)
.map(Optional::get)
.flatMap(Optional::stream)
.collect(toImmutableSet());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,8 @@ private Optional<String> getMessageForCheck(
ImmutableSet<InternetDomainName> bsaBlockedDomainNames,
ImmutableMap<String, TldState> tldStates,
ImmutableMap<String, InternetDomainName> parsedDomains,
DateTime now) {
DateTime now)
throws EppException {
InternetDomainName idn = parsedDomains.get(domainName);
Optional<AllocationToken> token;
try {
Expand All @@ -238,7 +239,9 @@ private Optional<String> getMessageForCheck(
eppInput.getSingleExtension(AllocationTokenExtension.class),
Tld.get(idn.parent().toString()),
domainName,
FeeQueryCommandExtensionItem.CommandName.CREATE);
FeeQueryCommandExtensionItem.CommandName.CREATE,
Optional.empty(),
pricingLogic);
} catch (AllocationTokenFlowUtils.NonexistentAllocationTokenException
| AllocationTokenFlowUtils.AllocationTokenInvalidException e) {
// The provided token was catastrophically invalid in some way
Expand Down Expand Up @@ -317,7 +320,9 @@ private ImmutableList<? extends ResponseExtension> getResponseExtensions(
eppInput.getSingleExtension(AllocationTokenExtension.class),
tld,
domainName,
feeCheckItem.getCommandName());
feeCheckItem.getCommandName(),
Optional.empty(),
pricingLogic);
} catch (AllocationTokenFlowUtils.NonexistentAllocationTokenException
| AllocationTokenFlowUtils.AllocationTokenInvalidException e) {
// The provided token was catastrophically invalid in some way
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,9 @@ public EppResponse run() throws EppException {
eppInput.getSingleExtension(AllocationTokenExtension.class),
tld,
command.getDomainName(),
CommandName.CREATE);
CommandName.CREATE,
Optional.of(years),
pricingLogic);
boolean defaultTokenUsed =
allocationToken.map(t -> t.getTokenType().equals(TokenType.DEFAULT_PROMO)).orElse(false);
boolean isAnchorTenant =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ public DomainPricingLogic(DomainPricingCustomLogic customLogic) {
* <p>If {@code allocationToken} is present and the domain is non-premium, that discount will be
* applied to the first year.
*/
FeesAndCredits getCreatePrice(
public FeesAndCredits getCreatePrice(
Tld tld,
String domainName,
DateTime dateTime,
Expand Down Expand Up @@ -193,8 +193,8 @@ public FeesAndCredits getRenewPrice(
}

/** Returns a new restore price for the pricer. */
FeesAndCredits getRestorePrice(Tld tld, String domainName, DateTime dateTime, boolean isExpired)
throws EppException {
public FeesAndCredits getRestorePrice(
Tld tld, String domainName, DateTime dateTime, boolean isExpired) throws EppException {
DomainPrices domainPrices = getPricesForDomainName(domainName, dateTime);
FeesAndCredits.Builder feesAndCredits =
new FeesAndCredits.Builder()
Expand All @@ -216,7 +216,7 @@ FeesAndCredits getRestorePrice(Tld tld, String domainName, DateTime dateTime, bo
}

/** Returns a new transfer price for the pricer. */
FeesAndCredits getTransferPrice(
public FeesAndCredits getTransferPrice(
Tld tld, String domainName, DateTime dateTime, @Nullable BillingRecurrence billingRecurrence)
throws EppException {
FeesAndCredits renewPrice =
Expand All @@ -239,7 +239,8 @@ FeesAndCredits getTransferPrice(
}

/** Returns a new update price for the pricer. */
FeesAndCredits getUpdatePrice(Tld tld, String domainName, DateTime dateTime) throws EppException {
public FeesAndCredits getUpdatePrice(Tld tld, String domainName, DateTime dateTime)
throws EppException {
CurrencyUnit currency = tld.getCurrency();
BaseFee feeOrCredit = Fee.create(zeroInCurrency(currency), FeeType.UPDATE, false);
return customLogic.customizeUpdatePrice(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -169,14 +169,18 @@ public EppResponse run() throws EppException {
Domain existingDomain = loadAndVerifyExistence(Domain.class, targetId, now);
String tldStr = existingDomain.getTld();
Tld tld = Tld.get(tldStr);
int years = command.getPeriod().getValue();

Optional<AllocationToken> allocationToken =
AllocationTokenFlowUtils.loadTokenFromExtensionOrGetDefault(
registrarId,
now,
eppInput.getSingleExtension(AllocationTokenExtension.class),
tld,
existingDomain.getDomainName(),
CommandName.RENEW);
CommandName.RENEW,
Optional.of(years),
pricingLogic);
boolean defaultTokenUsed =
allocationToken
.map(t -> t.getTokenType().equals(AllocationToken.TokenType.DEFAULT_PROMO))
Expand All @@ -186,7 +190,6 @@ public EppResponse run() throws EppException {
// If client passed an applicable static token this updates the domain
existingDomain = maybeApplyBulkPricingRemovalToken(existingDomain, allocationToken);

int years = command.getPeriod().getValue();
DateTime newExpirationTime =
leapSafeAddYears(existingDomain.getRegistrationExpirationTime(), years); // Uncapped
validateRegistrationPeriod(now, newExpirationTime);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
package google.registry.flows.domain.token;

import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkState;
import static com.google.common.collect.ImmutableList.toImmutableList;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.pricing.PricingEngineProxy.isDomainPremium;
Expand All @@ -24,21 +23,25 @@
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.net.InternetDomainName;
import google.registry.flows.EppException;
import google.registry.flows.EppException.AssociationProhibitsOperationException;
import google.registry.flows.EppException.AuthorizationErrorException;
import google.registry.flows.EppException.StatusProhibitsOperationException;
import google.registry.model.billing.BillingBase;
import google.registry.flows.domain.DomainPricingLogic;
import google.registry.model.billing.BillingBase.RenewalPriceBehavior;
import google.registry.model.billing.BillingRecurrence;
import google.registry.model.domain.Domain;
import google.registry.model.domain.fee.FeeQueryCommandExtensionItem.CommandName;
import google.registry.model.domain.token.AllocationToken;
import google.registry.model.domain.token.AllocationToken.TokenBehavior;
import google.registry.model.domain.token.AllocationToken.TokenStatus;
import google.registry.model.domain.token.AllocationTokenExtension;
import google.registry.model.reporting.HistoryEntry.HistoryEntryId;
import google.registry.model.tld.Tld;
import google.registry.persistence.VKey;
import java.math.BigDecimal;
import java.util.Map;
import java.util.Optional;
import org.joda.time.DateTime;
Expand Down Expand Up @@ -91,16 +94,19 @@ public static Optional<AllocationToken> loadTokenFromExtensionOrGetDefault(
Optional<AllocationTokenExtension> extension,
Tld tld,
String domainName,
CommandName commandName)
throws NonexistentAllocationTokenException, AllocationTokenInvalidException {
CommandName commandName,
Optional<Integer> years,
DomainPricingLogic pricingLogic)
throws EppException {
Optional<AllocationToken> fromExtension =
loadAllocationTokenFromExtension(registrarId, domainName, now, extension);
if (fromExtension.isPresent()
&& tokenIsValidAgainstDomain(
InternetDomainName.from(domainName), fromExtension.get(), commandName, now)) {
return fromExtension;
}
return checkForDefaultToken(tld, domainName, commandName, registrarId, now);
return checkForDefaultToken(
tld, domainName, commandName, registrarId, now, years, pricingLogic);
}

/** Verifies that the given domain can have a bulk pricing token removed from it. */
Expand Down Expand Up @@ -133,7 +139,7 @@ public static Domain maybeApplyBulkPricingRemovalToken(
BillingRecurrence newBillingRecurrence =
tm().loadByKey(domain.getAutorenewBillingEvent())
.asBuilder()
.setRenewalPriceBehavior(BillingBase.RenewalPriceBehavior.DEFAULT)
.setRenewalPriceBehavior(RenewalPriceBehavior.DEFAULT)
.setRenewalPrice(null)
.build();

Expand Down Expand Up @@ -182,37 +188,70 @@ static boolean tokenIsValidAgainstDomain(
* token found on the TLD's default token list will be returned.
*/
private static Optional<AllocationToken> checkForDefaultToken(
Tld tld, String domainName, CommandName commandName, String registrarId, DateTime now) {
Tld tld,
String domainName,
CommandName commandName,
String registrarId,
DateTime now,
Optional<Integer> years,
DomainPricingLogic pricingLogic)
throws EppException {
ImmutableList<VKey<AllocationToken>> tokensFromTld = tld.getDefaultPromoTokens();
if (isNullOrEmpty(tokensFromTld)) {
return Optional.empty();
}
Map<VKey<AllocationToken>, Optional<AllocationToken>> tokens =
AllocationToken.getAll(tokensFromTld);
checkState(
!isNullOrEmpty(tokens), "Failure while loading default TLD tokens from the database");
// Iterate over the list to maintain token ordering (since we return the first valid token)
ImmutableList<AllocationToken> tokenList =
tokensFromTld.stream()
.map(tokens::get)
.filter(Optional::isPresent)
.map(Optional::get)
AllocationToken.getAll(tokensFromTld).values().stream()
.flatMap(Optional::stream)
// Filter to tokens that are 1. valid in general 2. valid for this particular request
.filter(
token -> {
try {
validateTokenEntity(token, registrarId, domainName, now);
} catch (AllocationTokenInvalidException e) {
return false;
}
return tokenIsValidAgainstDomain(
InternetDomainName.from(domainName), token, commandName, now);
})
.collect(toImmutableList());

// Check if any of the tokens are valid for this domain registration
// We can't compute the costs directly in the stream due to the checked EppException
ImmutableMap.Builder<AllocationToken, BigDecimal> tokenCosts = new ImmutableMap.Builder<>();
for (AllocationToken token : tokenList) {
try {
validateTokenEntity(token, registrarId, domainName, now);
} catch (AllocationTokenInvalidException e) {
// Token is not valid for this registrar, etc. -- continue trying tokens
continue;
}
if (tokenIsValidAgainstDomain(InternetDomainName.from(domainName), token, commandName, now)) {
return Optional.of(token);
}
tokenCosts.put(
token,
getSampleCostWithToken(tld, domainName, token, commandName, now, years, pricingLogic));
}
// No valid default token found
return Optional.empty();
return tokenCosts.build().entrySet().stream()
.min(Map.Entry.comparingByValue())
.map(Map.Entry::getKey);
}

private static BigDecimal getSampleCostWithToken(
Tld tld,
String domainName,
AllocationToken token,
CommandName commandName,
DateTime now,
Optional<Integer> years,
DomainPricingLogic pricingLogic)
throws EppException {
int yearsForAction = years.orElse(1);
// We only support token discounts on creates or renews
return switch (commandName) {
case CREATE ->
pricingLogic
.getCreatePrice(
tld, domainName, now, yearsForAction, false, false, Optional.of(token))
.getTotalCost()
.getAmount();
case RENEW ->
pricingLogic
.getRenewPrice(tld, domainName, now, yearsForAction, null, Optional.of(token))
.getTotalCost()
.getAmount();
default -> BigDecimal.ZERO;
};
}

/** Loads a given token and validates it against the registrar, time, etc */
Expand Down Expand Up @@ -253,8 +292,7 @@ private static void validateTokenEntity(
// Tokens without status transitions will just have a single-entry NOT_STARTED map, so only
// check the status transitions map if it's non-trivial.
if (token.getTokenStatusTransitions().size() > 1
&& !AllocationToken.TokenStatus.VALID.equals(
token.getTokenStatusTransitions().getValueAtTime(now))) {
&& !TokenStatus.VALID.equals(token.getTokenStatusTransitions().getValueAtTime(now))) {
throw new AllocationTokenNotInPromotionException();
}

Expand Down Expand Up @@ -303,7 +341,7 @@ public static class AllocationTokenNotValidForDomainException
AllocationTokenNotValidForDomainException() {
super("Alloc token invalid for domain");
}
}
}

/** The allocation token is invalid. */
public static class NonexistentAllocationTokenException extends AuthorizationErrorException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -261,8 +261,7 @@ private static ImmutableSet<ReservedListEntry> getReservedListEntries(
public static ImmutableSet<ReservedList> loadReservedLists(
ImmutableSet<String> reservedListNames) {
return cache.getAll(reservedListNames).values().stream()
.filter(Optional::isPresent)
.map(Optional::get)
.flatMap(Optional::stream)
.collect(toImmutableSet());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -579,8 +579,7 @@ RdapRegistrarEntity createRdapRegistrarEntity(
ImmutableList<RdapRegistrarPocEntity> registrarPocs =
registrar.getPocsFromReplica().stream()
.map(RdapJsonFormatter::makeRdapJsonForRegistrarPoc)
.filter(Optional::isPresent)
.map(Optional::get)
.flatMap(Optional::stream)
.filter(
poc ->
outputDataType == OutputDataType.FULL
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,7 @@ private static ImmutableMap<VKey<Domain>, Domain> loadRedeemedDomains(
ImmutableList<VKey<Domain>> domainKeys =
tokens.stream()
.map(AllocationToken::getRedemptionHistoryId)
.filter(Optional::isPresent)
.map(Optional::get)
.flatMap(Optional::stream)
.map(hi -> tm().loadByKey(VKey.create(DomainHistory.class, hi)))
.map(dh -> VKey.create(Domain.class, dh.getRepoId()))
.collect(toImmutableList());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,7 @@ public ImmutableSet<PremiumList> loadObjects() {
tm().loadAllOf(PremiumList.class).stream()
.map(PremiumList::getName)
.map(PremiumListDao::getLatestRevision)
.filter(Optional::isPresent)
.map(Optional::get)
.flatMap(Optional::stream)
.collect(toImmutableSortedSet(Comparator.comparing(PremiumList::getName))));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,7 @@ public ImmutableSet<ReservedList> loadObjects() {
tm().loadAllOf(ReservedList.class).stream()
.map(ReservedList::getName)
.map(ReservedListDao::getLatestRevision)
.filter(Optional::isPresent)
.map(Optional::get)
.flatMap(Optional::stream)
.collect(toImmutableSortedSet(Comparator.comparing(ReservedList::getName))));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1577,7 +1577,7 @@ void testSuccess_onlyUseFirstValidDefaultToken() throws Exception {
persistHosts();
setupDefaultToken("aaaaa", 0, "TheRegistrar");
setupDefaultTokenWithDiscount();
runTest_defaultToken("aaaaa");
runTest_defaultToken("bbbbb");
}

@Test
Expand Down
Loading
Loading