Streamline transfer resolving helpers in ResourceFlowUtils

In the great flow flattening, ResourceFlowUtils grew a couple nice helpers
for rebuilding transferrable resources (Domains and Contacts) upon the
resolution of a transfer - approvePendingTransfer() and denyPendingTransfer().

Most transfer-resolving callsites use one of these two helpers, but for legacy
reasons the deletion flows (DomainDeleteFlow and DeleteContactsAndHostsAction)
were instead using the "manual" resolvePendingTransfer() method or its even more
low-level createResolvedTransferData() helper instead of denyPendingTransfer().
It's simpler to just have two options - approve and deny - so this CL inlines
createResolvedTransferData() into resolvePendingTransfer() and makes the latter
a private helper for the approve/denyPendingTransfer() public helpers.

This CL also adds sanity checks that approve/denyPendingTransfer() are called
only with the logically appropriate values of TransferStatus.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=170819358
This commit is contained in:
nickfelt 2017-10-03 01:10:39 -07:00 committed by Ben McIlwain
parent a5c931a152
commit fd62f4a74e
4 changed files with 37 additions and 34 deletions

View file

@ -20,7 +20,7 @@ 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.math.IntMath.divide; import static com.google.common.math.IntMath.divide;
import static com.googlecode.objectify.Key.getKind; import static com.googlecode.objectify.Key.getKind;
import static google.registry.flows.ResourceFlowUtils.createResolvedTransferData; import static google.registry.flows.ResourceFlowUtils.denyPendingTransfer;
import static google.registry.flows.ResourceFlowUtils.handlePendingTransferOnDelete; import static google.registry.flows.ResourceFlowUtils.handlePendingTransferOnDelete;
import static google.registry.flows.ResourceFlowUtils.updateForeignKeyIndexDeletionTime; import static google.registry.flows.ResourceFlowUtils.updateForeignKeyIndexDeletionTime;
import static google.registry.flows.async.AsyncFlowEnqueuer.PARAM_CLIENT_TRANSACTION_ID; import static google.registry.flows.async.AsyncFlowEnqueuer.PARAM_CLIENT_TRANSACTION_ID;
@ -373,12 +373,12 @@ public class DeleteContactsAndHostsAction implements Runnable {
EppResource.Builder<?, ?> resourceToSaveBuilder; EppResource.Builder<?, ?> resourceToSaveBuilder;
if (resource instanceof ContactResource) { if (resource instanceof ContactResource) {
ContactResource contact = (ContactResource) resource; ContactResource contact = (ContactResource) resource;
ContactResource.Builder contactToSaveBuilder = contact.asBuilder(); // Handle pending transfers on contact deletion.
if (contact.getStatusValues().contains(StatusValue.PENDING_TRANSFER)) { if (contact.getStatusValues().contains(StatusValue.PENDING_TRANSFER)) {
contactToSaveBuilder = contactToSaveBuilder.setTransferData(createResolvedTransferData( contact = denyPendingTransfer(contact, TransferStatus.SERVER_CANCELLED, now);
contact.getTransferData(), TransferStatus.SERVER_CANCELLED, now));
} }
resourceToSaveBuilder = contactToSaveBuilder.wipeOut(); // Wipe out PII on contact deletion.
resourceToSaveBuilder = contact.asBuilder().wipeOut();
} else { } else {
resourceToSaveBuilder = resource.asBuilder(); resourceToSaveBuilder = resource.asBuilder();
} }

View file

@ -206,25 +206,6 @@ public final class ResourceFlowUtils {
} }
} }
/**
* Create a {@link TransferData} object representing a resolved transfer.
*
* <p>This clears all the server-approve fields on the {@link TransferData}, sets the status
* field, and sets the expiration time of the last pending transfer to now.
*/
public static TransferData createResolvedTransferData(
TransferData oldTransferData, TransferStatus transferStatus, DateTime now) {
checkArgument(!oldTransferData.equals(TransferData.EMPTY), "No old transfer to resolve.");
return oldTransferData.asBuilder()
.setServerApproveEntities(null)
.setServerApproveBillingEvent(null)
.setServerApproveAutorenewEvent(null)
.setServerApproveAutorenewPollMessage(null)
.setTransferStatus(transferStatus)
.setPendingTransferExpirationTime(checkNotNull(now))
.build();
}
/** /**
* Turn a resource into a builder with its pending transfer resolved. * Turn a resource into a builder with its pending transfer resolved.
* *
@ -232,18 +213,29 @@ public final class ResourceFlowUtils {
* TransferStatus}, clears all the server-approve fields on the {@link TransferData}, and sets the * TransferStatus}, clears all the server-approve fields on the {@link TransferData}, and sets the
* expiration time of the last pending transfer to now. * expiration time of the last pending transfer to now.
*/ */
@SuppressWarnings("unchecked") private static <
public static <
R extends EppResource & ResourceWithTransferData, R extends EppResource & ResourceWithTransferData,
B extends EppResource.Builder<R, B> & BuilderWithTransferData<B>> B extends EppResource.Builder<R, B> & BuilderWithTransferData<B>>
B resolvePendingTransfer(R resource, TransferStatus transferStatus, DateTime now) { B resolvePendingTransfer(R resource, TransferStatus transferStatus, DateTime now) {
checkState( checkArgument(
resource.getStatusValues().contains(StatusValue.PENDING_TRANSFER), resource.getStatusValues().contains(StatusValue.PENDING_TRANSFER),
"Resource is not in pending transfer status."); "Resource is not in pending transfer status.");
return ((B) resource.asBuilder()) checkArgument(
!TransferData.EMPTY.equals(resource.getTransferData()),
"No old transfer data to resolve.");
@SuppressWarnings("unchecked")
B builder = (B) resource.asBuilder();
return builder
.removeStatusValue(StatusValue.PENDING_TRANSFER) .removeStatusValue(StatusValue.PENDING_TRANSFER)
.setTransferData( .setTransferData(
createResolvedTransferData(resource.getTransferData(), transferStatus, now)); resource.getTransferData().asBuilder()
.setServerApproveEntities(null)
.setServerApproveBillingEvent(null)
.setServerApproveAutorenewEvent(null)
.setServerApproveAutorenewPollMessage(null)
.setTransferStatus(transferStatus)
.setPendingTransferExpirationTime(checkNotNull(now))
.build());
} }
/** /**
@ -258,6 +250,7 @@ public final class ResourceFlowUtils {
R extends EppResource & ResourceWithTransferData, R extends EppResource & ResourceWithTransferData,
B extends Builder<R, B> & BuilderWithTransferData<B>> B extends Builder<R, B> & BuilderWithTransferData<B>>
R approvePendingTransfer(R resource, TransferStatus transferStatus, DateTime now) { R approvePendingTransfer(R resource, TransferStatus transferStatus, DateTime now) {
checkArgument(transferStatus.isApproved(), "Not an approval transfer status");
B builder = ResourceFlowUtils.<R, B>resolvePendingTransfer(resource, transferStatus, now); B builder = ResourceFlowUtils.<R, B>resolvePendingTransfer(resource, transferStatus, now);
return builder return builder
.setLastTransferTime(now) .setLastTransferTime(now)
@ -274,6 +267,7 @@ public final class ResourceFlowUtils {
*/ */
public static <R extends EppResource & ResourceWithTransferData> R denyPendingTransfer( public static <R extends EppResource & ResourceWithTransferData> R denyPendingTransfer(
R resource, TransferStatus transferStatus, DateTime now) { R resource, TransferStatus transferStatus, DateTime now) {
checkArgument(transferStatus.isDenied(), "Not a denial transfer status");
return resolvePendingTransfer(resource, transferStatus, now).build(); return resolvePendingTransfer(resource, transferStatus, now).build();
} }

View file

@ -17,6 +17,7 @@ package google.registry.flows.domain;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
import static google.registry.flows.FlowUtils.persistEntityChanges; import static google.registry.flows.FlowUtils.persistEntityChanges;
import static google.registry.flows.FlowUtils.validateClientIsLoggedIn; import static google.registry.flows.FlowUtils.validateClientIsLoggedIn;
import static google.registry.flows.ResourceFlowUtils.denyPendingTransfer;
import static google.registry.flows.ResourceFlowUtils.handlePendingTransferOnDelete; import static google.registry.flows.ResourceFlowUtils.handlePendingTransferOnDelete;
import static google.registry.flows.ResourceFlowUtils.loadAndVerifyExistence; import static google.registry.flows.ResourceFlowUtils.loadAndVerifyExistence;
import static google.registry.flows.ResourceFlowUtils.updateForeignKeyIndexDeletionTime; import static google.registry.flows.ResourceFlowUtils.updateForeignKeyIndexDeletionTime;
@ -48,7 +49,6 @@ import google.registry.flows.ExtensionManager;
import google.registry.flows.FlowModule.ClientId; import google.registry.flows.FlowModule.ClientId;
import google.registry.flows.FlowModule.Superuser; import google.registry.flows.FlowModule.Superuser;
import google.registry.flows.FlowModule.TargetId; import google.registry.flows.FlowModule.TargetId;
import google.registry.flows.ResourceFlowUtils;
import google.registry.flows.SessionMetadata; import google.registry.flows.SessionMetadata;
import google.registry.flows.TransactionalFlow; import google.registry.flows.TransactionalFlow;
import google.registry.flows.annotations.ReportingSpec; import google.registry.flows.annotations.ReportingSpec;
@ -145,10 +145,13 @@ public final class DomainDeleteFlow implements TransactionalFlow {
customLogic.afterValidation( customLogic.afterValidation(
AfterValidationParameters.newBuilder().setExistingDomain(existingDomain).build()); AfterValidationParameters.newBuilder().setExistingDomain(existingDomain).build());
ImmutableSet.Builder<ImmutableObject> entitiesToSave = new ImmutableSet.Builder<>(); ImmutableSet.Builder<ImmutableObject> entitiesToSave = new ImmutableSet.Builder<>();
Builder builder = existingDomain.getStatusValues().contains(StatusValue.PENDING_TRANSFER) Builder builder;
? ResourceFlowUtils.<DomainResource, DomainResource.Builder>resolvePendingTransfer( if (existingDomain.getStatusValues().contains(StatusValue.PENDING_TRANSFER)) {
existingDomain, TransferStatus.SERVER_CANCELLED, now) builder =
: existingDomain.asBuilder(); denyPendingTransfer(existingDomain, TransferStatus.SERVER_CANCELLED, now).asBuilder();
} else {
builder = existingDomain.asBuilder();
}
Duration redemptionGracePeriodLength = registry.getRedemptionGracePeriodLength(); Duration redemptionGracePeriodLength = registry.getRedemptionGracePeriodLength();
Duration pendingDeleteLength = registry.getPendingDeleteLength(); Duration pendingDeleteLength = registry.getPendingDeleteLength();
DomainDeleteSuperuserExtension domainDeleteSuperuserExtension = DomainDeleteSuperuserExtension domainDeleteSuperuserExtension =

View file

@ -54,4 +54,10 @@ public enum TransferStatus {
public boolean isApproved() { public boolean isApproved() {
return this.equals(CLIENT_APPROVED) || this.equals(SERVER_APPROVED); return this.equals(CLIENT_APPROVED) || this.equals(SERVER_APPROVED);
} }
public boolean isDenied() {
return this.equals(CLIENT_CANCELLED)
|| this.equals(CLIENT_REJECTED)
|| this.equals(SERVER_CANCELLED);
}
} }