mirror of
https://github.com/google/nomulus.git
synced 2025-08-06 01:35:17 +02:00
Record domain transaction for domain transfers
This is the last of many cls adding explicit logging in all our domain mutation flows to facilitate transaction reporting. The transfer process is as follows: GAINING sends a TransferRequest to LOSING LOSING either acks (TransferApprove), nacks (TransferReject) or does nothing (auto approve). For acks and autoapproves, we produce a +1 counter for GAINING and LOSING for domain-gaining/losing-successful for each registrar, to be reported on the approve date + the transfer grace period. For nacks, we produce a +1 counter for domain-gaining/losing-nacked for each registrar. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=166535579
This commit is contained in:
parent
7ee8bc9070
commit
16e8286dca
15 changed files with 319 additions and 95 deletions
|
@ -17,6 +17,10 @@ package google.registry.flows.domain;
|
|||
import static com.google.common.collect.Iterables.getOnlyElement;
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static google.registry.model.ofy.ObjectifyService.ofy;
|
||||
import static google.registry.model.reporting.DomainTransactionRecord.TransactionReportField.TRANSFER_SUCCESSFUL;
|
||||
import static google.registry.model.reporting.HistoryEntry.Type.DOMAIN_CREATE;
|
||||
import static google.registry.model.reporting.HistoryEntry.Type.DOMAIN_TRANSFER_APPROVE;
|
||||
import static google.registry.model.reporting.HistoryEntry.Type.DOMAIN_TRANSFER_REQUEST;
|
||||
import static google.registry.testing.DatastoreHelper.assertBillingEventsForResource;
|
||||
import static google.registry.testing.DatastoreHelper.createTld;
|
||||
import static google.registry.testing.DatastoreHelper.deleteResource;
|
||||
|
@ -57,6 +61,7 @@ import google.registry.model.eppcommon.Trid;
|
|||
import google.registry.model.poll.PendingActionNotificationResponse;
|
||||
import google.registry.model.poll.PollMessage;
|
||||
import google.registry.model.registry.Registry;
|
||||
import google.registry.model.reporting.DomainTransactionRecord;
|
||||
import google.registry.model.reporting.HistoryEntry;
|
||||
import google.registry.model.transfer.TransferResponse.DomainTransferResponse;
|
||||
import google.registry.model.transfer.TransferStatus;
|
||||
|
@ -139,12 +144,12 @@ public class DomainTransferApproveFlowTest
|
|||
runFlowAssertResponse(readFile(expectedXmlFilename));
|
||||
// Transfer should have succeeded. Verify correct fields were set.
|
||||
domain = reloadResourceByForeignKey();
|
||||
assertAboutDomains().that(domain).hasOneHistoryEntryEachOfTypes(
|
||||
HistoryEntry.Type.DOMAIN_CREATE,
|
||||
HistoryEntry.Type.DOMAIN_TRANSFER_REQUEST,
|
||||
HistoryEntry.Type.DOMAIN_TRANSFER_APPROVE);
|
||||
assertAboutDomains()
|
||||
.that(domain)
|
||||
.hasOneHistoryEntryEachOfTypes(
|
||||
DOMAIN_CREATE, DOMAIN_TRANSFER_REQUEST, DOMAIN_TRANSFER_APPROVE);
|
||||
final HistoryEntry historyEntryTransferApproved =
|
||||
getOnlyHistoryEntryOfType(domain, HistoryEntry.Type.DOMAIN_TRANSFER_APPROVE);
|
||||
getOnlyHistoryEntryOfType(domain, DOMAIN_TRANSFER_APPROVE);
|
||||
assertAboutHistoryEntries().that(historyEntryTransferApproved)
|
||||
.hasOtherClientId("NewRegistrar");
|
||||
assertTransferApproved(domain);
|
||||
|
@ -445,4 +450,53 @@ public class DomainTransferApproveFlowTest
|
|||
assertIcannReportingActivityFieldLogged("srs-dom-transfer-approve");
|
||||
assertTldsFieldLogged("tld");
|
||||
}
|
||||
|
||||
private void setUpGracePeriodDurations() {
|
||||
persistResource(
|
||||
Registry.get("tld")
|
||||
.asBuilder()
|
||||
.setAutomaticTransferLength(Duration.standardDays(2))
|
||||
.setTransferGracePeriodLength(Duration.standardDays(3))
|
||||
.build());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIcannTransactionRecord_noRecordsToCancel() throws Exception {
|
||||
setUpGracePeriodDurations();
|
||||
clock.advanceOneMilli();
|
||||
runFlow();
|
||||
HistoryEntry persistedEntry = getOnlyHistoryEntryOfType(domain, DOMAIN_TRANSFER_APPROVE);
|
||||
// We should only produce a transfer success record for (now + transfer grace period)
|
||||
assertThat(persistedEntry.getDomainTransactionRecords())
|
||||
.containsExactly(
|
||||
DomainTransactionRecord.create(
|
||||
"tld", clock.nowUtc().plusDays(3), TRANSFER_SUCCESSFUL, 1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIcannTransactionRecord_cancelsPreviousRecords() throws Exception {
|
||||
clock.advanceOneMilli();
|
||||
setUpGracePeriodDurations();
|
||||
DomainTransactionRecord previousSuccessRecord =
|
||||
DomainTransactionRecord.create(
|
||||
"tld", clock.nowUtc().plusDays(1), TRANSFER_SUCCESSFUL, 1);
|
||||
persistResource(
|
||||
new HistoryEntry.Builder()
|
||||
.setType(DOMAIN_TRANSFER_REQUEST)
|
||||
.setParent(domain)
|
||||
.setModificationTime(clock.nowUtc().minusDays(4))
|
||||
.setDomainTransactionRecords(
|
||||
ImmutableSet.of(previousSuccessRecord))
|
||||
.build());
|
||||
runFlow();
|
||||
HistoryEntry persistedEntry = getOnlyHistoryEntryOfType(domain, DOMAIN_TRANSFER_APPROVE);
|
||||
// We should produce cancellation records for the original reporting date (now + 1 day) and
|
||||
// success records for the new reporting date (now + transferGracePeriod=3 days)
|
||||
assertThat(persistedEntry.getDomainTransactionRecords())
|
||||
.containsExactly(
|
||||
previousSuccessRecord.asBuilder().setReportAmount(-1).build(),
|
||||
DomainTransactionRecord.create(
|
||||
"tld", clock.nowUtc().plusDays(3), TRANSFER_SUCCESSFUL, 1));
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,6 +15,10 @@
|
|||
package google.registry.flows.domain;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static google.registry.model.reporting.DomainTransactionRecord.TransactionReportField.TRANSFER_SUCCESSFUL;
|
||||
import static google.registry.model.reporting.HistoryEntry.Type.DOMAIN_CREATE;
|
||||
import static google.registry.model.reporting.HistoryEntry.Type.DOMAIN_TRANSFER_CANCEL;
|
||||
import static google.registry.model.reporting.HistoryEntry.Type.DOMAIN_TRANSFER_REQUEST;
|
||||
import static google.registry.testing.DatastoreHelper.assertBillingEvents;
|
||||
import static google.registry.testing.DatastoreHelper.createPollMessageForImplicitTransfer;
|
||||
import static google.registry.testing.DatastoreHelper.deleteResource;
|
||||
|
@ -39,10 +43,13 @@ import google.registry.model.domain.DomainResource;
|
|||
import google.registry.model.domain.GracePeriod;
|
||||
import google.registry.model.eppcommon.AuthInfo.PasswordAuth;
|
||||
import google.registry.model.poll.PollMessage;
|
||||
import google.registry.model.registry.Registry;
|
||||
import google.registry.model.reporting.DomainTransactionRecord;
|
||||
import google.registry.model.reporting.HistoryEntry;
|
||||
import google.registry.model.transfer.TransferResponse.DomainTransferResponse;
|
||||
import google.registry.model.transfer.TransferStatus;
|
||||
import org.joda.time.DateTime;
|
||||
import org.joda.time.Duration;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
|
@ -113,12 +120,12 @@ public class DomainTransferCancelFlowTest
|
|||
assertAboutDomains().that(domain)
|
||||
.hasRegistrationExpirationTime(originalExpirationTime).and()
|
||||
.hasLastTransferTimeNotEqualTo(clock.nowUtc());
|
||||
assertAboutDomains().that(domain).hasOneHistoryEntryEachOfTypes(
|
||||
HistoryEntry.Type.DOMAIN_CREATE,
|
||||
HistoryEntry.Type.DOMAIN_TRANSFER_REQUEST,
|
||||
HistoryEntry.Type.DOMAIN_TRANSFER_CANCEL);
|
||||
assertAboutDomains()
|
||||
.that(domain)
|
||||
.hasOneHistoryEntryEachOfTypes(
|
||||
DOMAIN_CREATE, DOMAIN_TRANSFER_REQUEST, DOMAIN_TRANSFER_CANCEL);
|
||||
final HistoryEntry historyEntryTransferCancel =
|
||||
getOnlyHistoryEntryOfType(domain, HistoryEntry.Type.DOMAIN_TRANSFER_CANCEL);
|
||||
getOnlyHistoryEntryOfType(domain, DOMAIN_TRANSFER_CANCEL);
|
||||
assertAboutHistoryEntries().that(historyEntryTransferCancel).hasClientId("NewRegistrar")
|
||||
.and().hasOtherClientId("TheRegistrar");
|
||||
// The only billing event left should be the original autorenew event, now reopened.
|
||||
|
@ -138,7 +145,7 @@ public class DomainTransferCancelFlowTest
|
|||
.setEventTime(originalExpirationTime)
|
||||
.setAutorenewEndTime(END_OF_TIME)
|
||||
.setMsg("Domain was auto-renewed.")
|
||||
.setParent(getOnlyHistoryEntryOfType(domain, HistoryEntry.Type.DOMAIN_CREATE))
|
||||
.setParent(getOnlyHistoryEntryOfType(domain, DOMAIN_CREATE))
|
||||
.build(),
|
||||
new PollMessage.OneTime.Builder()
|
||||
.setClientId("TheRegistrar")
|
||||
|
@ -152,7 +159,7 @@ public class DomainTransferCancelFlowTest
|
|||
.setPendingTransferExpirationTime(clock.nowUtc())
|
||||
.build()))
|
||||
.setMsg("Transfer cancelled.")
|
||||
.setParent(getOnlyHistoryEntryOfType(domain, HistoryEntry.Type.DOMAIN_TRANSFER_CANCEL))
|
||||
.setParent(getOnlyHistoryEntryOfType(domain, DOMAIN_TRANSFER_CANCEL))
|
||||
.build());
|
||||
|
||||
// The original grace periods should remain untouched.
|
||||
|
@ -323,4 +330,38 @@ public class DomainTransferCancelFlowTest
|
|||
assertIcannReportingActivityFieldLogged("srs-dom-transfer-cancel");
|
||||
assertTldsFieldLogged("tld");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIcannTransactionRecord_noRecordsToCancel() throws Exception {
|
||||
clock.advanceOneMilli();
|
||||
runFlow();
|
||||
HistoryEntry persistedEntry = getOnlyHistoryEntryOfType(domain, DOMAIN_TRANSFER_CANCEL);
|
||||
// No cancellation records should be produced
|
||||
assertThat(persistedEntry.getDomainTransactionRecords()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIcannTransactionRecord_cancelsPreviousRecords() throws Exception {
|
||||
clock.advanceOneMilli();
|
||||
persistResource(
|
||||
Registry.get("tld")
|
||||
.asBuilder()
|
||||
.setAutomaticTransferLength(Duration.standardDays(2))
|
||||
.setTransferGracePeriodLength(Duration.standardDays(3))
|
||||
.build());
|
||||
DomainTransactionRecord previousSuccessRecord =
|
||||
DomainTransactionRecord.create("tld", clock.nowUtc().plusDays(1), TRANSFER_SUCCESSFUL, 1);
|
||||
persistResource(
|
||||
new HistoryEntry.Builder()
|
||||
.setType(DOMAIN_TRANSFER_REQUEST)
|
||||
.setParent(domain)
|
||||
.setModificationTime(clock.nowUtc().minusDays(4))
|
||||
.setDomainTransactionRecords(ImmutableSet.of(previousSuccessRecord))
|
||||
.build());
|
||||
runFlow();
|
||||
HistoryEntry persistedEntry = getOnlyHistoryEntryOfType(domain, DOMAIN_TRANSFER_CANCEL);
|
||||
// We should produce a cancellation record for the original transfer success
|
||||
assertThat(persistedEntry.getDomainTransactionRecords())
|
||||
.containsExactly(previousSuccessRecord.asBuilder().setReportAmount(-1).build());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,6 +15,11 @@
|
|||
package google.registry.flows.domain;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static google.registry.model.reporting.DomainTransactionRecord.TransactionReportField.TRANSFER_NACKED;
|
||||
import static google.registry.model.reporting.DomainTransactionRecord.TransactionReportField.TRANSFER_SUCCESSFUL;
|
||||
import static google.registry.model.reporting.HistoryEntry.Type.DOMAIN_CREATE;
|
||||
import static google.registry.model.reporting.HistoryEntry.Type.DOMAIN_TRANSFER_REJECT;
|
||||
import static google.registry.model.reporting.HistoryEntry.Type.DOMAIN_TRANSFER_REQUEST;
|
||||
import static google.registry.testing.DatastoreHelper.assertBillingEvents;
|
||||
import static google.registry.testing.DatastoreHelper.deleteResource;
|
||||
import static google.registry.testing.DatastoreHelper.getOnlyHistoryEntryOfType;
|
||||
|
@ -42,10 +47,13 @@ import google.registry.model.eppcommon.AuthInfo.PasswordAuth;
|
|||
import google.registry.model.eppcommon.Trid;
|
||||
import google.registry.model.poll.PendingActionNotificationResponse;
|
||||
import google.registry.model.poll.PollMessage;
|
||||
import google.registry.model.registry.Registry;
|
||||
import google.registry.model.reporting.DomainTransactionRecord;
|
||||
import google.registry.model.reporting.HistoryEntry;
|
||||
import google.registry.model.transfer.TransferResponse;
|
||||
import google.registry.model.transfer.TransferStatus;
|
||||
import org.joda.time.DateTime;
|
||||
import org.joda.time.Duration;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
|
@ -88,11 +96,9 @@ public class DomainTransferRejectFlowTest
|
|||
.hasRegistrationExpirationTime(originalExpirationTime).and()
|
||||
.hasLastTransferTimeNotEqualTo(clock.nowUtc()).and()
|
||||
.hasOneHistoryEntryEachOfTypes(
|
||||
HistoryEntry.Type.DOMAIN_CREATE,
|
||||
HistoryEntry.Type.DOMAIN_TRANSFER_REQUEST,
|
||||
HistoryEntry.Type.DOMAIN_TRANSFER_REJECT);
|
||||
DOMAIN_CREATE, DOMAIN_TRANSFER_REQUEST, DOMAIN_TRANSFER_REJECT);
|
||||
final HistoryEntry historyEntryTransferRejected =
|
||||
getOnlyHistoryEntryOfType(domain, HistoryEntry.Type.DOMAIN_TRANSFER_REJECT);
|
||||
getOnlyHistoryEntryOfType(domain, DOMAIN_TRANSFER_REJECT);
|
||||
assertAboutHistoryEntries()
|
||||
.that(historyEntryTransferRejected)
|
||||
.hasOtherClientId("NewRegistrar");
|
||||
|
@ -285,4 +291,46 @@ public class DomainTransferRejectFlowTest
|
|||
assertIcannReportingActivityFieldLogged("srs-dom-transfer-reject");
|
||||
assertTldsFieldLogged("tld");
|
||||
}
|
||||
|
||||
private void setUpGracePeriodDurations() {
|
||||
persistResource(
|
||||
Registry.get("tld")
|
||||
.asBuilder()
|
||||
.setAutomaticTransferLength(Duration.standardDays(2))
|
||||
.setTransferGracePeriodLength(Duration.standardDays(3))
|
||||
.build());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIcannTransactionRecord_noRecordsToCancel() throws Exception {
|
||||
setUpGracePeriodDurations();
|
||||
runFlow();
|
||||
HistoryEntry persistedEntry = getOnlyHistoryEntryOfType(domain, DOMAIN_TRANSFER_REJECT);
|
||||
// We should only produce transfer nacked records, reported now
|
||||
assertThat(persistedEntry.getDomainTransactionRecords())
|
||||
.containsExactly(DomainTransactionRecord.create("tld", clock.nowUtc(), TRANSFER_NACKED, 1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIcannTransactionRecord_cancelsPreviousRecords() throws Exception {
|
||||
setUpGracePeriodDurations();
|
||||
DomainTransactionRecord previousSuccessRecord =
|
||||
DomainTransactionRecord.create(
|
||||
"tld", clock.nowUtc().plusDays(1), TRANSFER_SUCCESSFUL, 1);
|
||||
persistResource(
|
||||
new HistoryEntry.Builder()
|
||||
.setType(DOMAIN_TRANSFER_REQUEST)
|
||||
.setParent(domain)
|
||||
.setModificationTime(clock.nowUtc().minusDays(4))
|
||||
.setDomainTransactionRecords(
|
||||
ImmutableSet.of(previousSuccessRecord))
|
||||
.build());
|
||||
runFlow();
|
||||
HistoryEntry persistedEntry = getOnlyHistoryEntryOfType(domain, DOMAIN_TRANSFER_REJECT);
|
||||
// We should produce cancellation records for the original success records and nack records
|
||||
assertThat(persistedEntry.getDomainTransactionRecords())
|
||||
.containsExactly(
|
||||
previousSuccessRecord.asBuilder().setReportAmount(-1).build(),
|
||||
DomainTransactionRecord.create("tld", clock.nowUtc(), TRANSFER_NACKED, 1));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,9 @@ package google.registry.flows.domain;
|
|||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static google.registry.model.ofy.ObjectifyService.ofy;
|
||||
import static google.registry.model.reporting.DomainTransactionRecord.TransactionReportField.TRANSFER_SUCCESSFUL;
|
||||
import static google.registry.model.reporting.HistoryEntry.Type.DOMAIN_CREATE;
|
||||
import static google.registry.model.reporting.HistoryEntry.Type.DOMAIN_TRANSFER_REQUEST;
|
||||
import static google.registry.testing.DatastoreHelper.assertBillingEvents;
|
||||
import static google.registry.testing.DatastoreHelper.createTld;
|
||||
import static google.registry.testing.DatastoreHelper.getOnlyHistoryEntryOfType;
|
||||
|
@ -68,6 +71,7 @@ import google.registry.model.eppcommon.StatusValue;
|
|||
import google.registry.model.poll.PendingActionNotificationResponse;
|
||||
import google.registry.model.poll.PollMessage;
|
||||
import google.registry.model.registry.Registry;
|
||||
import google.registry.model.reporting.DomainTransactionRecord;
|
||||
import google.registry.model.reporting.HistoryEntry;
|
||||
import google.registry.model.transfer.TransferResponse;
|
||||
import google.registry.model.transfer.TransferStatus;
|
||||
|
@ -163,14 +167,12 @@ public class DomainTransferRequestFlowTest
|
|||
// Transfer should have been requested. Verify correct fields were set.
|
||||
domain = reloadResourceByForeignKey();
|
||||
final HistoryEntry historyEntryTransferRequest =
|
||||
getOnlyHistoryEntryOfType(domain, HistoryEntry.Type.DOMAIN_TRANSFER_REQUEST);
|
||||
getOnlyHistoryEntryOfType(domain, DOMAIN_TRANSFER_REQUEST);
|
||||
subordinateHost = reloadResourceAndCloneAtTime(subordinateHost, clock.nowUtc());
|
||||
assertTransferRequested(domain);
|
||||
assertAboutDomains().that(domain)
|
||||
.hasPendingTransferExpirationTime(implicitTransferTime).and()
|
||||
.hasOneHistoryEntryEachOfTypes(
|
||||
HistoryEntry.Type.DOMAIN_CREATE,
|
||||
HistoryEntry.Type.DOMAIN_TRANSFER_REQUEST);
|
||||
.hasOneHistoryEntryEachOfTypes(DOMAIN_CREATE, DOMAIN_TRANSFER_REQUEST);
|
||||
assertAboutHistoryEntries()
|
||||
.that(historyEntryTransferRequest)
|
||||
.hasPeriodYears(1)
|
||||
|
@ -971,4 +973,23 @@ public class DomainTransferRequestFlowTest
|
|||
assertIcannReportingActivityFieldLogged("srs-dom-transfer-request");
|
||||
assertTldsFieldLogged("tld");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIcannTransactionRecord_getsStored() throws Exception {
|
||||
setupDomain("example", "tld");
|
||||
persistResource(
|
||||
Registry.get("tld")
|
||||
.asBuilder()
|
||||
.setAutomaticTransferLength(Duration.standardDays(2))
|
||||
.setTransferGracePeriodLength(Duration.standardDays(3))
|
||||
.build());
|
||||
clock.advanceOneMilli();
|
||||
runTest("domain_transfer_request.xml", UserPrivileges.NORMAL);
|
||||
HistoryEntry persistedEntry = getOnlyHistoryEntryOfType(domain, DOMAIN_TRANSFER_REQUEST);
|
||||
// We should produce a transfer success record
|
||||
assertThat(persistedEntry.getDomainTransactionRecords())
|
||||
.containsExactly(
|
||||
DomainTransactionRecord.create(
|
||||
"tld", clock.nowUtc().plusDays(5), TRANSFER_SUCCESSFUL, 1));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -811,10 +811,8 @@ enum google.registry.model.reporting.DomainTransactionRecord$TransactionReportFi
|
|||
NET_RENEWS_8_YR;
|
||||
NET_RENEWS_9_YR;
|
||||
RESTORED_DOMAINS;
|
||||
TRANSFER_GAINING_NACKED;
|
||||
TRANSFER_GAINING_SUCCESSFUL;
|
||||
TRANSFER_LOSING_NACKED;
|
||||
TRANSFER_LOSING_SUCCESSFUL;
|
||||
TRANSFER_NACKED;
|
||||
TRANSFER_SUCCESSFUL;
|
||||
}
|
||||
class google.registry.model.reporting.HistoryEntry {
|
||||
@Id long id;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue