Flatten the contact flows

There was very little meat in the contact hierarchy and it
flattened quiet easily.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=133080191
This commit is contained in:
cgoldfeder 2016-09-13 19:28:06 -07:00 committed by Ben McIlwain
parent bf9a3a0fb2
commit 99af33328d
22 changed files with 682 additions and 154 deletions

View file

@ -14,35 +14,151 @@
package google.registry.flows.contact;
import google.registry.config.RegistryEnvironment;
import google.registry.flows.ResourceTransferRequestFlow;
import static google.registry.flows.ResourceFlowUtils.createPendingTransferNotificationResponse;
import static google.registry.flows.ResourceFlowUtils.createTransferResponse;
import static google.registry.flows.ResourceFlowUtils.verifyAuthInfoForResource;
import static google.registry.flows.ResourceFlowUtils.verifyNoDisallowedStatuses;
import static google.registry.model.EppResourceUtils.loadByUniqueId;
import static google.registry.model.eppoutput.Result.Code.SuccessWithActionPending;
import static google.registry.model.ofy.ObjectifyService.ofy;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.googlecode.objectify.Key;
import google.registry.config.ConfigModule.Config;
import google.registry.flows.EppException;
import google.registry.flows.LoggedInFlow;
import google.registry.flows.TransactionalFlow;
import google.registry.flows.exceptions.AlreadyPendingTransferException;
import google.registry.flows.exceptions.MissingTransferRequestAuthInfoException;
import google.registry.flows.exceptions.ObjectAlreadySponsoredException;
import google.registry.flows.exceptions.ResourceToMutateDoesNotExistException;
import google.registry.model.contact.ContactCommand.Transfer;
import google.registry.model.contact.ContactResource;
import google.registry.model.domain.metadata.MetadataExtension;
import google.registry.model.eppcommon.StatusValue;
import google.registry.model.eppinput.ResourceCommand;
import google.registry.model.eppoutput.EppOutput;
import google.registry.model.poll.PollMessage;
import google.registry.model.reporting.HistoryEntry;
import google.registry.model.transfer.TransferData;
import google.registry.model.transfer.TransferStatus;
import javax.inject.Inject;
import org.joda.time.DateTime;
import org.joda.time.Duration;
/**
* An EPP flow that requests a transfer on a {@link ContactResource}.
*
* @error {@link google.registry.flows.ResourceFlowUtils.BadAuthInfoForResourceException}
* @error {@link google.registry.flows.ResourceMutateFlow.ResourceToMutateDoesNotExistException}
* @error {@link google.registry.flows.ResourceTransferRequestFlow.AlreadyPendingTransferException}
* @error {@link google.registry.flows.ResourceTransferRequestFlow.MissingTransferRequestAuthInfoException}
* @error {@link google.registry.flows.ResourceTransferRequestFlow.ObjectAlreadySponsoredException}
* @error {@link google.registry.flows.exceptions.ResourceToMutateDoesNotExistException}
* @error {@link google.registry.flows.exceptions.AlreadyPendingTransferException}
* @error {@link google.registry.flows.exceptions.MissingTransferRequestAuthInfoException}
* @error {@link google.registry.flows.exceptions.ObjectAlreadySponsoredException}
*/
public class ContactTransferRequestFlow
extends ResourceTransferRequestFlow<ContactResource, Transfer> {
public class ContactTransferRequestFlow extends LoggedInFlow implements TransactionalFlow {
private static final ImmutableSet<StatusValue> DISALLOWED_STATUSES = ImmutableSet.of(
StatusValue.CLIENT_TRANSFER_PROHIBITED,
StatusValue.PENDING_DELETE,
StatusValue.SERVER_TRANSFER_PROHIBITED);
@Inject ResourceCommand resourceCommand;
@Inject @Config("contactAutomaticTransferLength") Duration automaticTransferLength;
@Inject HistoryEntry.Builder historyBuilder;
@Inject ContactTransferRequestFlow() {}
@Override
protected final HistoryEntry.Type getHistoryEntryType() {
return HistoryEntry.Type.CONTACT_TRANSFER_REQUEST;
protected final void initLoggedInFlow() throws EppException {
registerExtensions(MetadataExtension.class);
}
@Override
protected Duration getAutomaticTransferLength() {
return RegistryEnvironment.get().config().getContactAutomaticTransferLength();
protected final EppOutput run() throws EppException {
Transfer command = (Transfer) resourceCommand;
String targetId = command.getTargetId();
ContactResource existingResource = loadByUniqueId(ContactResource.class, targetId, now);
if (existingResource == null) {
throw new ResourceToMutateDoesNotExistException(ContactResource.class, targetId);
}
if (command.getAuthInfo() == null) {
throw new MissingTransferRequestAuthInfoException();
}
verifyAuthInfoForResource(command.getAuthInfo(), existingResource);
// Verify that the resource does not already have a pending transfer.
if (TransferStatus.PENDING.equals(existingResource.getTransferData().getTransferStatus())) {
throw new AlreadyPendingTransferException(targetId);
}
String gainingClientId = getClientId();
String losingClientId = existingResource.getCurrentSponsorClientId();
// Verify that this client doesn't already sponsor this resource.
if (gainingClientId.equals(losingClientId)) {
throw new ObjectAlreadySponsoredException();
}
verifyAuthInfoForResource(command.getAuthInfo(), existingResource);
verifyNoDisallowedStatuses(existingResource, DISALLOWED_STATUSES);
HistoryEntry historyEntry = historyBuilder
.setType(HistoryEntry.Type.CONTACT_TRANSFER_REQUEST)
.setModificationTime(now)
.setParent(Key.create(existingResource))
.build();
DateTime transferExpirationTime = now.plus(automaticTransferLength);
TransferData serverApproveTransferData = new TransferData.Builder()
.setTransferRequestTime(now)
.setTransferRequestTrid(trid)
.setGainingClientId(gainingClientId)
.setLosingClientId(losingClientId)
.setPendingTransferExpirationTime(transferExpirationTime)
.setTransferStatus(TransferStatus.SERVER_APPROVED)
.build();
// If the transfer is server approved, this message will be sent to the losing registrar. */
PollMessage.OneTime serverApproveLosingPollMessage = new PollMessage.OneTime.Builder()
.setClientId(losingClientId)
.setMsg(TransferStatus.SERVER_APPROVED.getMessage())
.setParent(historyEntry)
.setEventTime(transferExpirationTime)
.setResponseData(ImmutableList.of(
createTransferResponse(existingResource, serverApproveTransferData, now)))
.build();
// If the transfer is server approved, this message will be sent to the gaining registrar. */
PollMessage.OneTime serverApproveGainingPollMessage = new PollMessage.OneTime.Builder()
.setClientId(gainingClientId)
.setMsg(TransferStatus.SERVER_APPROVED.getMessage())
.setParent(historyEntry)
.setEventTime(transferExpirationTime)
.setResponseData(ImmutableList.of(
createTransferResponse(existingResource, serverApproveTransferData, now),
createPendingTransferNotificationResponse(existingResource, trid, true, now)))
.build();
TransferData pendingTransferData = serverApproveTransferData.asBuilder()
.setTransferStatus(TransferStatus.PENDING)
.setServerApproveEntities(
ImmutableSet.<Key<? extends TransferData.TransferServerApproveEntity>>of(
Key.create(serverApproveGainingPollMessage),
Key.create(serverApproveLosingPollMessage)))
.build();
// When a transfer is requested, a poll message is created to notify the losing registrar.
PollMessage.OneTime requestPollMessage = new PollMessage.OneTime.Builder()
.setClientId(losingClientId)
.setMsg(TransferStatus.PENDING.getMessage())
.setParent(historyEntry)
.setEventTime(now)
.setResponseData(ImmutableList.of(
createTransferResponse(existingResource, pendingTransferData, now)))
.build();
ContactResource newResource = existingResource.asBuilder()
.setTransferData(pendingTransferData)
.addStatusValue(StatusValue.PENDING_TRANSFER)
.build();
ofy().save().<Object>entities(
newResource,
historyEntry,
requestPollMessage,
serverApproveGainingPollMessage,
serverApproveLosingPollMessage);
return createOutput(
SuccessWithActionPending,
createTransferResponse(newResource, newResource.getTransferData(), now),
null);
}
}