Update lastEppUpdateTime and lastEppUpdateClientId when necessary

EppResource's lastEppUpdateTime and lastEppUpdateClientId need
to be updated whenever the domain is updated, renewed, deleted or
transfered.

This commit applied the change to the following domain EPP commands:

 - Update (already implemented)
 - Renew
 - Delete
 - Restore
 - Transfer request
 - Transfer approve
 - Transfer reject
 - Transfer cancel

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=223344758
This commit is contained in:
shicong 2018-11-29 07:47:54 -08:00 committed by jianglai
parent b54227e938
commit 5d2bb892f3
28 changed files with 110 additions and 37 deletions

View file

@ -39,6 +39,7 @@ import static google.registry.model.reporting.HistoryEntry.Type.CONTACT_DELETE;
import static google.registry.model.reporting.HistoryEntry.Type.CONTACT_DELETE_FAILURE;
import static google.registry.model.reporting.HistoryEntry.Type.HOST_DELETE;
import static google.registry.model.reporting.HistoryEntry.Type.HOST_DELETE_FAILURE;
import static google.registry.model.transfer.TransferStatus.SERVER_CANCELLED;
import static google.registry.util.PipelineUtils.createJobPath;
import static java.math.RoundingMode.CEILING;
import static java.util.concurrent.TimeUnit.DAYS;
@ -85,7 +86,6 @@ import google.registry.model.poll.PendingActionNotificationResponse.HostPendingA
import google.registry.model.poll.PollMessage;
import google.registry.model.reporting.HistoryEntry;
import google.registry.model.server.Lock;
import google.registry.model.transfer.TransferStatus;
import google.registry.request.Action;
import google.registry.request.Response;
import google.registry.request.auth.Auth;
@ -394,7 +394,9 @@ public class DeleteContactsAndHostsAction implements Runnable {
ContactResource contact = (ContactResource) resource;
// Handle pending transfers on contact deletion.
if (contact.getStatusValues().contains(StatusValue.PENDING_TRANSFER)) {
contact = denyPendingTransfer(contact, TransferStatus.SERVER_CANCELLED, now);
contact =
denyPendingTransfer(
contact, SERVER_CANCELLED, now, deletionRequest.requestingClientId());
}
// Wipe out PII on contact deletion.
resourceToSaveBuilder = contact.asBuilder().wipeOut();

View file

@ -258,13 +258,17 @@ public final class ResourceFlowUtils {
* Resolve a pending transfer by denying it.
*
* <p>This removes the {@link StatusValue#PENDING_TRANSFER} status, sets the {@link
* TransferStatus}, clears all the server-approve fields on the {@link TransferData}, and sets the
* expiration time of the last pending transfer to now.
* TransferStatus}, clears all the server-approve fields on the {@link TransferData}, sets the
* expiration time of the last pending transfer to now, sets the last EPP update time to now, and
* sets the last EPP update client id to the given client id.
*/
public static <R extends EppResource & ResourceWithTransferData> R denyPendingTransfer(
R resource, TransferStatus transferStatus, DateTime now) {
R resource, TransferStatus transferStatus, DateTime now, String lastEppUpdateClientId) {
checkArgument(transferStatus.isDenied(), "Not a denial transfer status");
return resolvePendingTransfer(resource, transferStatus, now).build();
return resolvePendingTransfer(resource, transferStatus, now)
.setLastEppUpdateTime(now)
.setLastEppUpdateClientId(lastEppUpdateClientId)
.build();
}
public static <R extends EppResource & ResourceWithTransferData> void verifyHasPendingTransfer(

View file

@ -80,7 +80,7 @@ public final class ContactTransferCancelFlow implements TransactionalFlow {
verifyHasPendingTransfer(existingContact);
verifyTransferInitiator(clientId, existingContact);
ContactResource newContact =
denyPendingTransfer(existingContact, TransferStatus.CLIENT_CANCELLED, now);
denyPendingTransfer(existingContact, TransferStatus.CLIENT_CANCELLED, now, clientId);
HistoryEntry historyEntry = historyBuilder
.setType(HistoryEntry.Type.CONTACT_TRANSFER_CANCEL)
.setModificationTime(now)

View file

@ -78,7 +78,7 @@ public final class ContactTransferRejectFlow implements TransactionalFlow {
verifyHasPendingTransfer(existingContact);
verifyResourceOwnership(clientId, existingContact);
ContactResource newContact =
denyPendingTransfer(existingContact, TransferStatus.CLIENT_REJECTED, now);
denyPendingTransfer(existingContact, TransferStatus.CLIENT_REJECTED, now, clientId);
HistoryEntry historyEntry = historyBuilder
.setType(HistoryEntry.Type.CONTACT_TRANSFER_REJECT)
.setModificationTime(now)

View file

@ -152,10 +152,12 @@ public final class DomainDeleteFlow implements TransactionalFlow {
Builder builder;
if (existingDomain.getStatusValues().contains(StatusValue.PENDING_TRANSFER)) {
builder =
denyPendingTransfer(existingDomain, TransferStatus.SERVER_CANCELLED, now).asBuilder();
denyPendingTransfer(existingDomain, TransferStatus.SERVER_CANCELLED, now, clientId)
.asBuilder();
} else {
builder = existingDomain.asBuilder();
}
builder.setLastEppUpdateTime(now).setLastEppUpdateClientId(clientId);
Duration redemptionGracePeriodLength = registry.getRedemptionGracePeriodLength();
Duration pendingDeleteLength = registry.getPendingDeleteLength();
Optional<DomainDeleteSuperuserExtension> domainDeleteSuperuserExtension =

View file

@ -175,11 +175,16 @@ public final class DomainRenewFlow implements TransactionalFlow {
.build();
// End the old autorenew billing event and poll message now. This may delete the poll message.
updateAutorenewRecurrenceEndTime(existingDomain, now);
DomainResource newDomain = existingDomain.asBuilder()
DomainResource newDomain =
existingDomain
.asBuilder()
.setLastEppUpdateTime(now)
.setLastEppUpdateClientId(clientId)
.setRegistrationExpirationTime(newExpirationTime)
.setAutorenewBillingEvent(Key.create(newAutorenewEvent))
.setAutorenewPollMessage(Key.create(newAutorenewPollMessage))
.addGracePeriod(GracePeriod.forBillingEvent(GracePeriodStatus.RENEW, explicitRenewEvent))
.addGracePeriod(
GracePeriod.forBillingEvent(GracePeriodStatus.RENEW, explicitRenewEvent))
.build();
EntityChanges entityChanges =
flowCustomLogic.beforeSave(

View file

@ -161,7 +161,8 @@ public final class DomainRestoreRequestFlow implements TransactionalFlow {
.setParent(historyEntry)
.build();
DomainResource newDomain =
performRestore(existingDomain, newExpirationTime, autorenewEvent, autorenewPollMessage);
performRestore(
existingDomain, newExpirationTime, autorenewEvent, autorenewPollMessage, now, clientId);
updateForeignKeyIndexDeletionTime(newDomain);
entitiesToSave.add(newDomain, historyEntry, autorenewEvent, autorenewPollMessage);
ofy().save().entities(entitiesToSave.build());
@ -227,8 +228,11 @@ public final class DomainRestoreRequestFlow implements TransactionalFlow {
DomainResource existingDomain,
DateTime newExpirationTime,
BillingEvent.Recurring autorenewEvent,
PollMessage.Autorenew autorenewPollMessage) {
return existingDomain.asBuilder()
PollMessage.Autorenew autorenewPollMessage,
DateTime now,
String clientId) {
return existingDomain
.asBuilder()
.setRegistrationExpirationTime(newExpirationTime)
.setDeletionTime(END_OF_TIME)
.setStatusValues(null)
@ -236,6 +240,8 @@ public final class DomainRestoreRequestFlow implements TransactionalFlow {
.setDeletePollMessage(null)
.setAutorenewBillingEvent(Key.create(autorenewEvent))
.setAutorenewPollMessage(Key.create(autorenewPollMessage))
.setLastEppUpdateTime(now)
.setLastEppUpdateClientId(clientId)
.build();
}

View file

@ -181,7 +181,9 @@ public final class DomainTransferApproveFlow implements TransactionalFlow {
// Update the transferredRegistrationExpirationTime here since approvePendingTransfer()
// doesn't know what to set it to and leaves it null.
.setTransferData(
partiallyApprovedDomain.getTransferData().asBuilder()
partiallyApprovedDomain
.getTransferData()
.asBuilder()
.setTransferredRegistrationExpirationTime(newExpirationTime)
.build())
.setRegistrationExpirationTime(newExpirationTime)
@ -193,6 +195,8 @@ public final class DomainTransferApproveFlow implements TransactionalFlow {
? ImmutableSet.of(
GracePeriod.forBillingEvent(GracePeriodStatus.TRANSFER, billingEvent.get()))
: ImmutableSet.of())
.setLastEppUpdateTime(now)
.setLastEppUpdateClientId(clientId)
.build();
// Create a poll message for the gaining client.
PollMessage gainingClientPollMessage = createGainingTransferPollMessage(

View file

@ -98,7 +98,7 @@ public final class DomainTransferCancelFlow implements TransactionalFlow {
Registry registry = Registry.get(existingDomain.getTld());
HistoryEntry historyEntry = buildHistoryEntry(existingDomain, registry, now);
DomainResource newDomain =
denyPendingTransfer(existingDomain, TransferStatus.CLIENT_CANCELLED, now);
denyPendingTransfer(existingDomain, TransferStatus.CLIENT_CANCELLED, now, clientId);
ofy().save().<ImmutableObject>entities(
newDomain,
historyEntry,

View file

@ -100,7 +100,7 @@ public final class DomainTransferRejectFlow implements TransactionalFlow {
checkAllowedAccessToTld(clientId, existingDomain.getTld());
}
DomainResource newDomain =
denyPendingTransfer(existingDomain, TransferStatus.CLIENT_REJECTED, now);
denyPendingTransfer(existingDomain, TransferStatus.CLIENT_REJECTED, now, clientId);
ofy().save().<ImmutableObject>entities(
newDomain,
historyEntry,

View file

@ -225,9 +225,13 @@ public final class DomainTransferRequestFlow implements TransactionalFlow {
// cloneProjectedAtTime() will replace these old autorenew entities with the server approve ones
// that we've created in this flow and stored in pendingTransferData.
updateAutorenewRecurrenceEndTime(existingDomain, automaticTransferTime);
DomainResource newDomain = existingDomain.asBuilder()
DomainResource newDomain =
existingDomain
.asBuilder()
.setTransferData(pendingTransferData)
.addStatusValue(StatusValue.PENDING_TRANSFER)
.setLastEppUpdateTime(now)
.setLastEppUpdateClientId(gainingClientId)
.build();
asyncFlowEnqueuer.enqueueAsyncResave(newDomain, now, automaticTransferTime);
ofy().save()

View file

@ -834,7 +834,11 @@ public class DomainDeleteFlowTest extends ResourceFlowTestCase<DomainDeleteFlow,
runFlow();
assertAboutDomains()
.that(reloadResourceByForeignKey())
.hasOneHistoryEntryEachOfTypes(DOMAIN_CREATE, DOMAIN_DELETE);
.hasOneHistoryEntryEachOfTypes(DOMAIN_CREATE, DOMAIN_DELETE)
.and()
.hasLastEppUpdateTime(clock.nowUtc())
.and()
.hasLastEppUpdateClientId("TheRegistrar");
assertAboutHistoryEntries()
.that(getOnlyHistoryEntryOfType(domain, DOMAIN_DELETE))
.hasType(DOMAIN_DELETE)

View file

@ -169,7 +169,11 @@ public class DomainRenewFlowTest extends ResourceFlowTestCase<DomainRenewFlow, D
.hasRegistrationExpirationTime(newExpiration)
.and()
.hasOneHistoryEntryEachOfTypes(
HistoryEntry.Type.DOMAIN_CREATE, HistoryEntry.Type.DOMAIN_RENEW);
HistoryEntry.Type.DOMAIN_CREATE, HistoryEntry.Type.DOMAIN_RENEW)
.and()
.hasLastEppUpdateTime(clock.nowUtc())
.and()
.hasLastEppUpdateClientId("TheRegistrar");
assertAboutHistoryEntries().that(historyEntryDomainRenew).hasPeriodYears(renewalYears);
BillingEvent.OneTime renewBillingEvent =
new BillingEvent.OneTime.Builder()

View file

@ -151,7 +151,11 @@ public class DomainRestoreRequestFlowTest
.hasDeletionTime(END_OF_TIME)
.and()
.hasOneHistoryEntryEachOfTypes(
HistoryEntry.Type.DOMAIN_DELETE, HistoryEntry.Type.DOMAIN_RESTORE);
HistoryEntry.Type.DOMAIN_DELETE, HistoryEntry.Type.DOMAIN_RESTORE)
.and()
.hasLastEppUpdateTime(clock.nowUtc())
.and()
.hasLastEppUpdateClientId("TheRegistrar");
assertThat(domain.getGracePeriods()).isEmpty();
assertDnsTasksEnqueued("example.tld");
// The poll message for the delete should now be gone. The only poll message should be the new

View file

@ -115,7 +115,11 @@ public class DomainTransferApproveFlowTest
.and()
.hasLastTransferTime(clock.nowUtc())
.and()
.doesNotHaveStatusValue(StatusValue.PENDING_TRANSFER);
.doesNotHaveStatusValue(StatusValue.PENDING_TRANSFER)
.and()
.hasLastEppUpdateTime(clock.nowUtc())
.and()
.hasLastEppUpdateClientId("TheRegistrar");
// The domain TransferData should reflect the approved transfer as we expect, with
// all the speculative server-approve fields nulled out.
assertThat(domain.getTransferData())

View file

@ -133,7 +133,11 @@ public class DomainTransferCancelFlowTest
assertAboutDomains()
.that(domain)
.hasOneHistoryEntryEachOfTypes(
DOMAIN_CREATE, DOMAIN_TRANSFER_REQUEST, DOMAIN_TRANSFER_CANCEL);
DOMAIN_CREATE, DOMAIN_TRANSFER_REQUEST, DOMAIN_TRANSFER_CANCEL)
.and()
.hasLastEppUpdateTime(clock.nowUtc())
.and()
.hasLastEppUpdateClientId("NewRegistrar");
final HistoryEntry historyEntryTransferCancel =
getOnlyHistoryEntryOfType(domain, DOMAIN_TRANSFER_CANCEL);
assertAboutHistoryEntries()

View file

@ -102,7 +102,11 @@ public class DomainTransferRejectFlowTest
.hasLastTransferTimeNotEqualTo(clock.nowUtc())
.and()
.hasOneHistoryEntryEachOfTypes(
DOMAIN_CREATE, DOMAIN_TRANSFER_REQUEST, DOMAIN_TRANSFER_REJECT);
DOMAIN_CREATE, DOMAIN_TRANSFER_REQUEST, DOMAIN_TRANSFER_REJECT)
.and()
.hasLastEppUpdateTime(clock.nowUtc())
.and()
.hasLastEppUpdateClientId("TheRegistrar");
final HistoryEntry historyEntryTransferRejected =
getOnlyHistoryEntryOfType(domain, DOMAIN_TRANSFER_REJECT);
assertAboutHistoryEntries().that(historyEntryTransferRejected).hasOtherClientId("NewRegistrar");

View file

@ -153,7 +153,11 @@ public class DomainTransferRequestFlowTest
.that(domain)
.hasCurrentSponsorClientId("TheRegistrar")
.and()
.hasStatusValue(StatusValue.PENDING_TRANSFER);
.hasStatusValue(StatusValue.PENDING_TRANSFER)
.and()
.hasLastEppUpdateTime(clock.nowUtc())
.and()
.hasLastEppUpdateClientId("NewRegistrar");
Trid expectedTrid =
Trid.create(
getClientTrid(),

View file

@ -160,7 +160,11 @@ public class DomainUpdateFlowTest extends ResourceFlowTestCase<DomainUpdateFlow,
.hasAuthInfoPwd("2BARfoo")
.and()
.hasOneHistoryEntryEachOfTypes(
HistoryEntry.Type.DOMAIN_CREATE, HistoryEntry.Type.DOMAIN_UPDATE);
HistoryEntry.Type.DOMAIN_CREATE, HistoryEntry.Type.DOMAIN_UPDATE)
.and()
.hasLastEppUpdateTime(clock.nowUtc())
.and()
.hasLastEppUpdateClientId("TheRegistrar");
assertNoBillingEvents();
assertDnsTasksEnqueued("example.tld");
}

View file

@ -21,8 +21,8 @@
<domain:clID>NewRegistrar</domain:clID>
<domain:crID>NewRegistrar</domain:crID>
<domain:crDate>2000-06-01T00:04:00Z</domain:crDate>
<domain:upID>NewRegistrar</domain:upID>
<domain:upDate>2000-06-08T00:00:00Z</domain:upDate>
<domain:upID>TheRegistrar</domain:upID>
<domain:upDate>2002-05-30T00:00:00Z</domain:upDate>
<domain:exDate>2002-06-01T00:04:00Z</domain:exDate>
<domain:authInfo>
<domain:pw>2fooBAR</domain:pw>

View file

@ -21,8 +21,8 @@
<domain:clID>TheRegistrar</domain:clID>
<domain:crID>NewRegistrar</domain:crID>
<domain:crDate>2000-06-01T00:04:00Z</domain:crDate>
<domain:upID>NewRegistrar</domain:upID>
<domain:upDate>2000-06-08T00:00:00Z</domain:upDate>
<domain:upID>TheRegistrar</domain:upID>
<domain:upDate>2002-05-30T00:00:00Z</domain:upDate>
<domain:exDate>2003-06-01T00:04:00Z</domain:exDate>
<domain:trDate>2002-06-04T00:00:00Z</domain:trDate>
<domain:authInfo>

View file

@ -19,6 +19,8 @@
<domain:clID>NewRegistrar</domain:clID>
<domain:crID>NewRegistrar</domain:crID>
<domain:crDate>2000-06-01T00:04:00Z</domain:crDate>
<domain:upID>NewRegistrar</domain:upID>
<domain:upDate>2002-05-30T01:01:00Z</domain:upDate>
<domain:exDate>2002-06-01T00:04:00Z</domain:exDate>
<domain:authInfo>
<domain:pw>2fooBAR</domain:pw>

View file

@ -19,6 +19,8 @@
<domain:clID>NewRegistrar</domain:clID>
<domain:crID>NewRegistrar</domain:crID>
<domain:crDate>2000-06-01T00:04:00Z</domain:crDate>
<domain:upID>TheRegistrar</domain:upID>
<domain:upDate>2002-05-30T00:00:00Z</domain:upDate>
<domain:exDate>2002-06-01T00:04:00Z</domain:exDate>
<domain:authInfo>
<domain:pw>2fooBAR</domain:pw>

View file

@ -19,6 +19,8 @@
<domain:clID>NewRegistrar</domain:clID>
<domain:crID>NewRegistrar</domain:crID>
<domain:crDate>2000-06-01T00:04:00Z</domain:crDate>
<domain:upID>TheRegistrar</domain:upID>
<domain:upDate>2002-05-30T00:00:00Z</domain:upDate>
<domain:exDate>2003-06-01T00:04:00Z</domain:exDate>
<domain:authInfo>
<domain:pw>2fooBAR</domain:pw>

View file

@ -19,6 +19,8 @@
<domain:clID>NewRegistrar</domain:clID>
<domain:crID>NewRegistrar</domain:crID>
<domain:crDate>2000-06-01T00:04:00Z</domain:crDate>
<domain:upID>NewRegistrar</domain:upID>
<domain:upDate>2002-05-30T01:03:00Z</domain:upDate>
<domain:exDate>2003-05-30T01:03:00Z</domain:exDate>
<domain:authInfo>
<domain:pw>2fooBAR</domain:pw>

View file

@ -19,6 +19,8 @@
<domain:clID>TheRegistrar</domain:clID>
<domain:crID>NewRegistrar</domain:crID>
<domain:crDate>2000-06-01T00:04:00Z</domain:crDate>
<domain:upID>TheRegistrar</domain:upID>
<domain:upDate>2002-05-30T00:00:00Z</domain:upDate>
<domain:exDate>2003-06-01T00:04:00Z</domain:exDate>
<domain:trDate>2002-06-04T00:00:00Z</domain:trDate>
<domain:authInfo>

View file

@ -19,6 +19,8 @@
<domain:clID>TheRegistrar</domain:clID>
<domain:crID>NewRegistrar</domain:crID>
<domain:crDate>2000-06-01T00:04:00Z</domain:crDate>
<domain:upID>TheRegistrar</domain:upID>
<domain:upDate>2002-05-30T00:00:00Z</domain:upDate>
<domain:exDate>2003-06-01T00:04:00Z</domain:exDate>
<domain:trDate>2002-06-04T00:00:00Z</domain:trDate>
<domain:authInfo>

View file

@ -17,6 +17,8 @@
<domain:clID>NewRegistrar</domain:clID>
<domain:crID>NewRegistrar</domain:crID>
<domain:crDate>2000-06-01T00:02:00.0Z</domain:crDate>
<domain:upID>NewRegistrar</domain:upID>
<domain:upDate>2000-07-07T00:02:00Z</domain:upDate>
<domain:exDate>2002-06-01T00:02:00.0Z</domain:exDate>
<domain:authInfo>
<domain:pw>2fooBAR</domain:pw>