diff --git a/core/src/main/java/google/registry/flows/contact/ContactCheckFlow.java b/core/src/main/java/google/registry/flows/contact/ContactCheckFlow.java index 9f924546e..07fe57708 100644 --- a/core/src/main/java/google/registry/flows/contact/ContactCheckFlow.java +++ b/core/src/main/java/google/registry/flows/contact/ContactCheckFlow.java @@ -19,6 +19,7 @@ import static google.registry.flows.ResourceFlowUtils.verifyTargetIdCount; import static google.registry.model.EppResourceUtils.checkResourcesExist; import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableSet; import google.registry.config.RegistryConfig.Config; import google.registry.flows.EppException; import google.registry.flows.ExtensionManager; @@ -33,8 +34,6 @@ import google.registry.model.eppoutput.CheckData.ContactCheckData; import google.registry.model.eppoutput.EppResponse; import google.registry.model.reporting.IcannReportingTypes.ActivityReportField; import google.registry.util.Clock; -import java.util.List; -import java.util.Set; import javax.inject.Inject; /** @@ -59,9 +58,10 @@ public final class ContactCheckFlow implements Flow { public final EppResponse run() throws EppException { extensionManager.validate(); // There are no legal extensions for this flow. validateClientIsLoggedIn(clientId); - List targetIds = ((Check) resourceCommand).getTargetIds(); + ImmutableList targetIds = ((Check) resourceCommand).getTargetIds(); verifyTargetIdCount(targetIds, maxChecks); - Set existingIds = checkResourcesExist(ContactResource.class, targetIds, clock.nowUtc()); + ImmutableSet existingIds = + checkResourcesExist(ContactResource.class, targetIds, clock.nowUtc()); ImmutableList.Builder checks = new ImmutableList.Builder<>(); for (String id : targetIds) { boolean unused = !existingIds.contains(id); diff --git a/core/src/main/java/google/registry/flows/domain/DomainCheckFlow.java b/core/src/main/java/google/registry/flows/domain/DomainCheckFlow.java index 939ff3e70..d7fec83ca 100644 --- a/core/src/main/java/google/registry/flows/domain/DomainCheckFlow.java +++ b/core/src/main/java/google/registry/flows/domain/DomainCheckFlow.java @@ -15,6 +15,8 @@ package google.registry.flows.domain; import static com.google.common.base.Strings.emptyToNull; +import static com.google.common.collect.ImmutableList.toImmutableList; +import static com.google.common.collect.ImmutableMap.toImmutableMap; import static google.registry.flows.FlowUtils.validateClientIsLoggedIn; import static google.registry.flows.ResourceFlowUtils.verifyTargetIdCount; import static google.registry.flows.domain.DomainFlowUtils.checkAllowedAccessToTld; @@ -26,7 +28,6 @@ import static google.registry.flows.domain.DomainFlowUtils.isValidReservedCreate import static google.registry.flows.domain.DomainFlowUtils.validateDomainName; import static google.registry.flows.domain.DomainFlowUtils.validateDomainNameWithIdnTables; import static google.registry.flows.domain.DomainFlowUtils.verifyNotInPredelegation; -import static google.registry.model.EppResourceUtils.checkResourcesExist; import static google.registry.model.registry.Registry.TldState.START_DATE_SUNRISE; import static google.registry.model.registry.label.ReservationType.getTypeOfHighestSeverity; @@ -48,11 +49,14 @@ import google.registry.flows.custom.DomainCheckFlowCustomLogic.BeforeResponsePar import google.registry.flows.custom.DomainCheckFlowCustomLogic.BeforeResponseReturnData; import google.registry.flows.domain.token.AllocationTokenDomainCheckResults; import google.registry.flows.domain.token.AllocationTokenFlowUtils; +import google.registry.model.EppResource; import google.registry.model.domain.DomainBase; import google.registry.model.domain.DomainCommand.Check; import google.registry.model.domain.fee.FeeCheckCommandExtension; import google.registry.model.domain.fee.FeeCheckCommandExtensionItem; import google.registry.model.domain.fee.FeeCheckResponseExtensionItem; +import google.registry.model.domain.fee.FeeQueryCommandExtensionItem.CommandName; +import google.registry.model.domain.fee06.FeeCheckCommandExtensionV06; import google.registry.model.domain.launch.LaunchCheckExtension; import google.registry.model.domain.token.AllocationToken; import google.registry.model.domain.token.AllocationTokenExtension; @@ -62,14 +66,14 @@ import google.registry.model.eppoutput.CheckData.DomainCheck; import google.registry.model.eppoutput.CheckData.DomainCheckData; import google.registry.model.eppoutput.EppResponse; import google.registry.model.eppoutput.EppResponse.ResponseExtension; +import google.registry.model.index.ForeignKeyIndex; import google.registry.model.registry.Registry; import google.registry.model.registry.Registry.TldState; import google.registry.model.registry.label.ReservationType; import google.registry.model.reporting.IcannReportingTypes.ActivityReportField; +import google.registry.persistence.VKey; import google.registry.util.Clock; import java.util.HashSet; -import java.util.List; -import java.util.Map; import java.util.Optional; import java.util.Set; import javax.inject.Inject; @@ -110,14 +114,20 @@ public final class DomainCheckFlow implements Flow { @Inject ExtensionManager extensionManager; @Inject EppInput eppInput; @Inject @ClientId String clientId; - @Inject @Config("maxChecks") int maxChecks; + + @Inject + @Config("maxChecks") + int maxChecks; + @Inject @Superuser boolean isSuperuser; @Inject Clock clock; @Inject EppResponse.Builder responseBuilder; @Inject AllocationTokenFlowUtils allocationTokenFlowUtils; @Inject DomainCheckFlowCustomLogic flowCustomLogic; @Inject DomainPricingLogic pricingLogic; - @Inject DomainCheckFlow() {} + + @Inject + DomainCheckFlow() {} @Override public EppResponse run() throws EppException { @@ -126,39 +136,41 @@ public final class DomainCheckFlow implements Flow { flowCustomLogic.beforeValidation(); extensionManager.validate(); validateClientIsLoggedIn(clientId); - List targetIds = ((Check) resourceCommand).getTargetIds(); - verifyTargetIdCount(targetIds, maxChecks); + ImmutableList domainNames = ((Check) resourceCommand).getTargetIds(); + verifyTargetIdCount(domainNames, maxChecks); DateTime now = clock.nowUtc(); - ImmutableMap.Builder domains = new ImmutableMap.Builder<>(); + ImmutableMap.Builder parsedDomainsBuilder = + new ImmutableMap.Builder<>(); // Only check that the registrar has access to a TLD the first time it is encountered Set seenTlds = new HashSet<>(); - for (String targetId : ImmutableSet.copyOf(targetIds)) { - InternetDomainName domainName = validateDomainName(targetId); - validateDomainNameWithIdnTables(domainName); + for (String domainName : ImmutableSet.copyOf(domainNames)) { + InternetDomainName parsedDomain = validateDomainName(domainName); + validateDomainNameWithIdnTables(parsedDomain); // This validation is moderately expensive, so cache the results. - domains.put(targetId, domainName); - String tld = domainName.parent().toString(); + parsedDomainsBuilder.put(domainName, parsedDomain); + String tld = parsedDomain.parent().toString(); boolean tldFirstTimeSeen = seenTlds.add(tld); if (tldFirstTimeSeen && !isSuperuser) { checkAllowedAccessToTld(clientId, tld); verifyNotInPredelegation(Registry.get(tld), now); } } - ImmutableMap domainNames = domains.build(); + ImmutableMap parsedDomains = parsedDomainsBuilder.build(); flowCustomLogic.afterValidation( DomainCheckFlowCustomLogic.AfterValidationParameters.newBuilder() - .setDomainNames(domainNames) + .setDomainNames(parsedDomains) // TODO: Use as of date from fee extension v0.12 instead of now, if specified. .setAsOfDate(now) .build()); - Set existingIds = checkResourcesExist(DomainBase.class, targetIds, now); + ImmutableMap> existingDomains = + ForeignKeyIndex.load(DomainBase.class, domainNames, now); Optional allocationTokenExtension = eppInput.getSingleExtension(AllocationTokenExtension.class); Optional tokenDomainCheckResults = allocationTokenExtension.map( tokenExtension -> allocationTokenFlowUtils.checkDomainsWithToken( - ImmutableList.copyOf(domainNames.values()), + ImmutableList.copyOf(parsedDomains.values()), tokenExtension.getAllocationToken(), clientId, now)); @@ -173,18 +185,18 @@ public final class DomainCheckFlow implements Flow { .orElse(ImmutableMap.of()); Optional allocationToken = tokenDomainCheckResults.flatMap(AllocationTokenDomainCheckResults::token); - for (String targetId : targetIds) { + for (String domainName : domainNames) { Optional message = getMessageForCheck( - domainNames.get(targetId), - existingIds, + parsedDomains.get(domainName), + existingDomains, domainCheckResults, tldStates, allocationToken); boolean isAvailable = !message.isPresent(); - checksBuilder.add(DomainCheck.create(isAvailable, targetId, message.orElse(null))); + checksBuilder.add(DomainCheck.create(isAvailable, domainName, message.orElse(null))); if (isAvailable) { - availableDomains.add(targetId); + availableDomains.add(domainName); } } BeforeResponseReturnData responseData = @@ -193,7 +205,11 @@ public final class DomainCheckFlow implements Flow { .setDomainChecks(checksBuilder.build()) .setResponseExtensions( getResponseExtensions( - domainNames, availableDomains.build(), now, allocationToken)) + parsedDomains, + existingDomains, + availableDomains.build(), + now, + allocationToken)) .setAsOfDate(now) .build()); return responseBuilder @@ -204,11 +220,11 @@ public final class DomainCheckFlow implements Flow { private Optional getMessageForCheck( InternetDomainName domainName, - Set existingIds, + ImmutableMap> existingDomains, ImmutableMap tokenCheckResults, - Map tldStates, + ImmutableMap tldStates, Optional allocationToken) { - if (existingIds.contains(domainName.toString())) { + if (existingDomains.containsKey(domainName.toString())) { return Optional.of("In use"); } TldState tldState = tldStates.get(domainName.parent().toString()); @@ -228,6 +244,7 @@ public final class DomainCheckFlow implements Flow { /** Handle the fee check extension. */ private ImmutableList getResponseExtensions( ImmutableMap domainNames, + ImmutableMap> existingDomains, ImmutableSet availableDomains, DateTime now, Optional allocationToken) @@ -240,6 +257,9 @@ public final class DomainCheckFlow implements Flow { FeeCheckCommandExtension feeCheck = feeCheckOpt.get(); ImmutableList.Builder responseItems = new ImmutableList.Builder<>(); + ImmutableMap domainObjs = + loadDomainsForRestoreChecks(feeCheck, domainNames, existingDomains); + for (FeeCheckCommandExtensionItem feeCheckItem : feeCheck.getItems()) { for (String domainName : getDomainNamesToCheckForFee(feeCheckItem, domainNames.keySet())) { FeeCheckResponseExtensionItem.Builder builder = feeCheckItem.createResponseBuilder(); @@ -247,7 +267,7 @@ public final class DomainCheckFlow implements Flow { feeCheckItem, builder, domainNames.get(domainName), - Optional.empty(), + Optional.ofNullable((DomainBase) domainObjs.get(domainName)), feeCheck.getCurrency(), now, pricingLogic, @@ -259,12 +279,57 @@ public final class DomainCheckFlow implements Flow { return ImmutableList.of(feeCheck.createResponse(responseItems.build())); } + /** + * Loads and returns all existing domains that are having restore fees checked. + * + *

This is necessary so that we can check their expiration dates to determine if a one-year + * renewal is part of the cost of a restore. + * + *

This may be resource-intensive for large checks of many restore fees, but those are + * comparatively rare, and we are at least using an in-memory cache. Also this will get a lot + * nicer in Cloud SQL when we can SELECT just the fields we want rather than having to load the + * entire entity. + */ + private ImmutableMap loadDomainsForRestoreChecks( + FeeCheckCommandExtension feeCheck, + ImmutableMap domainNames, + ImmutableMap> existingDomains) { + ImmutableList restoreCheckDomains; + if (feeCheck instanceof FeeCheckCommandExtensionV06) { + // The V06 fee extension supports specifying the command fees to check on a per-domain basis. + restoreCheckDomains = + feeCheck.getItems().stream() + .filter(fc -> fc.getCommandName() == CommandName.RESTORE) + .map(FeeCheckCommandExtensionItem::getDomainName) + .collect(toImmutableList()); + } else if (feeCheck.getItems().stream() + .anyMatch(fc -> fc.getCommandName() == CommandName.RESTORE)) { + // The more recent fee extension versions support specifying the command fees to check only on + // the overall domain check, not per-domain. + restoreCheckDomains = ImmutableList.copyOf(domainNames.keySet()); + } else { + // Fall-through case for more recent fee extension versions when the restore fee isn't being + // checked. + restoreCheckDomains = ImmutableList.of(); + } + + // Filter down to just domains we know exist and then use the EppResource cache to load them. + ImmutableMap> existingDomainsToLoad = + restoreCheckDomains.stream() + .filter(existingDomains::containsKey) + .collect(toImmutableMap(d -> d, d -> existingDomains.get(d).getResourceKey())); + ImmutableMap, EppResource> loadedDomains = + EppResource.loadCached(ImmutableList.copyOf(existingDomainsToLoad.values())); + return ImmutableMap.copyOf( + Maps.transformEntries(existingDomainsToLoad, (k, v) -> loadedDomains.get(v))); + } + /** * Return the domains to be checked for a particular fee check item. Some versions of the fee * extension specify the domain name in the extension item, while others use the list of domain * names from the regular check domain availability list. */ - private Set getDomainNamesToCheckForFee( + private ImmutableSet getDomainNamesToCheckForFee( FeeCheckCommandExtensionItem feeCheckItem, ImmutableSet availabilityCheckDomains) throws OnlyCheckedNamesCanBeFeeCheckedException { if (feeCheckItem.isDomainNameSupported()) { diff --git a/core/src/main/java/google/registry/flows/domain/DomainClaimsCheckFlow.java b/core/src/main/java/google/registry/flows/domain/DomainClaimsCheckFlow.java index 8ac4a408d..a98c8cc89 100644 --- a/core/src/main/java/google/registry/flows/domain/DomainClaimsCheckFlow.java +++ b/core/src/main/java/google/registry/flows/domain/DomainClaimsCheckFlow.java @@ -48,7 +48,6 @@ import google.registry.model.reporting.IcannReportingTypes.ActivityReportField; import google.registry.model.tmch.ClaimsListShard; import google.registry.util.Clock; import java.util.HashSet; -import java.util.List; import java.util.Optional; import java.util.Set; import javax.inject.Inject; @@ -87,14 +86,14 @@ public final class DomainClaimsCheckFlow implements Flow { if (eppInput.getSingleExtension(AllocationTokenExtension.class).isPresent()) { throw new DomainClaimsCheckNotAllowedWithAllocationTokens(); } - List targetIds = ((Check) resourceCommand).getTargetIds(); - verifyTargetIdCount(targetIds, maxChecks); + ImmutableList domainNames = ((Check) resourceCommand).getTargetIds(); + verifyTargetIdCount(domainNames, maxChecks); Set seenTlds = new HashSet<>(); ImmutableList.Builder launchChecksBuilder = new ImmutableList.Builder<>(); - for (String targetId : ImmutableSet.copyOf(targetIds)) { - InternetDomainName domainName = validateDomainName(targetId); - validateDomainNameWithIdnTables(domainName); - String tld = domainName.parent().toString(); + for (String domainName : ImmutableSet.copyOf(domainNames)) { + InternetDomainName parsedDomain = validateDomainName(domainName); + validateDomainNameWithIdnTables(parsedDomain); + String tld = parsedDomain.parent().toString(); // Only validate access to a TLD the first time it is encountered. if (seenTlds.add(tld)) { if (!isSuperuser) { @@ -105,10 +104,10 @@ public final class DomainClaimsCheckFlow implements Flow { verifyClaimsPeriodNotEnded(registry, now); } } - Optional claimKey = ClaimsListShard.get().getClaimKey(domainName.parts().get(0)); + Optional claimKey = ClaimsListShard.get().getClaimKey(parsedDomain.parts().get(0)); launchChecksBuilder.add( LaunchCheck.create( - LaunchCheckName.create(claimKey.isPresent(), targetId), claimKey.orElse(null))); + LaunchCheckName.create(claimKey.isPresent(), domainName), claimKey.orElse(null))); } return responseBuilder .setOnlyExtension(LaunchCheckResponseExtension.create(CLAIMS, launchChecksBuilder.build())) diff --git a/core/src/main/java/google/registry/flows/domain/DomainFlowUtils.java b/core/src/main/java/google/registry/flows/domain/DomainFlowUtils.java index 983c58dfc..32616c7bc 100644 --- a/core/src/main/java/google/registry/flows/domain/DomainFlowUtils.java +++ b/core/src/main/java/google/registry/flows/domain/DomainFlowUtils.java @@ -17,6 +17,7 @@ package google.registry.flows.domain; import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkState; import static com.google.common.base.Predicates.equalTo; +import static com.google.common.base.Strings.emptyToNull; import static com.google.common.collect.ImmutableList.toImmutableList; import static com.google.common.collect.ImmutableMap.toImmutableMap; import static com.google.common.collect.ImmutableSetMultimap.toImmutableSetMultimap; @@ -32,7 +33,9 @@ import static google.registry.model.registry.Registry.TldState.GENERAL_AVAILABIL import static google.registry.model.registry.Registry.TldState.PREDELEGATION; import static google.registry.model.registry.Registry.TldState.QUIET_PERIOD; import static google.registry.model.registry.Registry.TldState.START_DATE_SUNRISE; +import static google.registry.model.registry.label.ReservationType.ALLOWED_IN_SUNRISE; import static google.registry.model.registry.label.ReservationType.FULLY_BLOCKED; +import static google.registry.model.registry.label.ReservationType.NAME_COLLISION; import static google.registry.model.registry.label.ReservationType.RESERVED_FOR_ANCHOR_TENANT; import static google.registry.model.registry.label.ReservationType.RESERVED_FOR_SPECIFIC_USE; import static google.registry.persistence.transaction.TransactionManagerFactory.tm; @@ -87,6 +90,7 @@ import google.registry.model.domain.DomainCommand.InvalidReferencesException; import google.registry.model.domain.DomainCommand.Update; import google.registry.model.domain.ForeignKeyedDesignatedContact; import google.registry.model.domain.Period; +import google.registry.model.domain.fee.BaseFee; import google.registry.model.domain.fee.BaseFee.FeeType; import google.registry.model.domain.fee.Credit; import google.registry.model.domain.fee.Fee; @@ -152,9 +156,7 @@ public class DomainFlowUtils { /** Reservation types that are only allowed in sunrise by policy. */ public static final ImmutableSet TYPES_ALLOWED_FOR_CREATE_ONLY_IN_SUNRISE = - Sets.immutableEnumSet( - ReservationType.ALLOWED_IN_SUNRISE, - ReservationType.NAME_COLLISION); + Sets.immutableEnumSet(ALLOWED_IN_SUNRISE, NAME_COLLISION); /** Warning message for allocation of collision domains in sunrise. */ public static final String COLLISION_MESSAGE = @@ -583,15 +585,15 @@ public class DomainFlowUtils { builder .setCommand(feeRequest.getCommandName(), feeRequest.getPhase(), feeRequest.getSubphase()) .setCurrencyIfSupported(registry.getCurrency()) - .setPeriod(feeRequest.getPeriod()) - .setClass(pricingLogic.getFeeClass(domainNameString, now).orElse(null)); + .setPeriod(feeRequest.getPeriod()); + String feeClass = null; ImmutableList fees = ImmutableList.of(); switch (feeRequest.getCommandName()) { case CREATE: // Don't return a create price for reserved names. if (isReserved(domainName, isSunrise) && !isAvailable) { - builder.setClass("reserved"); // Override whatever class we've set above. + feeClass = "reserved"; builder.setAvailIfSupported(false); builder.setReasonIfSupported("reserved"); } else { @@ -616,15 +618,11 @@ public class DomainFlowUtils { throw new RestoresAreAlwaysForOneYearException(); } builder.setAvailIfSupported(true); - // The domain object is present only on domain info commands, not on domain check commands, - // because check commands can query up to 50 domains and it isn't performant to load them - // all. So, only on info commands can we actually determine if we should include the renewal - // fee because the domain needs to have been loaded in order to know its expiration time. We - // default to including the renewal fee on domain checks because typically most domains are - // deleted during the autorenew grace period and thus if restored will require a renewal, - // but this is just a best guess. + // Domains that never existed, or that used to exist but have completed the entire deletion + // process, don't count as expired for the purposes of requiring an added year of renewal on + // restore because they can't be restored in the first place. boolean isExpired = - !domain.isPresent() || domain.get().getRegistrationExpirationTime().isBefore(now); + domain.isPresent() && domain.get().getRegistrationExpirationTime().isBefore(now); fees = pricingLogic.getRestorePrice(registry, domainNameString, now, isExpired).getFees(); break; case TRANSFER: @@ -642,6 +640,23 @@ public class DomainFlowUtils { throw new UnknownFeeCommandException(feeRequest.getUnparsedCommandName()); } + if (feeClass == null) { + // Calculate and set the correct fee class based on whether the name is a collision name or we + // are returning any premium fees, but only if the fee class isn't already set (i.e. because + // the domain is reserved, which overrides any other classes). + boolean isNameCollisionInSunrise = + registry.getTldState(now).equals(START_DATE_SUNRISE) + && getReservationTypes(domainName).contains(NAME_COLLISION); + boolean isPremium = fees.stream().anyMatch(BaseFee::isPremium); + feeClass = + emptyToNull( + Joiner.on('-') + .skipNulls() + .join( + isPremium ? "premium" : null, isNameCollisionInSunrise ? "collision" : null)); + } + builder.setClass(feeClass); + // Set the fees, and based on the validDateRange of the fees, set the notAfterDate. if (!fees.isEmpty()) { builder.setFees(fees); diff --git a/core/src/main/java/google/registry/flows/domain/DomainPricingLogic.java b/core/src/main/java/google/registry/flows/domain/DomainPricingLogic.java index 988ef03e2..ffd7129df 100644 --- a/core/src/main/java/google/registry/flows/domain/DomainPricingLogic.java +++ b/core/src/main/java/google/registry/flows/domain/DomainPricingLogic.java @@ -15,7 +15,6 @@ package google.registry.flows.domain; import static google.registry.flows.domain.DomainFlowUtils.zeroInCurrency; -import static google.registry.pricing.PricingEngineProxy.getDomainFeeClass; import static google.registry.pricing.PricingEngineProxy.getPricesForDomainName; import com.google.common.net.InternetDomainName; @@ -186,11 +185,6 @@ public final class DomainPricingLogic { .build()); } - /** Returns the fee class for a given domain and date. */ - public Optional getFeeClass(String domainName, DateTime dateTime) { - return getDomainFeeClass(domainName, dateTime); - } - /** Returns the domain create cost with allocation-token-related discounts applied. */ private Money getDomainCreateCostWithDiscount( DomainPrices domainPrices, int years, Optional allocationToken) diff --git a/core/src/main/java/google/registry/flows/host/HostCheckFlow.java b/core/src/main/java/google/registry/flows/host/HostCheckFlow.java index b7e089fe0..b00c72e19 100644 --- a/core/src/main/java/google/registry/flows/host/HostCheckFlow.java +++ b/core/src/main/java/google/registry/flows/host/HostCheckFlow.java @@ -19,6 +19,7 @@ import static google.registry.flows.ResourceFlowUtils.verifyTargetIdCount; import static google.registry.model.EppResourceUtils.checkResourcesExist; import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableSet; import google.registry.config.RegistryConfig.Config; import google.registry.flows.EppException; import google.registry.flows.ExtensionManager; @@ -33,8 +34,6 @@ import google.registry.model.host.HostCommand.Check; import google.registry.model.host.HostResource; import google.registry.model.reporting.IcannReportingTypes.ActivityReportField; import google.registry.util.Clock; -import java.util.List; -import java.util.Set; import javax.inject.Inject; /** @@ -59,13 +58,14 @@ public final class HostCheckFlow implements Flow { public final EppResponse run() throws EppException { extensionManager.validate(); // There are no legal extensions for this flow. validateClientIsLoggedIn(clientId); - List targetIds = ((Check) resourceCommand).getTargetIds(); - verifyTargetIdCount(targetIds, maxChecks); - Set existingIds = checkResourcesExist(HostResource.class, targetIds, clock.nowUtc()); + ImmutableList hostnames = ((Check) resourceCommand).getTargetIds(); + verifyTargetIdCount(hostnames, maxChecks); + ImmutableSet existingIds = + checkResourcesExist(HostResource.class, hostnames, clock.nowUtc()); ImmutableList.Builder checks = new ImmutableList.Builder<>(); - for (String id : targetIds) { - boolean unused = !existingIds.contains(id); - checks.add(HostCheck.create(unused, id, unused ? null : "In use")); + for (String hostname : hostnames) { + boolean unused = !existingIds.contains(hostname); + checks.add(HostCheck.create(unused, hostname, unused ? null : "In use")); } return responseBuilder.setResData(HostCheckData.create(checks.build())).build(); } diff --git a/core/src/main/java/google/registry/model/EppResource.java b/core/src/main/java/google/registry/model/EppResource.java index 364a76738..e2ccc25af 100644 --- a/core/src/main/java/google/registry/model/EppResource.java +++ b/core/src/main/java/google/registry/model/EppResource.java @@ -364,9 +364,11 @@ public abstract class EppResource extends BackupGroupRoot implements Buildable { /** * A limited size, limited time cache for EPP resource entities. * - *

This is only used to cache contacts and hosts for the purposes of checking whether they are - * deleted or in pending delete during a few domain flows. Any operations on contacts and hosts - * directly should of course never use the cache. + *

This is used to cache contacts and hosts for the purposes of checking whether they are + * deleted or in pending delete during a few domain flows, and also to cache domains for the + * purpose of determining restore fees in domain checks. Any mutating operations directly on EPP + * resources should of course never use the cache as they always need perfectly up-to-date + * information. */ @NonFinalForTesting private static LoadingCache, EppResource> cacheEppResources = diff --git a/core/src/main/java/google/registry/model/EppResourceUtils.java b/core/src/main/java/google/registry/model/EppResourceUtils.java index 10d09e393..c543021e5 100644 --- a/core/src/main/java/google/registry/model/EppResourceUtils.java +++ b/core/src/main/java/google/registry/model/EppResourceUtils.java @@ -23,6 +23,7 @@ import static google.registry.util.DateTimeUtils.isBeforeOrAt; import static google.registry.util.DateTimeUtils.latestOf; import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableSet; import com.google.common.flogger.FluentLogger; import com.googlecode.objectify.Key; import com.googlecode.objectify.Result; @@ -45,7 +46,6 @@ import google.registry.model.transfer.TransferStatus; import java.util.List; import java.util.Map.Entry; import java.util.Optional; -import java.util.Set; import java.util.function.Function; import javax.annotation.Nullable; import org.joda.time.DateTime; @@ -169,7 +169,7 @@ public final class EppResourceUtils { * @param uniqueIds a list of ids to match * @param now the logical time of the check */ - public static Set checkResourcesExist( + public static ImmutableSet checkResourcesExist( Class clazz, List uniqueIds, final DateTime now) { return ForeignKeyIndex.load(clazz, uniqueIds, now).keySet(); } diff --git a/core/src/main/java/google/registry/model/domain/DomainCommand.java b/core/src/main/java/google/registry/model/domain/DomainCommand.java index 6584f0bb8..50ffe88e6 100644 --- a/core/src/main/java/google/registry/model/domain/DomainCommand.java +++ b/core/src/main/java/google/registry/model/domain/DomainCommand.java @@ -41,7 +41,6 @@ import google.registry.model.eppinput.ResourceCommand.SingleResourceCommand; import google.registry.model.host.HostResource; import google.registry.model.index.ForeignKeyIndex; import google.registry.persistence.VKey; -import java.util.Map; import java.util.Set; import javax.annotation.Nullable; import javax.xml.bind.annotation.XmlAttribute; @@ -447,7 +446,8 @@ public class DomainCommand { private static ImmutableMap> loadByForeignKeysCached( final Set foreignKeys, final Class clazz, final DateTime now) throws InvalidReferencesException { - Map> fkis = ForeignKeyIndex.loadCached(clazz, foreignKeys, now); + ImmutableMap> fkis = + ForeignKeyIndex.loadCached(clazz, foreignKeys, now); if (!fkis.keySet().equals(foreignKeys)) { throw new InvalidReferencesException( clazz, ImmutableSet.copyOf(difference(foreignKeys, fkis.keySet()))); diff --git a/core/src/main/java/google/registry/model/domain/fee/FeeCheckCommandExtension.java b/core/src/main/java/google/registry/model/domain/fee/FeeCheckCommandExtension.java index 6e3a37435..9787abfa5 100644 --- a/core/src/main/java/google/registry/model/domain/fee/FeeCheckCommandExtension.java +++ b/core/src/main/java/google/registry/model/domain/fee/FeeCheckCommandExtension.java @@ -15,7 +15,6 @@ package google.registry.model.domain.fee; import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableSet; import google.registry.model.eppinput.EppInput.CommandExtension; import org.joda.money.CurrencyUnit; @@ -40,7 +39,7 @@ public interface FeeCheckCommandExtension< */ CurrencyUnit getCurrency(); - ImmutableSet getItems(); + ImmutableList getItems(); R createResponse(ImmutableList items); } diff --git a/core/src/main/java/google/registry/model/domain/fee06/FeeCheckCommandExtensionV06.java b/core/src/main/java/google/registry/model/domain/fee06/FeeCheckCommandExtensionV06.java index 89108e48a..9cd050ea3 100644 --- a/core/src/main/java/google/registry/model/domain/fee06/FeeCheckCommandExtensionV06.java +++ b/core/src/main/java/google/registry/model/domain/fee06/FeeCheckCommandExtensionV06.java @@ -17,11 +17,10 @@ package google.registry.model.domain.fee06; import static google.registry.util.CollectionUtils.nullToEmptyImmutableCopy; import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableSet; import google.registry.model.ImmutableObject; import google.registry.model.domain.fee.FeeCheckCommandExtension; import google.registry.model.domain.fee.FeeCheckResponseExtensionItem; -import java.util.Set; +import java.util.List; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; import org.joda.money.CurrencyUnit; @@ -34,7 +33,7 @@ public class FeeCheckCommandExtensionV06 extends ImmutableObject FeeCheckResponseExtensionV06> { @XmlElement(name = "domain") - Set items; + List items; @Override public CurrencyUnit getCurrency() { @@ -42,7 +41,7 @@ public class FeeCheckCommandExtensionV06 extends ImmutableObject } @Override - public ImmutableSet getItems() { + public ImmutableList getItems() { return nullToEmptyImmutableCopy(items); } diff --git a/core/src/main/java/google/registry/model/domain/fee11/FeeCheckCommandExtensionV11.java b/core/src/main/java/google/registry/model/domain/fee11/FeeCheckCommandExtensionV11.java index 086350b2c..cb312649c 100644 --- a/core/src/main/java/google/registry/model/domain/fee11/FeeCheckCommandExtensionV11.java +++ b/core/src/main/java/google/registry/model/domain/fee11/FeeCheckCommandExtensionV11.java @@ -17,7 +17,6 @@ package google.registry.model.domain.fee11; import static com.google.common.base.Preconditions.checkState; import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableSet; import google.registry.model.ImmutableObject; import google.registry.model.domain.Period; import google.registry.model.domain.fee.FeeCheckCommandExtension; @@ -69,8 +68,8 @@ public class FeeCheckCommandExtensionV11 extends ImmutableObject } @Override - public ImmutableSet getItems() { - return ImmutableSet.of(new FeeCheckCommandExtensionItemV11()); + public ImmutableList getItems() { + return ImmutableList.of(new FeeCheckCommandExtensionItemV11()); } @Override diff --git a/core/src/main/java/google/registry/model/domain/fee12/FeeCheckCommandExtensionV12.java b/core/src/main/java/google/registry/model/domain/fee12/FeeCheckCommandExtensionV12.java index c0b094df6..4bcf1bf54 100644 --- a/core/src/main/java/google/registry/model/domain/fee12/FeeCheckCommandExtensionV12.java +++ b/core/src/main/java/google/registry/model/domain/fee12/FeeCheckCommandExtensionV12.java @@ -17,11 +17,10 @@ package google.registry.model.domain.fee12; import static google.registry.util.CollectionUtils.nullToEmptyImmutableCopy; import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableSet; import google.registry.model.ImmutableObject; import google.registry.model.domain.fee.FeeCheckCommandExtension; import google.registry.model.domain.fee.FeeCheckResponseExtensionItem; -import java.util.Set; +import java.util.List; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlType; @@ -43,10 +42,10 @@ public class FeeCheckCommandExtensionV12 extends ImmutableObject } @XmlElement(name = "command") - Set items; + List items; @Override - public ImmutableSet getItems() { + public ImmutableList getItems() { return nullToEmptyImmutableCopy(items); } diff --git a/core/src/main/java/google/registry/model/index/ForeignKeyIndex.java b/core/src/main/java/google/registry/model/index/ForeignKeyIndex.java index cf37ab17a..1f6a495de 100644 --- a/core/src/main/java/google/registry/model/index/ForeignKeyIndex.java +++ b/core/src/main/java/google/registry/model/index/ForeignKeyIndex.java @@ -15,7 +15,6 @@ package google.registry.model.index; import static com.google.common.collect.ImmutableList.toImmutableList; -import static com.google.common.collect.Maps.filterValues; import static google.registry.config.RegistryConfig.getEppResourceCachingDuration; import static google.registry.config.RegistryConfig.getEppResourceMaxCachedEntries; import static google.registry.model.ofy.ObjectifyService.ofy; @@ -178,11 +177,11 @@ public abstract class ForeignKeyIndex extends BackupGroup *

The returned map will omit any keys for which the {@link ForeignKeyIndex} doesn't exist or * has been soft deleted. */ - public static Map> load( + public static ImmutableMap> load( Class clazz, Iterable foreignKeys, final DateTime now) { - return filterValues( - ofy().load().type(mapToFkiClass(clazz)).ids(foreignKeys), - (ForeignKeyIndex fki) -> now.isBefore(fki.deletionTime)); + return ofy().load().type(mapToFkiClass(clazz)).ids(foreignKeys).entrySet().stream() + .filter(e -> now.isBefore(e.getValue().deletionTime)) + .collect(ImmutableMap.toImmutableMap(Map.Entry::getKey, Map.Entry::getValue)); } static final CacheLoader>, Optional>> CACHE_LOADER = @@ -249,7 +248,7 @@ public abstract class ForeignKeyIndex extends BackupGroup *

Don't use the cached version of this method unless you really need it for performance * reasons, and are OK with the trade-offs in loss of transactional consistency. */ - public static Map> loadCached( + public static ImmutableMap> loadCached( Class clazz, Iterable foreignKeys, final DateTime now) { if (!RegistryConfig.isEppResourceCachingEnabled()) { return tm().doTransactionless(() -> load(clazz, foreignKeys, now)); @@ -262,16 +261,14 @@ public abstract class ForeignKeyIndex extends BackupGroup // This cast is safe because when we loaded ForeignKeyIndexes above we used type clazz, which // is scoped to E. @SuppressWarnings("unchecked") - Map> fkisFromCache = cacheForeignKeyIndexes - .getAll(fkiKeys) - .entrySet() - .stream() - .filter(entry -> entry.getValue().isPresent()) - .filter(entry -> now.isBefore(entry.getValue().get().getDeletionTime())) - .collect( - ImmutableMap.toImmutableMap( - entry -> entry.getKey().getName(), - entry -> (ForeignKeyIndex) entry.getValue().get())); + ImmutableMap> fkisFromCache = + cacheForeignKeyIndexes.getAll(fkiKeys).entrySet().stream() + .filter(entry -> entry.getValue().isPresent()) + .filter(entry -> now.isBefore(entry.getValue().get().getDeletionTime())) + .collect( + ImmutableMap.toImmutableMap( + entry -> entry.getKey().getName(), + entry -> (ForeignKeyIndex) entry.getValue().get())); return fkisFromCache; } catch (ExecutionException e) { throw new RuntimeException("Error loading cached ForeignKeyIndexes", e.getCause()); diff --git a/core/src/main/java/google/registry/model/pricing/PremiumPricingEngine.java b/core/src/main/java/google/registry/model/pricing/PremiumPricingEngine.java index 590b74e93..cbabe8d79 100644 --- a/core/src/main/java/google/registry/model/pricing/PremiumPricingEngine.java +++ b/core/src/main/java/google/registry/model/pricing/PremiumPricingEngine.java @@ -14,7 +14,6 @@ package google.registry.model.pricing; -import java.util.Optional; import org.joda.money.Money; import org.joda.time.DateTime; @@ -46,18 +45,12 @@ public interface PremiumPricingEngine { // create, renew, restore, and transfer. private Money createCost; private Money renewCost; - private Optional feeClass; - static DomainPrices create( - boolean isPremium, - Money createCost, - Money renewCost, - Optional feeClass) { + static DomainPrices create(boolean isPremium, Money createCost, Money renewCost) { DomainPrices instance = new DomainPrices(); instance.isPremium = isPremium; instance.createCost = createCost; instance.renewCost = renewCost; - instance.feeClass = feeClass; return instance; } @@ -75,10 +68,5 @@ public interface PremiumPricingEngine { public Money getRenewCost() { return renewCost; } - - /** Returns the fee class of the cost (used for the Fee extension). */ - public Optional getFeeClass() { - return feeClass; - } } } diff --git a/core/src/main/java/google/registry/model/pricing/StaticPremiumListPricingEngine.java b/core/src/main/java/google/registry/model/pricing/StaticPremiumListPricingEngine.java index ca93c8a0b..6d3ed38bd 100644 --- a/core/src/main/java/google/registry/model/pricing/StaticPremiumListPricingEngine.java +++ b/core/src/main/java/google/registry/model/pricing/StaticPremiumListPricingEngine.java @@ -15,14 +15,9 @@ package google.registry.model.pricing; import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.base.Strings.emptyToNull; -import static google.registry.model.registry.Registry.TldState.START_DATE_SUNRISE; import static google.registry.model.registry.label.PremiumListUtils.getPremiumPrice; -import static google.registry.model.registry.label.ReservationType.NAME_COLLISION; -import static google.registry.model.registry.label.ReservedList.getReservationTypes; import static google.registry.util.DomainNameUtils.getTldFromDomainName; -import com.google.common.base.Joiner; import com.google.common.net.InternetDomainName; import google.registry.model.registry.Registry; import java.util.Optional; @@ -44,16 +39,9 @@ public final class StaticPremiumListPricingEngine implements PremiumPricingEngin String label = InternetDomainName.from(fullyQualifiedDomainName).parts().get(0); Registry registry = Registry.get(checkNotNull(tld, "tld")); Optional premiumPrice = getPremiumPrice(label, registry); - boolean isNameCollisionInSunrise = - registry.getTldState(priceTime).equals(START_DATE_SUNRISE) - && getReservationTypes(label, tld).contains(NAME_COLLISION); - String feeClass = emptyToNull(Joiner.on('-').skipNulls().join( - premiumPrice.isPresent() ? "premium" : null, - isNameCollisionInSunrise ? "collision" : null)); return DomainPrices.create( premiumPrice.isPresent(), premiumPrice.orElse(registry.getStandardCreateCost()), - premiumPrice.orElse(registry.getStandardRenewCost(priceTime)), - Optional.ofNullable(feeClass)); + premiumPrice.orElse(registry.getStandardRenewCost(priceTime))); } } diff --git a/core/src/main/java/google/registry/model/registry/Registry.java b/core/src/main/java/google/registry/model/registry/Registry.java index 859da9e65..4592d034e 100644 --- a/core/src/main/java/google/registry/model/registry/Registry.java +++ b/core/src/main/java/google/registry/model/registry/Registry.java @@ -587,8 +587,9 @@ public class Registry extends ImmutableObject implements Buildable { return Fee.create( eapFeeSchedule.getValueAtTime(now).getAmount(), FeeType.EAP, - // An EAP fee counts as premium so the domain's overall Fee doesn't show as standard-priced. - true, + // An EAP fee does not count as premium -- it's a separate one-time fee, independent of + // which the domain is separately considered standard vs premium depending on renewal price. + false, validPeriod, validPeriod.upperEndpoint()); } diff --git a/core/src/main/java/google/registry/pricing/PricingEngineProxy.java b/core/src/main/java/google/registry/pricing/PricingEngineProxy.java index 90170e63a..f3f9c258c 100644 --- a/core/src/main/java/google/registry/pricing/PricingEngineProxy.java +++ b/core/src/main/java/google/registry/pricing/PricingEngineProxy.java @@ -22,7 +22,6 @@ import google.registry.model.pricing.PremiumPricingEngine; import google.registry.model.pricing.PremiumPricingEngine.DomainPrices; import google.registry.model.registry.Registry; import java.util.Map; -import java.util.Optional; import org.joda.money.Money; import org.joda.time.DateTime; @@ -52,11 +51,6 @@ public final class PricingEngineProxy { return getPricesForDomainName(domainName, priceTime).isPremium(); } - /** Returns the fee class of the specified domain name. */ - public static Optional getDomainFeeClass(String domainName, DateTime priceTime) { - return getPricesForDomainName(domainName, priceTime).getFeeClass(); - } - /** * Returns the full {@link DomainPrices} details for the given domain name by dispatching to the * appropriate {@link PremiumPricingEngine} based on what is configured for the TLD that the diff --git a/core/src/test/java/google/registry/flows/domain/DomainCheckFlowTest.java b/core/src/test/java/google/registry/flows/domain/DomainCheckFlowTest.java index cf209cefa..d7f94e324 100644 --- a/core/src/test/java/google/registry/flows/domain/DomainCheckFlowTest.java +++ b/core/src/test/java/google/registry/flows/domain/DomainCheckFlowTest.java @@ -22,6 +22,7 @@ import static google.registry.model.registry.Registry.TldState.START_DATE_SUNRIS import static google.registry.testing.DatastoreHelper.createTld; import static google.registry.testing.DatastoreHelper.createTlds; import static google.registry.testing.DatastoreHelper.loadRegistrar; +import static google.registry.testing.DatastoreHelper.newDomainBase; import static google.registry.testing.DatastoreHelper.persistActiveDomain; import static google.registry.testing.DatastoreHelper.persistDeletedDomain; import static google.registry.testing.DatastoreHelper.persistPremiumList; @@ -65,6 +66,7 @@ import google.registry.flows.exceptions.TooManyResourceChecksException; import google.registry.model.domain.DomainBase; import google.registry.model.domain.token.AllocationToken; import google.registry.model.domain.token.AllocationToken.TokenStatus; +import google.registry.model.eppcommon.StatusValue; import google.registry.model.registry.Registry; import google.registry.model.registry.Registry.TldState; import google.registry.model.registry.label.ReservedList; @@ -656,6 +658,19 @@ public class DomainCheckFlowTest extends ResourceCheckFlowTestCase(Ordering.natural()) + .put(START_OF_TIME, Money.of(USD, 0)) + .put(clock.nowUtc().minusDays(1), Money.of(USD, 100)) + .put(clock.nowUtc().plusDays(1), Money.of(USD, 50)) + .put(clock.nowUtc().plusDays(2), Money.of(USD, 0)) + .build()) + .build()); + + runFlowAssertResponse(loadFile("domain_check_fee_premium_eap_response_v06_with_renewal.xml")); + } + @Test public void testFeeExtension_premiumLabels_v11_create() throws Exception { createTld("example"); @@ -730,6 +766,15 @@ public class DomainCheckFlowTest extends ResourceCheckFlowTestCaseNote that the actual XML must start with a UTF-8 standalone XML header, but the expected - * XML has no such restriction (and typically lacks the header entirely). + *

Note that the actual XML must start with a UTF-8 standalone XML header, but the expected XML + * has no such restriction (and typically lacks the header entirely). */ public static void assertXmlEquals(String expected, String actual, String... ignoredPaths) throws Exception { diff --git a/core/src/test/resources/google/registry/flows/domain/domain_check_fee_multiple_commands_response_v06.xml b/core/src/test/resources/google/registry/flows/domain/domain_check_fee_multiple_commands_response_v06.xml index cf011a6eb..13ff59558 100644 --- a/core/src/test/resources/google/registry/flows/domain/domain_check_fee_multiple_commands_response_v06.xml +++ b/core/src/test/resources/google/registry/flows/domain/domain_check_fee_multiple_commands_response_v06.xml @@ -38,7 +38,6 @@ USD restore 1 - 11.00 17.00 diff --git a/core/src/test/resources/google/registry/flows/domain/domain_check_fee_multiple_commands_response_v12.xml b/core/src/test/resources/google/registry/flows/domain/domain_check_fee_multiple_commands_response_v12.xml index 0f105a47c..e2b832535 100644 --- a/core/src/test/resources/google/registry/flows/domain/domain_check_fee_multiple_commands_response_v12.xml +++ b/core/src/test/resources/google/registry/flows/domain/domain_check_fee_multiple_commands_response_v12.xml @@ -46,7 +46,6 @@ 1 - 11.00 17.00 diff --git a/core/src/test/resources/google/registry/flows/domain/domain_check_fee_premium_eap_response_v06.xml b/core/src/test/resources/google/registry/flows/domain/domain_check_fee_premium_eap_response_v06.xml index 9ab706c0f..78366cc8e 100644 --- a/core/src/test/resources/google/registry/flows/domain/domain_check_fee_premium_eap_response_v06.xml +++ b/core/src/test/resources/google/registry/flows/domain/domain_check_fee_premium_eap_response_v06.xml @@ -43,9 +43,7 @@ USD restore 1 - 100.00 17.00 - premium diff --git a/core/src/test/resources/google/registry/flows/domain/domain_check_fee_premium_eap_response_v06_with_renewal.xml b/core/src/test/resources/google/registry/flows/domain/domain_check_fee_premium_eap_response_v06_with_renewal.xml new file mode 100644 index 000000000..23ba2eb6d --- /dev/null +++ b/core/src/test/resources/google/registry/flows/domain/domain_check_fee_premium_eap_response_v06_with_renewal.xml @@ -0,0 +1,58 @@ + + + + Command completed successfully + + + + + rich.example + In use + + + + + + + rich.example + USD + create + 1 + 100.00 + 100.00 + + premium + + + rich.example + USD + renew + 1 + 100.00 + premium + + + rich.example + USD + transfer + 1 + 100.00 + premium + + + rich.example + USD + restore + 1 + 100.00 + 17.00 + premium + + + + + ABC-12345 + server-trid + + + diff --git a/core/src/test/resources/google/registry/flows/domain/domain_check_fee_premium_response_v06.xml b/core/src/test/resources/google/registry/flows/domain/domain_check_fee_premium_response_v06.xml index 600c670f4..9ebeac37f 100644 --- a/core/src/test/resources/google/registry/flows/domain/domain_check_fee_premium_response_v06.xml +++ b/core/src/test/resources/google/registry/flows/domain/domain_check_fee_premium_response_v06.xml @@ -41,9 +41,7 @@ USD restore 1 - 100.00 17.00 - premium diff --git a/core/src/test/resources/google/registry/flows/domain/domain_check_fee_premium_response_v11_restore.xml b/core/src/test/resources/google/registry/flows/domain/domain_check_fee_premium_response_v11_restore.xml index a9900ef7e..2da4e0ace 100644 --- a/core/src/test/resources/google/registry/flows/domain/domain_check_fee_premium_response_v11_restore.xml +++ b/core/src/test/resources/google/registry/flows/domain/domain_check_fee_premium_response_v11_restore.xml @@ -20,9 +20,7 @@ restore USD 1 - 100.00 17.00 - premium diff --git a/core/src/test/resources/google/registry/flows/domain/domain_check_fee_premium_response_v11_restore_with_renewal.xml b/core/src/test/resources/google/registry/flows/domain/domain_check_fee_premium_response_v11_restore_with_renewal.xml new file mode 100644 index 000000000..36803fdf5 --- /dev/null +++ b/core/src/test/resources/google/registry/flows/domain/domain_check_fee_premium_response_v11_restore_with_renewal.xml @@ -0,0 +1,35 @@ + + + + Command completed successfully + + + + + rich.example + In use + + + + + + + + rich.example + + restore + USD + 1 + 100.00 + 17.00 + premium + + + + + ABC-12345 + server-trid + + + diff --git a/core/src/test/resources/google/registry/flows/domain/domain_check_fee_premium_response_v11_update.xml b/core/src/test/resources/google/registry/flows/domain/domain_check_fee_premium_response_v11_update.xml index 47572fef6..946c7f30f 100644 --- a/core/src/test/resources/google/registry/flows/domain/domain_check_fee_premium_response_v11_update.xml +++ b/core/src/test/resources/google/registry/flows/domain/domain_check_fee_premium_response_v11_update.xml @@ -21,7 +21,6 @@ USD 1 0.00 - premium diff --git a/core/src/test/resources/google/registry/flows/domain/domain_check_fee_premium_response_v12.xml b/core/src/test/resources/google/registry/flows/domain/domain_check_fee_premium_response_v12.xml index eafbd5301..6692e2e5d 100644 --- a/core/src/test/resources/google/registry/flows/domain/domain_check_fee_premium_response_v12.xml +++ b/core/src/test/resources/google/registry/flows/domain/domain_check_fee_premium_response_v12.xml @@ -1,4 +1,4 @@ - +domain_check_fee_premium_response_v12.xml Command completed successfully @@ -49,9 +49,7 @@ 1 - 100.00 17.00 - premium @@ -61,7 +59,6 @@ 1 0.00 - premium diff --git a/core/src/test/resources/google/registry/flows/domain/domain_check_fee_premium_response_v12_with_renewal.xml b/core/src/test/resources/google/registry/flows/domain/domain_check_fee_premium_response_v12_with_renewal.xml new file mode 100644 index 000000000..5f2ef4b86 --- /dev/null +++ b/core/src/test/resources/google/registry/flows/domain/domain_check_fee_premium_response_v12_with_renewal.xml @@ -0,0 +1,74 @@ +domain_check_fee_premium_response_v12.xml + + + Command completed successfully + + + + + rich.example + In use + + + + + + + + rich.example + + + 1 + 100.00 + premium + + + + + rich.example + + + 1 + 100.00 + premium + + + + + rich.example + + + 1 + 100.00 + premium + + + + + rich.example + + + 1 + 100.00 + 17.00 + premium + + + + + rich.example + + + 1 + 0.00 + + + + + + ABC-12345 + server-trid + + + diff --git a/core/src/test/resources/google/registry/flows/domain/domain_check_fee_reserved_response_v06.xml b/core/src/test/resources/google/registry/flows/domain/domain_check_fee_reserved_response_v06.xml index ecc216b57..9e5ae7307 100644 --- a/core/src/test/resources/google/registry/flows/domain/domain_check_fee_reserved_response_v06.xml +++ b/core/src/test/resources/google/registry/flows/domain/domain_check_fee_reserved_response_v06.xml @@ -51,7 +51,6 @@ USD restore 1 - 11.00 17.00 @@ -80,7 +79,6 @@ USD restore 1 - 11.00 17.00 @@ -109,7 +107,6 @@ USD restore 1 - 11.00 17.00 @@ -140,9 +137,7 @@ USD restore 1 - 70.00 17.00 - premium diff --git a/core/src/test/resources/google/registry/flows/domain/domain_check_fee_reserved_response_v11_restore.xml b/core/src/test/resources/google/registry/flows/domain/domain_check_fee_reserved_response_v11_restore.xml index 101e1ecce..3d3c2d2ea 100644 --- a/core/src/test/resources/google/registry/flows/domain/domain_check_fee_reserved_response_v11_restore.xml +++ b/core/src/test/resources/google/registry/flows/domain/domain_check_fee_reserved_response_v11_restore.xml @@ -33,7 +33,6 @@ restore USD 1 - 11.00 17.00 @@ -43,7 +42,6 @@ restore USD 1 - 11.00 17.00 @@ -53,7 +51,6 @@ restore USD 1 - 11.00 17.00 @@ -63,8 +60,6 @@ restore USD 1 - 70.00 - premium 17.00 diff --git a/core/src/test/resources/google/registry/flows/domain/domain_check_fee_reserved_response_v11_restore_with_renewals.xml b/core/src/test/resources/google/registry/flows/domain/domain_check_fee_reserved_response_v11_restore_with_renewals.xml new file mode 100644 index 000000000..5ef08cf27 --- /dev/null +++ b/core/src/test/resources/google/registry/flows/domain/domain_check_fee_reserved_response_v11_restore_with_renewals.xml @@ -0,0 +1,77 @@ + + + + Command completed successfully + + + + + reserved.tld + In use + + + allowedinsunrise.tld + In use + + + collision.tld + In use + + + premiumcollision.tld + In use + + + + + + + + reserved.tld + + restore + USD + 1 + 11.00 + 17.00 + + + + allowedinsunrise.tld + + restore + USD + 1 + 11.00 + 17.00 + + + + collision.tld + + restore + USD + 1 + 11.00 + 17.00 + + + + premiumcollision.tld + + restore + USD + 1 + 70.00 + premium + 17.00 + + + + + ABC-12345 + server-trid + + + diff --git a/core/src/test/resources/google/registry/flows/domain/domain_check_fee_reserved_response_v12.xml b/core/src/test/resources/google/registry/flows/domain/domain_check_fee_reserved_response_v12.xml index f053b8ef6..1f46e20a5 100644 --- a/core/src/test/resources/google/registry/flows/domain/domain_check_fee_reserved_response_v12.xml +++ b/core/src/test/resources/google/registry/flows/domain/domain_check_fee_reserved_response_v12.xml @@ -60,7 +60,6 @@ 1 - 11.00 17.00 @@ -97,7 +96,6 @@ 1 - 11.00 17.00 @@ -134,7 +132,6 @@ 1 - 11.00 17.00 @@ -173,9 +170,7 @@ 1 - 70.00 17.00 - premium diff --git a/core/src/test/resources/google/registry/flows/domain/domain_check_fee_reserved_sunrise_response_v06.xml b/core/src/test/resources/google/registry/flows/domain/domain_check_fee_reserved_sunrise_response_v06.xml index 53dcb6f6d..647175735 100644 --- a/core/src/test/resources/google/registry/flows/domain/domain_check_fee_reserved_sunrise_response_v06.xml +++ b/core/src/test/resources/google/registry/flows/domain/domain_check_fee_reserved_sunrise_response_v06.xml @@ -48,7 +48,6 @@ USD restore 1 - 11.00 17.00 @@ -77,7 +76,6 @@ USD restore 1 - 11.00 17.00 @@ -109,7 +107,6 @@ USD restore 1 - 11.00 17.00 collision @@ -142,9 +139,8 @@ USD restore 1 - 70.00 17.00 - premium-collision + collision diff --git a/core/src/test/resources/google/registry/flows/domain/domain_check_fee_reserved_sunrise_response_v06_with_renewals.xml b/core/src/test/resources/google/registry/flows/domain/domain_check_fee_reserved_sunrise_response_v06_with_renewals.xml new file mode 100644 index 000000000..b82115747 --- /dev/null +++ b/core/src/test/resources/google/registry/flows/domain/domain_check_fee_reserved_sunrise_response_v06_with_renewals.xml @@ -0,0 +1,159 @@ + + + + Command completed successfully + + + + + reserved.tld + In use + + + allowedinsunrise.tld + In use + + + collision.tld + In use + + + premiumcollision.tld + In use + + + + + + + reserved.tld + USD + create + 1 + reserved + + + reserved.tld + USD + renew + 1 + 11.00 + + + reserved.tld + USD + transfer + 1 + 11.00 + + + reserved.tld + USD + restore + 1 + 11.00 + 17.00 + + + allowedinsunrise.tld + USD + create + 1 + 13.00 + + + allowedinsunrise.tld + USD + renew + 1 + 11.00 + + + allowedinsunrise.tld + USD + transfer + 1 + 11.00 + + + allowedinsunrise.tld + USD + restore + 1 + 11.00 + 17.00 + + + collision.tld + USD + create + 1 + 13.00 + collision + + + collision.tld + USD + renew + 1 + 11.00 + collision + + + collision.tld + USD + transfer + 1 + 11.00 + collision + + + collision.tld + USD + restore + 1 + 11.00 + 17.00 + collision + + + premiumcollision.tld + USD + create + 1 + 70.00 + premium-collision + + + premiumcollision.tld + USD + renew + 1 + 70.00 + premium-collision + + + premiumcollision.tld + USD + transfer + 1 + 70.00 + premium-collision + + + premiumcollision.tld + USD + restore + 1 + 70.00 + 17.00 + premium-collision + + + + + ABC-12345 + server-trid + + + diff --git a/core/src/test/resources/google/registry/flows/domain/domain_check_fee_reserved_sunrise_response_v11_restore.xml b/core/src/test/resources/google/registry/flows/domain/domain_check_fee_reserved_sunrise_response_v11_restore.xml index c65800496..6bf16ced7 100644 --- a/core/src/test/resources/google/registry/flows/domain/domain_check_fee_reserved_sunrise_response_v11_restore.xml +++ b/core/src/test/resources/google/registry/flows/domain/domain_check_fee_reserved_sunrise_response_v11_restore.xml @@ -30,7 +30,6 @@ restore USD 1 - 11.00 17.00 @@ -40,7 +39,6 @@ restore USD 1 - 11.00 17.00 @@ -50,7 +48,6 @@ restore USD 1 - 11.00 17.00 collision @@ -61,9 +58,8 @@ restore USD 1 - 70.00 17.00 - premium-collision + collision diff --git a/core/src/test/resources/google/registry/flows/domain/domain_check_fee_reserved_sunrise_response_v12.xml b/core/src/test/resources/google/registry/flows/domain/domain_check_fee_reserved_sunrise_response_v12.xml index 200f23dd7..94b0d63ff 100644 --- a/core/src/test/resources/google/registry/flows/domain/domain_check_fee_reserved_sunrise_response_v12.xml +++ b/core/src/test/resources/google/registry/flows/domain/domain_check_fee_reserved_sunrise_response_v12.xml @@ -57,7 +57,6 @@ 1 - 11.00 17.00 @@ -94,7 +93,6 @@ 1 - 11.00 17.00 @@ -134,7 +132,6 @@ 1 - 11.00 17.00 collision @@ -175,9 +172,8 @@ 1 - 70.00 17.00 - premium-collision + collision diff --git a/core/src/test/resources/google/registry/flows/domain/domain_check_fee_response_thirty_domains.xml b/core/src/test/resources/google/registry/flows/domain/domain_check_fee_response_thirty_domains.xml new file mode 100644 index 000000000..c804520c3 --- /dev/null +++ b/core/src/test/resources/google/registry/flows/domain/domain_check_fee_response_thirty_domains.xml @@ -0,0 +1,378 @@ + + + + + Command completed successfully + + + + + example-00.tld + + + example-01.tld + In use + + + example-02.tld + In use + + + example-03.tld + In use + + + example-04.tld + In use + + + example-05.tld + In use + + + example-06.tld + In use + + + example-07.tld + In use + + + example-08.tld + In use + + + example-09.tld + In use + + + example-10.tld + In use + + + example-11.tld + In use + + + example-12.tld + In use + + + example-13.tld + In use + + + example-14.tld + In use + + + example-15.tld + In use + + + example-16.tld + In use + + + example-17.tld + In use + + + example-18.tld + In use + + + example-19.tld + In use + + + example-20.tld + In use + + + example-21.tld + In use + + + example-22.tld + In use + + + example-23.tld + In use + + + example-24.tld + In use + + + example-25.tld + In use + + + example-26.tld + In use + + + example-27.tld + In use + + + example-28.tld + In use + + + example-29.tld + In use + + + + + + + example-00.tld + USD + restore + 1 + 17.00 + + + example-01.tld + USD + restore + 1 + 17.00 + 11.00 + + + example-02.tld + USD + restore + 1 + 17.00 + 11.00 + + + example-03.tld + USD + restore + 1 + 17.00 + 11.00 + + + example-04.tld + USD + restore + 1 + 17.00 + 11.00 + + + example-05.tld + USD + restore + 1 + 17.00 + 11.00 + + + example-06.tld + USD + restore + 1 + 17.00 + 11.00 + + + example-07.tld + USD + restore + 1 + 17.00 + 11.00 + + + example-08.tld + USD + restore + 1 + 17.00 + 11.00 + + + example-09.tld + USD + restore + 1 + 17.00 + 11.00 + + + example-10.tld + USD + restore + 1 + 17.00 + 11.00 + + + example-11.tld + USD + restore + 1 + 17.00 + 11.00 + + + example-12.tld + USD + restore + 1 + 17.00 + 11.00 + + + example-13.tld + USD + restore + 1 + 17.00 + 11.00 + + + example-14.tld + USD + restore + 1 + 17.00 + 11.00 + + + example-15.tld + USD + restore + 1 + 17.00 + 11.00 + + + example-16.tld + USD + restore + 1 + 17.00 + 11.00 + + + example-17.tld + USD + restore + 1 + 17.00 + 11.00 + + + example-18.tld + USD + restore + 1 + 17.00 + 11.00 + + + example-19.tld + USD + restore + 1 + 17.00 + 11.00 + + + example-20.tld + USD + restore + 1 + 17.00 + 11.00 + + + example-21.tld + USD + restore + 1 + 17.00 + 11.00 + + + example-22.tld + USD + restore + 1 + 17.00 + 11.00 + + + example-23.tld + USD + restore + 1 + 17.00 + 11.00 + + + example-24.tld + USD + restore + 1 + 17.00 + 11.00 + + + example-25.tld + USD + restore + 1 + 17.00 + 11.00 + + + example-26.tld + USD + restore + 1 + 17.00 + 11.00 + + + example-27.tld + USD + restore + 1 + 17.00 + 11.00 + + + example-28.tld + USD + restore + 1 + 17.00 + 11.00 + + + example-29.tld + USD + restore + 1 + 17.00 + 11.00 + + + + + ABC-12345 + server-trid + + + diff --git a/core/src/test/resources/google/registry/flows/domain/domain_check_fee_thirty_domains.xml b/core/src/test/resources/google/registry/flows/domain/domain_check_fee_thirty_domains.xml new file mode 100644 index 000000000..f9d2febc2 --- /dev/null +++ b/core/src/test/resources/google/registry/flows/domain/domain_check_fee_thirty_domains.xml @@ -0,0 +1,226 @@ + + + + + example-00.tld + example-01.tld + example-02.tld + example-03.tld + example-04.tld + example-05.tld + example-06.tld + example-07.tld + example-08.tld + example-09.tld + example-10.tld + example-11.tld + example-12.tld + example-13.tld + example-14.tld + example-15.tld + example-16.tld + example-17.tld + example-18.tld + example-19.tld + example-20.tld + example-21.tld + example-22.tld + example-23.tld + example-24.tld + example-25.tld + example-26.tld + example-27.tld + example-28.tld + example-29.tld + + + + + custom + + + + example-00.tld + USD + restore + 1 + + + example-01.tld + USD + restore + 1 + + + example-02.tld + USD + restore + 1 + + + example-03.tld + USD + restore + 1 + + + example-04.tld + USD + restore + 1 + + + example-05.tld + USD + restore + 1 + + + example-06.tld + USD + restore + 1 + + + example-07.tld + USD + restore + 1 + + + example-08.tld + USD + restore + 1 + + + example-09.tld + USD + restore + 1 + + + example-10.tld + USD + restore + 1 + + + example-11.tld + USD + restore + 1 + + + example-12.tld + USD + restore + 1 + + + example-13.tld + USD + restore + 1 + + + example-14.tld + USD + restore + 1 + + + example-15.tld + USD + restore + 1 + + + example-16.tld + USD + restore + 1 + + + example-17.tld + USD + restore + 1 + + + example-18.tld + USD + restore + 1 + + + example-19.tld + USD + restore + 1 + + + example-20.tld + USD + restore + 1 + + + example-21.tld + USD + restore + 1 + + + example-22.tld + USD + restore + 1 + + + example-23.tld + USD + restore + 1 + + + example-24.tld + USD + restore + 1 + + + example-25.tld + USD + restore + 1 + + + example-26.tld + USD + restore + 1 + + + example-27.tld + USD + restore + 1 + + + example-28.tld + USD + restore + 1 + + + example-29.tld + USD + restore + 1 + + + + ABC-12345 + + diff --git a/core/src/test/resources/google/registry/flows/domain/domain_info_fee_restore_premium_response.xml b/core/src/test/resources/google/registry/flows/domain/domain_info_fee_restore_premium_response.xml index 34facbd10..c1c9b49a0 100644 --- a/core/src/test/resources/google/registry/flows/domain/domain_info_fee_restore_premium_response.xml +++ b/core/src/test/resources/google/registry/flows/domain/domain_info_fee_restore_premium_response.xml @@ -36,7 +36,6 @@ restore 1 17.00 - premium